Preview documentation. The interface is being rolled out — examples are indicative, and we will confirm final values at launch.
Customers, locale, consent
The Customers resource stores the minimum needed for a conversation: phone
number, contact language, and consent proof for contact. You identify the
customer with your external_customer_id, so upsert is safe to call repeatedly.
Base URL: https://api.callbotagent.ai/api/v1/commerce. Sign all requests with
HMAC (X-CBA-Key-Id, X-CBA-Timestamp, X-CBA-Signature); mutations add
Idempotency-Key. Signing details: ./authentication.md.
Customer model
JSON body in snake_case. Phone in E.164, locale in BCP 47.
| Field | Type | Description |
|---|---|---|
external_customer_id |
string | Your customer identifier (upsert key). |
phone |
string | E.164 number, e.g. "+48512123456". |
locale |
string | BCP 47 language tag, e.g. "pl-PL". |
consent.status |
enum | granted | withdrawn | unknown. |
consent.proof |
object | Consent proof: source, reference, collected_at (RFC 3339 UTC). |
Without valid consent (consent.status: granted) the customer will not pass
contact qualification — see ./qualification-scheduling.md.
Operations
PUT /customers/{externalCustomerId}
Idempotent upsert of customer (contact data, locale, consent proof). Scope
customers:write.
curl -X PUT https://api.callbotagent.ai/api/v1/commerce/customers/CUSTOMER-8821 \
-H "X-CBA-Key-Id: cba_test_••••••••" \
-H "X-CBA-Timestamp: 2026-07-10T12:34:56Z" \
-H "X-CBA-Signature: v1=9f8c2a...e41" \
-H "Idempotency-Key: customer-upsert-8821-01" \
-H "Content-Type: application/json" \
-d '{
"external_customer_id": "CUSTOMER-8821",
"phone": "+48512123456", "locale": "pl-PL",
"consent": { "status": "granted", "proof": {
"source": "checkout_optin", "reference": "form-2026-07-09-2231",
"collected_at": "2026-07-09T22:31:07Z" } }
}'
# 200 OK → { "external_customer_id": "CUSTOMER-8821", "outcome": "upserted",
# "consent": { "status": "granted" } }const body = {
external_customer_id: "CUSTOMER-8821",
phone: "+48512123456", locale: "pl-PL",
consent: { status: "granted", proof: {
source: "checkout_optin", reference: "form-2026-07-09-2231",
collected_at: "2026-07-09T22:31:07Z" } },
};
const res = await fetch(
"https://api.callbotagent.ai/api/v1/commerce/customers/CUSTOMER-8821",
{ method: "PUT", headers: {
"X-CBA-Key-Id": "cba_test_••••••••",
"X-CBA-Timestamp": "2026-07-10T12:34:56Z",
"X-CBA-Signature": "v1=9f8c2a...e41",
"Idempotency-Key": "customer-upsert-8821-01",
"Content-Type": "application/json",
}, body: JSON.stringify(body) },
);
const data = await res.json(); // { external_customer_id: "...", outcome: "upserted" }$body = [
"external_customer_id" => "CUSTOMER-8821",
"phone" => "+48512123456", "locale" => "pl-PL",
"consent" => ["status" => "granted", "proof" => [
"source" => "checkout_optin", "reference" => "form-2026-07-09-2231",
"collected_at" => "2026-07-09T22:31:07Z"]],
];
$ch = curl_init("https://api.callbotagent.ai/api/v1/commerce/customers/CUSTOMER-8821");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "PUT", CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-CBA-Key-Id: cba_test_••••••••",
"X-CBA-Timestamp: 2026-07-10T12:34:56Z",
"X-CBA-Signature: v1=9f8c2a...e41",
"Idempotency-Key: customer-upsert-8821-01",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode($body),
]);
$data = json_decode(curl_exec($ch), true); // { external_customer_id: "...", ... }GET /customers/{externalCustomerId}
Returns a sanitized customer record (redacted phone, consent status without
sensitive details). Scope customers:read. Missing resource →
404 resource_not_found.
POST /customers/{externalCustomerId}/anonymize
Idempotent anonymization: removes customer PII while preserving an
irreversible marker in history. Scope customers:erase. Calling again on an
already anonymized customer returns the same result (no error).
Anonymization is irreversible. After it runs, phone number and consent proof are no longer available, and the customer cannot be qualified for contact without a new upsert and fresh consent.