curl --request POST \
--url https://api.example.com/customer \
--header 'Content-Type: application/json' \
--header 'x-hub-signature: <api-key>' \
--data '
{
"externalId": "user_8f2c1a",
"email": "ana.perez@example.com",
"name": "Ana Pérez"
}
'import requests
url = "https://api.example.com/customer"
payload = {
"externalId": "user_8f2c1a",
"email": "ana.perez@example.com",
"name": "Ana Pérez"
}
headers = {
"x-hub-signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-hub-signature': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({externalId: 'user_8f2c1a', email: 'ana.perez@example.com', name: 'Ana Pérez'})
};
fetch('https://api.example.com/customer', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/customer",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'externalId' => 'user_8f2c1a',
'email' => 'ana.perez@example.com',
'name' => 'Ana Pérez'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-hub-signature: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/customer"
payload := strings.NewReader("{\n \"externalId\": \"user_8f2c1a\",\n \"email\": \"ana.perez@example.com\",\n \"name\": \"Ana Pérez\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-hub-signature", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/customer")
.header("x-hub-signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"externalId\": \"user_8f2c1a\",\n \"email\": \"ana.perez@example.com\",\n \"name\": \"Ana Pérez\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/customer")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-hub-signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"externalId\": \"user_8f2c1a\",\n \"email\": \"ana.perez@example.com\",\n \"name\": \"Ana Pérez\"\n}"
response = http.request(request)
puts response.read_body{
"id": "7d4f1c2e-3b5a-4e8f-9a1d-2c6b8e0f4a13",
"externalId": "user_8f2c1a",
"email": "ana.perez@example.com",
"name": "Ana Pérez",
"createdAt": "2026-10-01T16:45:18.000Z",
"updatedAt": "2026-10-01T16:45:18.000Z"
}{
"message": "<string>"
}Create or update a customer
Creates the customer for an externalId, or updates its email and name when one already exists. Checkouts created with the same externalId link to this customer.
curl --request POST \
--url https://api.example.com/customer \
--header 'Content-Type: application/json' \
--header 'x-hub-signature: <api-key>' \
--data '
{
"externalId": "user_8f2c1a",
"email": "ana.perez@example.com",
"name": "Ana Pérez"
}
'import requests
url = "https://api.example.com/customer"
payload = {
"externalId": "user_8f2c1a",
"email": "ana.perez@example.com",
"name": "Ana Pérez"
}
headers = {
"x-hub-signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-hub-signature': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({externalId: 'user_8f2c1a', email: 'ana.perez@example.com', name: 'Ana Pérez'})
};
fetch('https://api.example.com/customer', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/customer",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'externalId' => 'user_8f2c1a',
'email' => 'ana.perez@example.com',
'name' => 'Ana Pérez'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-hub-signature: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/customer"
payload := strings.NewReader("{\n \"externalId\": \"user_8f2c1a\",\n \"email\": \"ana.perez@example.com\",\n \"name\": \"Ana Pérez\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-hub-signature", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/customer")
.header("x-hub-signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"externalId\": \"user_8f2c1a\",\n \"email\": \"ana.perez@example.com\",\n \"name\": \"Ana Pérez\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/customer")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-hub-signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"externalId\": \"user_8f2c1a\",\n \"email\": \"ana.perez@example.com\",\n \"name\": \"Ana Pérez\"\n}"
response = http.request(request)
puts response.read_body{
"id": "7d4f1c2e-3b5a-4e8f-9a1d-2c6b8e0f4a13",
"externalId": "user_8f2c1a",
"email": "ana.perez@example.com",
"name": "Ana Pérez",
"createdAt": "2026-10-01T16:45:18.000Z",
"updatedAt": "2026-10-01T16:45:18.000Z"
}{
"message": "<string>"
}Authorizations
HMAC-SHA256 hex digest keyed with the shared secret: over the raw request body for POST requests, or over the query string (the characters after "?") for GET requests. The signed query string is the one the WHATWG URL parser serializes, so a query built with URLSearchParams and appended unchanged verifies, while a hand-assembled query must be percent-encoded the same way.
Body
Customer details
Who is paying. Creates the customer on first use and updates its details on later checkouts.
Response
The customer as stored
"7d4f1c2e-3b5a-4e8f-9a1d-2c6b8e0f4a13"
"user_8f2c1a"
"ana.perez@example.com"
"Ana Pérez"
"2026-10-01T16:45:18.000Z"
"2026-10-01T16:45:18.000Z"