callbotagent.aiDocs
v1 · Contract draft
ENPL
Open dashboard
Preview

Preview documentation. The interface is being rolled out — examples are indicative, and we will confirm final values at launch.

Authentication: HMAC, key ID, scopes

Every request to Commerce API v1 is signed with an HMAC key. The key consists of a public key_id and a secret. We show the secret only once — when the key is created — so save it immediately in a secure place. In examples, the key ID is always masked: cba_test_••••••••.

Key model

  • key_id — public identifier, sent in the X-CBA-Key-Id header.
  • secret — secret material for computing the signature; never leaves your server.
  • scopes — permission scopes in a deny-by-default model (without a granted scope, the request is rejected with 403).
  • expiration — the key has an expiry date.
  • rotation — key replacement with an overlap window for old and new keys.

Signature headers

Every request carries a complete set of headers. For mutating methods (POST, PATCH, DELETE), also include Idempotency-Key.

Header Meaning
X-CBA-Key-Id Public key identifier
X-CBA-Timestamp RFC 3339 UTC timestamp when the request was generated
X-CBA-Nonce Unique one-time value per key within the replay window
X-CBA-Content-SHA256 SHA-256 (hex) of the raw body
X-CBA-Signature HMAC-SHA256 signature in hmac-sha256=… format
Idempotency-Key Idempotency key (mutations only)

How to compute the signature

The signature covers a canonical string built from six elements, joined by newlines in a fixed order:

  1. HTTP method (uppercase, e.g. POST),
  2. canonical path (e.g. /api/v1/commerce/orders),
  3. canonical query (sorted parameters, empty when none),
  4. timestamp (X-CBA-Timestamp),
  5. nonce (X-CBA-Nonce),
  6. body hash (X-CBA-Content-SHA256).

Compute HMAC-SHA256 on that string using the secret and place the result in X-CBA-Signature.

CANONICAL="POST\n/api/v1/commerce/orders\n\n2026-07-11T10:00:00Z\n$NONCE\n$BODY_SHA256"
SIGNATURE=$(printf "%b" "$CANONICAL" | openssl dgst -sha256 -hmac "$SECRET" -binary | xxd -p -c 256)
# header: X-CBA-Signature: hmac-sha256=$SIGNATURE

Replay window and nonce

The timestamp must fall within a 300-second window relative to server time — keep clocks synchronized (NTP). The nonce must be unique per key in that window; a repeated nonce is rejected as a replay attempt. Typical rejections are described in Errors (401 invalid_signature, expired_timestamp, replay_nonce).

Scopes

Permissions use deny-by-default — a key can only do what you explicitly grant. Assign the narrowest set you need.

Scope Access
commerce:read Aggregate commerce data read
catalog:read / catalog:write Catalog and variant read / write
customers:read / customers:write Customer data read / write
customers:erase Customer data erasure (right to be forgotten)
orders:read / orders:write Order and intent read / create
results:read Conversation results read
rules:read / rules:write Sales rules read / write
webhooks:read / webhooks:write Webhook management
configuration:read Integration configuration read

Rotation and reveal-once

The secret is shown once. When rotating, create a new key, deploy it in parallel (the overlap window lets old and new keys work at the same time), and after traffic confirms the new key, revoke the old one. This avoids an integration outage during key exchange.

Best practices

  • Keep the secret server-side only; never in a client app or URL.
  • Sign requests immediately before sending so you do not exceed the 300 s window.
  • Log correlation_id from error responses, but never log the secret.
  • More in Security and data.