Preview documentation. The interface is being rolled out — examples are indicative, and we will confirm final values at launch.
Products, variants, categories
The catalog is the foundation of conversations: without current product, price, and availability data the system cannot build a correct script. Maintain the Products resource as a mirror of your store — usually with one bulk upload, then incremental updates.
Base URL: https://api.callbotagent.ai/api/v1/commerce. Sign every request with
HMAC headers (X-CBA-Key-Id, X-CBA-Timestamp, X-CBA-Signature); mutations
add Idempotency-Key. Signing: ./authentication.md;
retry semantics: ./idempotency.md.
Product model
JSON body in snake_case. Prices are decimal strings with a separate ISO
4217 currency code.
| Field | Type | Description |
|---|---|---|
external_product_id |
string | Your product identifier (upsert key). |
title |
string | Product name visible in the conversation script. |
category |
string | Category/catalog path used by sales rules. |
status |
enum | active | draft | archived. |
availability |
enum | in_stock | out_of_stock | preorder. |
variants[] |
array | Up to 100 variants per product. |
archived_at |
string | null | RFC 3339 UTC timestamp set on archive. |
Variant (variants[]): external_variant_id (SKU), price (decimal string,
e.g. "149.00"), currency (ISO 4217), inventory (integer; 0 = unavailable),
min_quantity, max_quantity (integer | null).
Operations
POST /products/batch
Idempotent upsert of up to 500 products per request (100 variants each).
Scope catalog:write. Repeat with the same Idempotency-Key returns the same
result.
curl -X POST https://api.callbotagent.ai/api/v1/commerce/products/batch \
-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: catalog-sync-2026-07-10-01" \
-H "Content-Type: application/json" \
-d '{
"products": [{
"external_product_id": "SKU-ROUTER-01", "title": "Router Mesh Home",
"category": "sieci/routery", "status": "active", "availability": "in_stock",
"variants": [{ "external_variant_id": "SKU-ROUTER-01-BLK",
"price": "349.00", "currency": "PLN",
"inventory": 42, "min_quantity": 1, "max_quantity": 5 }]
}]
}'
# 200 OK → { "accepted": 1, "rejected": 0,
# "results": [{ "external_product_id": "SKU-ROUTER-01", "outcome": "upserted" }] }const body = { products: [{
external_product_id: "SKU-ROUTER-01", title: "Router Mesh Home",
category: "sieci/routery", status: "active", availability: "in_stock",
variants: [{ external_variant_id: "SKU-ROUTER-01-BLK", price: "349.00",
currency: "PLN", inventory: 42, min_quantity: 1, max_quantity: 5 }],
}] };
const res = await fetch(
"https://api.callbotagent.ai/api/v1/commerce/products/batch",
{ method: "POST", headers: {
"X-CBA-Key-Id": "cba_test_••••••••",
"X-CBA-Timestamp": "2026-07-10T12:34:56Z",
"X-CBA-Signature": "v1=9f8c2a...e41",
"Idempotency-Key": "catalog-sync-2026-07-10-01",
"Content-Type": "application/json",
}, body: JSON.stringify(body) },
);
const data = await res.json(); // { accepted: 1, rejected: 0, results: [...] }$body = ["products" => [[
"external_product_id" => "SKU-ROUTER-01", "title" => "Router Mesh Home",
"category" => "sieci/routery", "status" => "active", "availability" => "in_stock",
"variants" => [["external_variant_id" => "SKU-ROUTER-01-BLK", "price" => "349.00",
"currency" => "PLN", "inventory" => 42, "min_quantity" => 1, "max_quantity" => 5]],
]]];
$ch = curl_init("https://api.callbotagent.ai/api/v1/commerce/products/batch");
curl_setopt_array($ch, [
CURLOPT_POST => true, 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: catalog-sync-2026-07-10-01",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode($body),
]);
$data = json_decode(curl_exec($ch), true); // { accepted: 1, ... }GET /products
List with opaque cursor pagination (?cursor=…&limit=50, max 200) and filters
(status, availability, category). Scope catalog:read.
GET /products/{externalProductId}
Returns a single product with variants; missing resource →
404 resource_not_found.
DELETE /products/{externalProductId}
Archive (tombstone), never hard delete. Product gets status: archived and
archived_at, drops out of new conversations, but stays linked to historical
orders and rules. Operation is idempotent; a variant with inventory: 0 is not
offered in conversation.