Skip to main content
Crave promotions belong to one organization. A definition can apply to every active location or an explicit location set, while product and category rules use canonical organization catalog IDs. Location pricing, availability, publication revision, and timezone are resolved again when the cart is evaluated and immediately before payment.

Authentication and scopes

Private management calls use an authenticated Business Manager session or a server-only X-API-Key. API-key reads require catalog:read; API-key creates, updates, and archives require catalog:write. Business Manager mutations require an organization administrator. A location-limited key cannot create an all-location definition, target a location outside its grants, or read/mutate a definition whose complete selected-location set is not contained by those grants. Storefront cart calls use the cart capability and Idempotency-Key, never a private API key.

Create a definition

Call POST /api/v1/discounts. Codes are trimmed and normalized to uppercase, and are unique within the organization. Use locationScope: "all" with an empty locationIds array, or locationScope: "selected" with at least one organization-owned location ID.
Money uses integer minor units and percentages use basis points (1000 = 10%). Weekly windows use the location timezone and half-open intervals: the start is included and the end is excluded. dayOfWeek is 0 for Sunday through 6 for Saturday. A per-customer limit requires a verified organization customer; guests fail closed for that code. Use GET /api/v1/discounts/catalog-targets to discover active canonical products and categories and the locations where each target is currently published.

Preview, update, and archive

  • GET /api/v1/discounts lists definitions with organization and per-location ledger metrics.
  • GET /api/v1/discounts/{discountId} reads one definition.
  • POST /api/v1/discounts/{discountId}/preview evaluates supplied cart lines without reserving or consuming usage.
  • PUT /api/v1/discounts/{discountId} requires the current positive revision in the request body.
  • DELETE /api/v1/discounts/{discountId} archives the definition and requires { "revision": N }.
Disabling or archiving an active definition with reserved or committed usage fails closed unless the request also includes "confirmActiveUsage": true. Business Manager asks for this confirmation and then sends the same explicit API evidence; integrations must do likewise. A stale revision or normalized duplicate returns a conflict. Foreign locations and targets are not disclosed. Archiving prevents new evaluation but does not rewrite historical order or redemption evidence.

Storefront use

Apply a code with POST /api/v1/storefront/locations/{locationId}/carts/{cartId}/discount and { "code": "LUNCH10" }. Remove it with the corresponding DELETE. Both mutations require the cart capability, an Idempotency-Key, and the current cart precondition used by the Storefront contract. Crave supports one public promotion or one loyalty reward on a cart, not both. Applying a public code while loyalty is reserved fails without silently releasing the reward. The response is the authoritative cart, including the exact adjustment and current revision. At payment creation Crave evaluates the definition again, reserves capacity atomically, and stores the definition, cart, and catalog revisions. Payment cancellation releases the reservation; order materialization commits it; a full provider-confirmed refund reverses it. Partial refunds retain the usage and record cumulative proportional evidence.
Do not calculate discount eligibility or usage limits in a client. Never retry checkout with a new idempotency key after an ambiguous response; read the cart or order and reconcile the canonical state first.