Skip to main content
UCPQuote endpoint
UCP

Quote endpoint

Turn a cart and shipping details into a clear, server-approved checkout quote.

Checkout sessions — create, update, apply discounts, capture consent, complete. Idempotency-key required.

Aly's checkout session is the “quote” in UCP terms — a server-authoritative price including shipping, tax, and discounts for the buyer's exact line items and address. It's also the thing the buyer eventually pays against.

Lifecycle

  1. Create with line items + shipping address + buyer email. Server validates stock and pricing, computes shipping options and tax.
  2. Update (PUT) to change line items, address, or selected shipping option. Totals recompute.
  3. Apply discount (POST /discount) — adds a coupon code, recomputes totals.discount.
  4. Consent (POST /consent) — buyer agrees to the quoted shipping option and terms.
  5. Complete (POST /complete) or open the continue_url for human-in-the-loop payment.

Create a session

bash
curl -X POST https://aly.store/api/ucp/v1/checkout-sessions \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{    "line_items": [      { "product_id": "prod_abc", "quantity": 1 },      { "product_id": "prod_def", "variant_options": { "size": "L" }, "quantity": 2 }    ],    "shipping_address": {      "country": "US",      "state": "CA",      "postcode": "94110"    },    "buyer": { "email": "buyer@example.com", "name": "A. Buyer" }  }'
Idempotency-Key is required
Every state-changing call (create, update, discount, consent, complete) requires an Idempotency-Key header. The server fingerprints the request body and key together — replays return the original response; conflicts (same key, different body) return 409.

Response shape

json
{  "ucp": { "version": "1", "timestamp": "..." },  "id": "cs_8f...e2",  "status": "open",  "currency": "USD",  "line_items": [    {      "product_id": "prod_abc",      "variant_id": "var_1",      "name": "Linen Tote — natural",      "quantity": 1,      "unit_price": 4200,      "subtotal": 4200,      "image_url": "https://cdn.aly.store/..."    }  ],  "shipping_address": { "country": "US", "state": "CA", "postcode": "94110" },  "shipping_options": [    { "id": "ship_std", "label": "Standard 3-5d", "amount": 500, "selected": true },    { "id": "ship_exp", "label": "Express 1-2d", "amount": 1500, "selected": false }  ],  "totals": { "subtotal": 4200, "shipping": 500, "tax": 376, "discount": 0, "total": 5076 },  "messages": [],  "continue_url": "https://acme.aly.store/checkout/cs_8f...e2",  "created_at": "2026-05-19T08:30:00.000Z",  "updated_at": "2026-05-19T08:30:00.000Z"}

Update

bash
curl -X PUT https://aly.store/api/ucp/v1/checkout-sessions/cs_8f...e2 \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{    "selected_shipping_option_id": "ship_exp"  }'

Apply discount

bash
curl -X POST https://aly.store/api/ucp/v1/checkout-sessions/cs_8f...e2/discount \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{ "code": "WELCOME10" }'

The session response now carries totals.discount and a discount object on the session.

Buyer consent

bash
curl -X POST https://aly.store/api/ucp/v1/checkout-sessions/cs_8f...e2/consent \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{    "selected_shipping_option_id": "ship_std",    "accepted_terms_version": "2026-01"  }'

Complete the checkout

Two paths:

  • Human-in-the-loop — Direct the buyer to continue_url. They pay through the hosted checkout (Stripe). The session moves to completed on success.
  • x402 micro-payment — For digital products under the per-site limit, the buyer agent can pay directly. See x402 overview.

Status values

statusMeaning
openQuote is valid; buyer can keep editing.
requires_consentServer is waiting on a /consent POST.
completedOrder was placed; order field is populated.
expiredQuote ran past its TTL; create a new session.
cancelledExplicitly cancelled by buyer or server.

Messages

The messages array surfaces non-fatal notes: variant switched to default, item out of stock and removed, coupon expired. Display these to the buyer; they explain why totals or line items changed across an update.

Updated

Was this page helpful?