Cart
Temporary purchase-intent carts and checkout preparation: line items backed by real Item Engine inventory reservations, per-line price locks, guest-cart merge, shareable carts, split-checkout grouping, and a freeze step that commits the holds and hands checkout off to your order flow.
When to reach for it: e-commerce and in-game purchase carts where stock must be held while the buyer decides, guest-to-user merge on login, checkout preparation that must survive stock races.
When not to: the durable inventory itself - definitions, containers,
stock - lives in the Item Engine; carts
only borrow it through reservations. Actual payment is out of scope
platform-wide - checkout-ready ends with a handoff token for your own
order and payment layer.
Concepts
- Carts are ephemeral - each cart carries an
expires_at(30 minutes by default), refreshed on every mutation. A background sweeper abandons overdue and inactive carts and releases their holds. - Every line holds real stock. Adding an item creates an Item Engine reservation against a seller's container; the line stores its snapshot (id, fencing token, expiry, status). Item Engine remains the stock authority - the cart never keeps its own counters.
- Price locks are separate - each line locks its
unit_amountfor a price-lock TTL independent of the reservation TTL. - Lifecycle: only
activeandsharedcarts accept mutations (else409 cart_not_active); freezing moves tocheckout_ready, a merge leaves its sourceconverted, the sweeper producesabandoned. - Add is add-or-update. Adding an
item_idalready in the cart grows that line; anidempotency_keymakes retries safe instead of doubling.
Create a cart and add items
Adding a line names the Item Engine coordinates the stock is reserved from: the domain, the seller's container and its owner, and the definition (SKU).
snug cart create --currency USD
snug cart add docs4-world-pass --qty 2 --cart ryLqjXLpyDPNThWdTNDL \
--domain docs4-shop --source-container cont_CmREXGyNvQKN \
--definition HctVYVhHbdBKyrcsYFGF --inventory-owner docs-wave \
--currency USD --unit-amount 4999{
"cart_id": "ryLqjXLpyDPNThWdTNDL",
"line_id": "QXUhFTjaeQrSwMuBCfNd",
"quantity": 2,
"reservation_expires_at": "2026-08-28T13:02:09.141568Z",
"reservation_status": "held",
"totals": { "subtotal": 9998, "discount": 0, "estimated_tax": 0, "total": 9998, "currency": "USD" }
}snug cart get --cart <id> returns the full cart with per-line reservation
and price-lock snapshots; snug cart view shows the CLI's current cart
(cart add without --cart starts one). Only the owner or a platform
admin can touch a cart - anyone else gets 403 insufficient_permissions.
Reservations hold real stock
The hold is not advisory. With 50 units in the container and 2 already held
by the cart above, a second cart asking for 49 was refused. Changing a line
re-reserves at the new quantity; removing it gives the stock back
immediately ("Line removed and reservation released"). Reservations default
to strict mode; --reservation-mode soft or availability_check relax
the hold.
snug cart add docs4-world-pass --qty 49 --cart RtqjeSPBjYZBpsYerbny ...
# 409 reservation_conflict: "only 48 of HctVYVhHbdBKyrcsYFGF available to reserve"
snug cart update-item --cart ryLqjXLpyDPNThWdTNDL --line-id QXUhFTjaeQrSwMuBCfNd --qty 3
snug cart remove --cart ryLqjXLpyDPNThWdTNDL --line-id KuShdFrFVBfYyQJXscqEKeeping a cart valid
Reservations and price locks expire on their own clocks (15 minutes each by
default), so an open cart goes stale. revalidate reports per-line health
without mutating anything; price-lock re-locks prices:
snug cart revalidate --cart ryLqjXLpyDPNThWdTNDL # per-line reservation_valid / price_lock_valid + "valid": true
snug cart price-lock --cart ryLqjXLpyDPNThWdTNDL # returns refreshed_line_idsMerging a guest cart
On login, fold a guest cart into the user's cart. Lines merge by item_id,
per-item conflicts come back in a conflicts array with reason codes, and
the source cart is drained: its status becomes converted.
snug cart merge --cart ryLqjXLpyDPNThWdTNDL --source-cart RtqjeSPBjYZBpsYerbny
# { "merged_lines": 1, "conflicts": [], "totals": { ... } }Sharing
share mints a permission-scoped token (view, clone, or contribute)
with a TTL, and flips an active cart to shared; --revoke deletes the
token and flips it back.
snug cart share --cart ryLqjXLpyDPNThWdTNDL --mode view --ttl-seconds 3600
# { "share": { "token": "share_ATSMbycdFWtZhzuctshc", "permission": "view", ... } }
snug cart share --cart ryLqjXLpyDPNThWdTNDL --revokeThe token is state for your application layer to redeem - no cart endpoint
accepts it in this version, so sharing does not by itself open the cart:
a second user's direct GET still fails with 403 while sharing is enabled
(verified). A TTL above the maximum fails with 400 share_ttl_exceeded.
Checkout
split-checkout is a read-only preview of how the lines partition for
downstream orders - group by seller, warehouse, currency,
availability, or fulfillment (default inventory_source):
snug cart split-checkout --cart ryLqjXLpyDPNThWdTNDL --group-by currencycheckout-ready is the point of no return: it verifies every reservation is
still held, commits them in the Item Engine (stock is now consumed), freezes
the cart, and returns a handoff token for your order flow. Raw HTTP,
enveloped:
curl -X POST -H "Authorization: Bearer $SNUG_API_TOKEN" \
http://localhost:4000/api/v1/carts/ryLqjXLpyDPNThWdTNDL/checkout-ready{
"status": 200,
"msg": "OK",
"data": {
"cart_id": "ryLqjXLpyDPNThWdTNDL",
"status": "checkout_ready",
"checkout_token": "checkout_AQemDHpjrJFRxxDdqLxe",
"totals": { "subtotal": 20995, "discount": 0, "estimated_tax": 0, "total": 20995, "currency": "USD" }
}
}A frozen cart rejects further mutation (409 cart_not_active), and freezing
an empty cart or one with a lapsed reservation fails (400 /
409 reservation_conflict) - revalidate first if the cart has been sitting.
Abandonment and recovery
When a cart is abandoned - TTL expiry, inactivity, or a merge draining the
source - its holds are released and a recovery record is written with
reason (ttl_expired, inactivity, merged, cancelled),
item_count, estimated_value, and recovery_eligible, the raw material
for win-back flows. Both endpoints require a platform admin token:
snug cart abandoned --since 2026-08-28T00:00:00Z
snug cart sweep-abandoned # force a sweep pass now; returns { "swept": n }The list paginates and sorts (created_at, item_count), with repeatable
filter expressions in the shared
field:operator:value grammar.
Limits and configuration
100 lines per cart, 999 units per line, 30-minute cart TTL, 15-minute
reservation and price-lock windows, 7-day share-token maximum, and the
sweeper's cadence are all tunable via the CART_* variables in the
Cart CONFIG reference.
Reference
- Cart API - every endpoint, callable
- Related: Item Engine for the inventory behind the reservations, Auctions for bid-based selling, Promo Code for discount codes