API ReferenceEndpointsCart

Cart

A cart holds line items, applied coupons, bundles, and order bumps before the shopper commits to a checkout. Carts can be guest (session-token) or customer-owned, and can be merged on login. Cart endpoints recalculate totals on every change.

Two auth surfaces on this page.

  • Storefront (/vc/{connectionId}/cart/*) — sales-channel scope, the public surface vibe-coded sites call from the browser.
  • Public API (/v1/cart/*)Authorization: Bearer brainerce_* api-key, for server-to-server integrations that manage carts directly.

Both surfaces operate on the same Cart resource — the difference is just who is authenticated and which scope they get.

Create cart

Creates an empty cart. If an opportunistic Authorization Bearer is supplied and resolves to a valid customer, the new cart is linked to that customer; otherwise a guest cart is created.

POST
/vc/{connectionId}/cart
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring

Sales-channel connection ID (vc_*)

Header Parameters

origin?string
authorization?string

Optional customer Bearer token. Present → cart is linked to the customer; absent or invalid → guest cart.

curl -X POST "https://api.brainerce.com/api/vc/string/cart" \  -H "origin: string" \  -H "authorization: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Get cart by session

GET
/vc/{connectionId}/cart/session/{sessionToken}
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
sessionTokenstring

Header Parameters

originstring
curl -X GET "https://api.brainerce.com/api/vc/string/cart/session/string" \  -H "origin: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Merge carts

Merges a guest session cart into the authenticated customer’s cart. Requires a valid customer Bearer token.

POST
/vc/{connectionId}/cart/merge
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring

Sales-channel connection ID (vc_*)

Header Parameters

origin?string
authorizationstring

Customer Bearer token (Bearer <token>).

sessionTokenstring

Guest session token to merge into the customer cart.

curl -X POST "https://api.brainerce.com/api/vc/string/cart/merge" \  -H "origin: string" \  -H "authorization: string" \  -H "Content-Type: application/json" \  -d '{    "sessionToken": "string"  }'
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Get cart

GET
/vc/{connectionId}/cart/{cartId}
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Query Parameters

includestring

Header Parameters

originstring
curl -X GET "https://api.brainerce.com/api/vc/string/cart/string?include=string" \  -H "origin: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Clear cart

DELETE
/vc/{connectionId}/cart/{cartId}
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
curl -X DELETE "https://api.brainerce.com/api/vc/string/cart/string" \  -H "origin: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Add to cart

POST
/vc/{connectionId}/cart/{cartId}/items
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
productIdstring

Product to add.

variantId?string

Variant id for the product, if it has variants.

quantitynumber

Number of units to add (1..1000).

Range1 <= value <= 1000
notes?string

Shopper-facing note attached to this line item ("Please gift-wrap"). Max 2000 chars.

Lengthlength <= 2000
metadata?object

Arbitrary JSON metadata you want to carry through to the order line. Not displayed in the storefront UI. Max 4 KB, depth ≤ 3, no prototype keys.

Empty Object

analyticsClientId?string

GA4 gtag.js client_id (from gtag('get', measurementId, 'client_id', cb)), forwarded so a later server-side purchase event can stitch to this browser session. Written onto the cart if not already set. Omit if unavailable, and never send a synthesized id.

Lengthlength <= 100
analyticsSessionId?string

GA4 gtag.js session_id (from gtag('get', measurementId, 'session_id', cb)), forwarded alongside analyticsClientId for the same stitch.

Lengthlength <= 100
selections?array<ModifierSelectionDto>

Modifier selections grouped by modifierGroupId, in click-order. Omit for products without modifier groups.

nestedByModifierId?object

Nested combo specs (for modifiers with referencedProductId). Keyed by parent modifier id; validator rejects depth > 3.

Empty Object

curl -X POST "https://api.brainerce.com/api/vc/string/cart/string/items" \  -H "origin: string" \  -H "Content-Type: application/json" \  -d '{    "productId": "prod_abc123",    "quantity": 1  }'
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/vc/{connectionId}/cart/{cartId}/items"
}

Update cart item

PATCH
/vc/{connectionId}/cart/{cartId}/items/{itemId}
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring
itemIdstring

Header Parameters

originstring
quantity?number

New quantity (0 to 1000). Setting quantity: 0 removes the line, same as DELETE.

Range0 <= value <= 1000
notes?string

New shopper-facing note for this line.

selections?array<ModifierSelectionDto>

New modifier selections. PRD §7.2.3: present means REPLACE all existing selections on this line. Omit to keep the existing selections unchanged.

nestedByModifierId?object

New nested combo selections. Same REPLACE semantics as selections.

Empty Object

curl -X PATCH "https://api.brainerce.com/api/vc/string/cart/string/items/string" \  -H "origin: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Remove cart item

DELETE
/vc/{connectionId}/cart/{cartId}/items/{itemId}
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring
itemIdstring

Header Parameters

originstring
curl -X DELETE "https://api.brainerce.com/api/vc/string/cart/string/items/string" \  -H "origin: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Associates a guest cart with the now-logged-in customer. Requires a valid customer Bearer token.

POST
/vc/{connectionId}/cart/{cartId}/link
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

origin?string
authorizationstring

Customer Bearer token (Bearer <token>).

sessionTokenstring

The guest cart session token returned when the cart was originally created. Required as proof-of-possession to prevent guest-cart takeover.

curl -X POST "https://api.brainerce.com/api/vc/string/cart/string/link" \  -H "origin: string" \  -H "authorization: string" \  -H "Content-Type: application/json" \  -d '{    "sessionToken": "sess_01HX7Y6F8M9R0K2N3P4Q5R6S7T"  }'
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Apply coupon

POST
/vc/{connectionId}/cart/{cartId}/coupon
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
codestring

Coupon code (case-insensitive). Validation runs server-side, and invalid codes return 400 with code: COUPON_INVALID or COUPON_USAGE_LIMIT_REACHED.

curl -X POST "https://api.brainerce.com/api/vc/string/cart/string/coupon" \  -H "origin: string" \  -H "Content-Type: application/json" \  -d '{    "code": "SUMMER25"  }'
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Remove coupon

DELETE
/vc/{connectionId}/cart/{cartId}/coupon
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
curl -X DELETE "https://api.brainerce.com/api/vc/string/cart/string/coupon" \  -H "origin: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Recalculate cart

POST
/vc/{connectionId}/cart/{cartId}/recalculate
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
curl -X POST "https://api.brainerce.com/api/vc/string/cart/string/recalculate" \  -H "origin: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Refresh cart snapshots

POST
/vc/{connectionId}/cart/{cartId}/refresh-snapshots
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
curl -X POST "https://api.brainerce.com/api/vc/string/cart/string/refresh-snapshots" \  -H "origin: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

List cart nudges

GET
/vc/{connectionId}/cart/{cartId}/nudges
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
curl -X GET "https://api.brainerce.com/api/vc/string/cart/string/nudges" \  -H "origin: string"
[
  {
    "ruleId": "cldr_abc123",
    "text": "string",
    "type": "AMOUNT_NEEDED",
    "amountNeeded": "12.00",
    "quantityNeeded": 1
  }
]

List cart recommendations

GET
/vc/{connectionId}/cart/{cartId}/recommendations
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Query Parameters

limitstring

Header Parameters

originstring
curl -X GET "https://api.brainerce.com/api/vc/string/cart/string/recommendations?limit=string" \  -H "origin: string"
{
  "recommendations": [
    {
      "id": "clprd_abc123",
      "name": "string",
      "slug": "string",
      "basePrice": "24.00",
      "salePrice": "string",
      "images": [
        {
          "url": "https://cdn.brainerce.com/products/abc123.jpg",
          "alt": "Blue mug"
        }
      ],
      "type": "SIMPLE",
      "inventory": {},
      "targetVariantId": null,
      "requiresVariantSelection": false,
      "pinnedVariant": {
        "id": "clvar_abc123",
        "name": "string",
        "attributes": {}
      },
      "variants": [
        {
          "id": "clvar_abc123",
          "name": "string",
          "attributes": {
            "property1": "string",
            "property2": "string"
          },
          "image": {
            "url": "https://cdn.brainerce.com/products/abc123.jpg",
            "alt": "Blue mug"
          },
          "price": "24.00",
          "salePrice": null
        }
      ],
      "relationType": "CROSS_SELL"
    }
  ]
}

List cart bundles

GET
/vc/{connectionId}/cart/{cartId}/bundles
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
curl -X GET "https://api.brainerce.com/api/vc/string/cart/string/bundles" \  -H "origin: string"
{
  "bundles": [
    {
      "id": "string",
      "name": "string",
      "description": "string",
      "triggerProductId": "string",
      "productIds": [
        "string"
      ],
      "offeredProducts": [
        {
          "id": "clprd_abc123",
          "name": "string",
          "slug": "string",
          "basePrice": "30.00",
          "salePrice": "string",
          "images": [
            {
              "url": "https://cdn.brainerce.com/products/abc123.jpg",
              "alt": "Blue mug"
            }
          ],
          "type": "SIMPLE",
          "variantId": "string",
          "requiresVariantSelection": false,
          "pinnedVariant": {
            "id": "clvar_abc123",
            "name": "string",
            "attributes": {}
          },
          "variants": [
            {
              "id": "clvar_abc123",
              "name": "string",
              "attributes": {
                "property1": "string",
                "property2": "string"
              },
              "image": {
                "url": "https://cdn.brainerce.com/products/abc123.jpg",
                "alt": "Blue mug"
              },
              "price": "24.00",
              "salePrice": null
            }
          ],
          "originalPrice": "30.00",
          "discountedPrice": "24.00"
        }
      ],
      "discountType": "PERCENTAGE",
      "discountValue": "20",
      "totalOriginalPrice": "30.00",
      "totalDiscountedPrice": "24.00"
    }
  ]
}

Add bundle item

POST
/vc/{connectionId}/cart/{cartId}/bundle
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
bundleOfferIdstring

Id of the bundle offer being added.

variantSelections?object

Chosen variant per bundle slot, keyed by the slot/product id.

Empty Object

curl -X POST "https://api.brainerce.com/api/vc/string/cart/string/bundle" \  -H "origin: string" \  -H "Content-Type: application/json" \  -d '{    "bundleOfferId": "string"  }'
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/vc/{connectionId}/cart/{cartId}/bundle"
}

Remove bundle item

DELETE
/vc/{connectionId}/cart/{cartId}/bundle/{bundleOfferId}
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring
bundleOfferIdstring

Header Parameters

originstring
curl -X DELETE "https://api.brainerce.com/api/vc/string/cart/string/bundle/string" \  -H "origin: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

List cart upgrades

GET
/vc/{connectionId}/cart/{cartId}/upgrades
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
curl -X GET "https://api.brainerce.com/api/vc/string/cart/string/upgrades" \  -H "origin: string"
{
  "upgrades": {
    "property1": {
      "sourceProductId": "clprd_abc123",
      "targetProduct": {
        "id": "clprd_abc123",
        "name": "string",
        "slug": "string",
        "basePrice": "39.00",
        "salePrice": "string",
        "images": [
          {
            "url": "https://cdn.brainerce.com/products/abc123.jpg",
            "alt": "Blue mug"
          }
        ],
        "type": "SIMPLE",
        "inventory": {},
        "relationType": "UPSELL"
      },
      "priceDelta": "15.00",
      "deltaPercent": 21
    },
    "property2": {
      "sourceProductId": "clprd_abc123",
      "targetProduct": {
        "id": "clprd_abc123",
        "name": "string",
        "slug": "string",
        "basePrice": "39.00",
        "salePrice": "string",
        "images": [
          {
            "url": "https://cdn.brainerce.com/products/abc123.jpg",
            "alt": "Blue mug"
          }
        ],
        "type": "SIMPLE",
        "inventory": {},
        "relationType": "UPSELL"
      },
      "priceDelta": "15.00",
      "deltaPercent": 21
    }
  }
}

Add order bump

POST
/vc/{connectionId}/cart/{cartId}/bump
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring

Header Parameters

originstring
bumpConfigIdstring

Id of the order-bump configuration being accepted.

curl -X POST "https://api.brainerce.com/api/vc/string/cart/string/bump" \  -H "origin: string" \  -H "Content-Type: application/json" \  -d '{    "bumpConfigId": "string"  }'
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/vc/{connectionId}/cart/{cartId}/bump"
}

Remove order bump

DELETE
/vc/{connectionId}/cart/{cartId}/bump/{bumpConfigId}
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring
cartIdstring
bumpConfigIdstring

Header Parameters

originstring
curl -X DELETE "https://api.brainerce.com/api/vc/string/cart/string/bump/string" \  -H "origin: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

Create a new cart

Supports Idempotency-Key header for safe retries.

POST
/v1/cart
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

customerId?string

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
sessionToken?string

Existing session token to attach this cart to. Omit on the first call, and the server will generate a fresh token and return it on the response. Only supply on retry / explicit re-attach flows.

customerId?string

Customer id to associate the cart with. Only honoured for admin / server-to-server callers. Sales-channel callers must instead send a Authorization: Bearer <customer-token> header.

analyticsClientId?string

GA4 gtag.js client_id (from gtag('get', measurementId, 'client_id', cb)), forwarded so a later server-side purchase event can stitch to this browser session. Omit if unavailable, and never send a synthesized id.

Lengthlength <= 100
analyticsSessionId?string

GA4 gtag.js session_id (from gtag('get', measurementId, 'session_id', cb)), forwarded alongside analyticsClientId for the same stitch.

Lengthlength <= 100
curl -X POST "https://api.brainerce.com/api/v1/cart?customerId=string" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart"
}

Get cart by ID

GET
/v1/cart/{cartId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

cartIdstring

Cart ID

curl -X GET "https://api.brainerce.com/api/v1/cart/string"
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}"
}

Get cart by session token

GET
/v1/cart/session/{sessionToken}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

sessionTokenstring

Cart session token

curl -X GET "https://api.brainerce.com/api/v1/cart/session/string"
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/session/{sessionToken}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/session/{sessionToken}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/session/{sessionToken}"
}

Get cart by customer ID

GET
/v1/cart/customer/{customerId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

customerIdstring

Customer ID

curl -X GET "https://api.brainerce.com/api/v1/cart/customer/string"
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/customer/{customerId}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/customer/{customerId}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/customer/{customerId}"
}

Add item to cart

Supports Idempotency-Key header for safe retries.

POST
/v1/cart/{cartId}/items
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

cartIdstring

Cart ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
productIdstring

Product to add.

variantId?string

Variant id for the product, if it has variants.

quantitynumber

Number of units to add (1..1000).

Range1 <= value <= 1000
notes?string

Shopper-facing note attached to this line item ("Please gift-wrap"). Max 2000 chars.

Lengthlength <= 2000
metadata?object

Arbitrary JSON metadata you want to carry through to the order line. Not displayed in the storefront UI. Max 4 KB, depth ≤ 3, no prototype keys.

Empty Object

analyticsClientId?string

GA4 gtag.js client_id (from gtag('get', measurementId, 'client_id', cb)), forwarded so a later server-side purchase event can stitch to this browser session. Written onto the cart if not already set. Omit if unavailable, and never send a synthesized id.

Lengthlength <= 100
analyticsSessionId?string

GA4 gtag.js session_id (from gtag('get', measurementId, 'session_id', cb)), forwarded alongside analyticsClientId for the same stitch.

Lengthlength <= 100
selections?array<ModifierSelectionDto>

Modifier selections grouped by modifierGroupId, in click-order. Omit for products without modifier groups.

nestedByModifierId?object

Nested combo specs (for modifiers with referencedProductId). Keyed by parent modifier id; validator rejects depth > 3.

Empty Object

curl -X POST "https://api.brainerce.com/api/v1/cart/string/items" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{    "productId": "prod_abc123",    "quantity": 1  }'
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items"
}

Update cart item

Supports Idempotency-Key header for safe retries.

PATCH
/v1/cart/{cartId}/items/{itemId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

cartIdstring

Cart ID

itemIdstring

Cart Item ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
quantity?number

New quantity (0 to 1000). Setting quantity: 0 removes the line, same as DELETE.

Range0 <= value <= 1000
notes?string

New shopper-facing note for this line.

selections?array<ModifierSelectionDto>

New modifier selections. PRD §7.2.3: present means REPLACE all existing selections on this line. Omit to keep the existing selections unchanged.

nestedByModifierId?object

New nested combo selections. Same REPLACE semantics as selections.

Empty Object

curl -X PATCH "https://api.brainerce.com/api/v1/cart/string/items/string" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items/{itemId}"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items/{itemId}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items/{itemId}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items/{itemId}"
}

Remove item from cart

Supports Idempotency-Key header for safe retries.

DELETE
/v1/cart/{cartId}/items/{itemId}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

cartIdstring

Cart ID

itemIdstring

Cart Item ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
curl -X DELETE "https://api.brainerce.com/api/v1/cart/string/items/string" \  -H "Idempotency-Key: string"
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items/{itemId}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items/{itemId}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items/{itemId}"
}

Clear all items from cart

Supports Idempotency-Key header for safe retries.

DELETE
/v1/cart/{cartId}/items
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

cartIdstring

Cart ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
curl -X DELETE "https://api.brainerce.com/api/v1/cart/string/items" \  -H "Idempotency-Key: string"
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/items"
}

Apply coupon to cart

Supports Idempotency-Key header for safe retries.

POST
/v1/cart/{cartId}/coupon
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

cartIdstring

Cart ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
codestring

Coupon code (case-insensitive). Validation runs server-side, and invalid codes return 400 with code: COUPON_INVALID or COUPON_USAGE_LIMIT_REACHED.

curl -X POST "https://api.brainerce.com/api/v1/cart/string/coupon" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{    "code": "SUMMER25"  }'
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/coupon"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/coupon"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/coupon"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/coupon"
}

{
  "statusCode": 429,
  "code": "RATE_LIMITED",
  "message": "Too many requests",
  "details": {
    "retryAfterSeconds": 12
  },
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/coupon"
}

Remove coupon from cart

Supports Idempotency-Key header for safe retries.

DELETE
/v1/cart/{cartId}/coupon
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

cartIdstring

Cart ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
curl -X DELETE "https://api.brainerce.com/api/v1/cart/string/coupon" \  -H "Idempotency-Key: string"
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/coupon"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/coupon"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/{cartId}/coupon"
}

Merge guest cart into customer cart

Supports Idempotency-Key header for safe retries.

POST
/v1/cart/merge
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
sessionTokenstring

Guest cart session token

customerIdstring

Customer ID to merge into

curl -X POST "https://api.brainerce.com/api/v1/cart/merge" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{    "sessionToken": "string",    "customerId": "string"  }'
{
  "id": "string",
  "sessionToken": "string",
  "customerId": "string",
  "status": "string",
  "currency": "string",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "string",
  "discountAmount": "string",
  "ruleDiscountAmount": "string",
  "promoDiscountTotal": "string",
  "couponCode": "string",
  "appliedDiscounts": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "type": "string",
      "discountAmount": "string",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "string",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "string",
      "quantityNeeded": 0
    }
  ],
  "items": [
    {
      "id": "string",
      "productId": "string",
      "variantId": "string",
      "quantity": 0,
      "unitPrice": "string",
      "currentUnitPrice": "string",
      "priceChanged": true,
      "priceDelta": "string",
      "priceDirection": "increased",
      "isAvailable": true,
      "unavailableReason": "PRODUCT_DRAFT",
      "discountAmount": "string",
      "promoDiscountAmount": "string",
      "promoSource": "string",
      "promoSourceId": "string",
      "notes": "string",
      "metadata": {},
      "customizations": {},
      "product": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "images": [
          {}
        ]
      },
      "variant": {
        "id": "string",
        "name": "string",
        "sku": "string",
        "image": {}
      },
      "modifiers": [
        {
          "modifierId": "string",
          "modifierGroupId": "string",
          "name": "string",
          "priceDelta": "string",
          "freeApplied": true,
          "effectivePrice": "string",
          "positionInGroup": 0
        }
      ],
      "modifiersTotal": "string",
      "parentCartItemId": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "itemCount": 0,
  "hasPriceChanges": true,
  "hasUnavailableItems": true,
  "unavailableItemIds": [
    "string"
  ],
  "expiresAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "2019-08-24T14:15:22Z",
    "remainingSeconds": 0,
    "strategy": "ON_PAYMENT",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/merge"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/merge"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/merge"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/cart/merge"
}

Get customer cart

Returns the logged-in customer's active cart, creating one if none exists. Requires a customer Bearer token in the Authorization header.

GET
/vc/{connectionId}/customers/me/cart
X-Sales-Channel-Origin<token>

For /api/vc/{connectionId}/* routes the connectionId (vc_*) is in the URL path — not a header. Live-mode requests must also send a matching Origin header.

In: header

Path Parameters

connectionIdstring

Sales-channel connection ID (vc_*)

Header Parameters

origin?string
authorizationstring

Customer Bearer token (Bearer <token>).

curl -X GET "https://api.brainerce.com/api/vc/string/customers/me/cart" \  -H "origin: string" \  -H "authorization: string"
{
  "id": "clcrt_abc123",
  "sessionToken": "string",
  "customerId": "string",
  "status": "ACTIVE",
  "currency": "USD",
  "notes": "string",
  "analyticsClientId": "string",
  "analyticsSessionId": "string",
  "subtotal": "39.80",
  "discountAmount": "5.00",
  "ruleDiscountAmount": "0",
  "promoDiscountTotal": "0",
  "couponCode": "WELCOME10",
  "appliedDiscounts": [
    {
      "ruleId": "cldr_abc123",
      "ruleName": "string",
      "type": "PERCENTAGE_OFF",
      "discountAmount": "5.00",
      "description": "string"
    }
  ],
  "nudges": [
    {
      "ruleId": "cldr_abc123",
      "text": "string",
      "type": "AMOUNT_NEEDED",
      "amountNeeded": "12.00",
      "quantityNeeded": 1
    }
  ],
  "items": [
    {
      "productId": "clx1234567890",
      "variantId": "string",
      "quantity": 2
    }
  ],
  "itemCount": 3,
  "hasPriceChanges": false,
  "hasUnavailableItems": false,
  "unavailableItemIds": [],
  "expiresAt": "string",
  "createdAt": "string",
  "updatedAt": "string",
  "reservation": {
    "hasReservation": true,
    "expiresAt": "string",
    "remainingSeconds": 540,
    "strategy": "ON_CART",
    "countdownMessage": "string"
  },
  "recommendations": {},
  "upgrades": {},
  "bundles": {}
}

On this page

No Headings