Preview documentation. The interface is being rolled out — examples are indicative, and we will confirm final values at launch.
Sales rules and constraints
The Sales Rules resource controls what the system may offer in a
conversation: variant substitution, upsell, cross-sell, and quantity/price
constraints. You identify a rule with your external_rule_id, so upsert is
idempotent.
Base URL: https://api.callbotagent.ai/api/v1/commerce. Sign requests with HMAC
(X-CBA-Key-Id, X-CBA-Timestamp, X-CBA-Signature); mutations add
Idempotency-Key.
Rule model
| Field | Type | Description |
|---|---|---|
external_rule_id |
string | Your rule identifier (upsert key). |
rule_type |
enum | substitution | upsell | cross_sell | quantity_limit | price_constraint. |
priority |
integer | Application order when multiple rules match (higher = earlier). |
applies_to |
object | Scope: category, external_product_id, or external_variant_id. |
action |
object | Rule effect, e.g. suggest_variant, min_quantity, max_quantity, price_floor. |
enabled |
boolean | Whether the rule is active. |
Rules reference products and variants by your identifiers from ./products.md. An archived product automatically disables related rules.
Operations
PUT /sales-rules/{externalRuleId}
Idempotent upsert of a rule. Scope rules:write.
curl -X PUT https://api.callbotagent.ai/api/v1/commerce/sales-rules/RULE-UPSELL-01 \
-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: rule-upsell-01-01" \
-H "Content-Type: application/json" \
-d '{
"external_rule_id": "RULE-UPSELL-01", "rule_type": "upsell", "priority": 10,
"applies_to": { "category": "sieci/routery" },
"action": { "suggest_variant": "SKU-ROUTER-01-PRO", "max_quantity": 3 },
"enabled": true
}'
# 200 OK → { "external_rule_id": "RULE-UPSELL-01", "outcome": "upserted", "enabled": true }const body = {
external_rule_id: "RULE-UPSELL-01", rule_type: "upsell", priority: 10,
applies_to: { category: "sieci/routery" },
action: { suggest_variant: "SKU-ROUTER-01-PRO", max_quantity: 3 },
enabled: true,
};
const res = await fetch(
"https://api.callbotagent.ai/api/v1/commerce/sales-rules/RULE-UPSELL-01",
{ 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": "rule-upsell-01-01",
"Content-Type": "application/json",
}, body: JSON.stringify(body) },
);
const data = await res.json(); // { external_rule_id: "RULE-UPSELL-01", outcome: "upserted" }$body = [
"external_rule_id" => "RULE-UPSELL-01", "rule_type" => "upsell", "priority" => 10,
"applies_to" => ["category" => "sieci/routery"],
"action" => ["suggest_variant" => "SKU-ROUTER-01-PRO", "max_quantity" => 3],
"enabled" => true,
];
$ch = curl_init("https://api.callbotagent.ai/api/v1/commerce/sales-rules/RULE-UPSELL-01");
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: rule-upsell-01-01",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode($body),
]);
$data = json_decode(curl_exec($ch), true); // { external_rule_id: "RULE-UPSELL-01", ... }GET /sales-rules
List with opaque cursor pagination (?cursor=…&limit=50, max 200) and
rule_type filter. Scope rules:read.
GET /sales-rules/{externalRuleId}
Returns a single rule; missing resource → 404 resource_not_found.
DELETE /sales-rules/{externalRuleId}
Archive, never hard delete. The rule is marked inactive and stops applying, but remains in history. Operation is idempotent.
Partner rules narrow the offer but cannot relax account-owner policy or compliance constraints — full hierarchy in ./qualification-scheduling.md.