State reference

Cart states

A cart's status field is the single source of truth for whether it can still accept mutations. Only open carts are writable.

State machine

stateDiagram-v2
  [*] --> open: POST /carts
  open --> open: mutations (items / shipping / discount / tax)
  open --> checkout: POST /carts/{id}/checkout (creates draft order)
  checkout --> converted: order is paid (payment.captured)
  open --> abandoned: 24h idle (background sweep)
  checkout --> abandoned: 24h idle OR order cancelled before payment
  abandoned --> [*]
  converted --> [*]
Cart lifecycle from create through conversion.

States

  • open — initial state. Accepts items, discount apply/remove, shipping select, tax recompute, and checkout conversion.
  • checkout — cart has been converted to a draft order (POST /carts/{id}/checkout). The cart is frozen; further mutations return 409 cart_already_checked_out.
  • converted — the linked draft order was paid and an order row was finalised (payment.captured fired). Read- only; archived.
  • abandoned — no activity for 24 hours (or past the cart's expiresAt), OR the linked draft order was cancelled before payment. An hourly background sweep performs the idle transition and emits cart.abandoned. Read-only. See Abandoned-cart recovery below.

Mutation rules

  • Every mutation increments sequence on the cart. Webhook payloads include sequence so subscribers can detect out-of-order delivery.
  • POST /carts/{id}/checkout transitions opencheckout. Idempotent within the 24h Idempotency-Key window — same key replays the same draft order id.
  • Direct transitions out of checkout / converted / abandoned via the cart API are not allowed. Cancel the linked order to roll the cart back to abandoned.
Error codes
Mutating a non-open cart returns one of: cart_already_checked_out (409), cart_already_converted (409), or cart_abandoned (410).

Abandoned-cart recovery

An hourly background sweep marks idle carts as abandoned and emits cart.abandoned. A cart is idle when it has had no mutation for 24 hours — every item, shipping, discount, or tax change resets the clock — or when its expiresAt has passed. Empty carts and externally-managed carts are never swept.

  • Webhook (always): every swept cart emits cart.abandoned to your subscribed webhook endpoints, so you can drive recovery from your own systems — including for anonymous carts you track by your own session. The payload carries the line items, totals, customer (a linked customer, or a guest with id: null when only the cart’s customerEmail was captured; null if neither), shippingAddress / billingAddress (if set), and the recoveryUrl.
  • Recovery email: Throttle sends the customer.cart_abandoned email automatically whenever the cart has a known customer email. The email respects customer opt-out / unsubscribe; in non-production environments it carries a [TEST] subject banner.

Where the recovery link points

The link in the recovery email resolves through three tiers, first match wins:

  1. cartRecoveryUrlTemplate — a URL on your own site containing a {cartId} placeholder, e.g. https://shop.example.com/cart?c={cartId} . Use this when you want the buyer to land on a specific page you control.
  2. checkoutLinkBaseUrl — your own host, e.g. https://shop.example.com. Throttle appends /r/<cartSessionToken>, so serve that route yourself with the cart SDK.
  3. Throttle-hosted — when neither is set, the link points at Throttle’s own checkout. Nothing to configure.

Both settings live on the application, per environment, and are editable from the dashboard’s Abandoned carts page. checkoutLinkBaseUrl also governs where quote links point, so a merchant hosting their own buyer-facing pages sets it once.

A recovery link is single-use. Opening it converts the underlying cart session into a checkout session; a second click lands on the expired page rather than reopening a checkout the buyer may already have paid.

Create the cart at add-to-cart to enable recovery
Throttle can only recover carts it knows about. To get abandoned-cart recovery, create the Throttle cart (POST /carts) when the buyer first adds an item and mutate it on every change — the mirror pattern. If you only create the cart at checkout, abandonment happens before Throttle ever sees it and there is nothing to recover.