Skip to content

Universal Commerce Protocol

UCP is the open standard AI agents use to discover, price, and complete a purchase without a bespoke integration. Every public Sessions business is reachable from any agent that speaks it — over REST, MCP, or an embedded checkout the host frames.

Endpoint/.well-known/ucpSpec version2026-04-08TransportsREST · MCP

What Sessions exposes

One capability: checkout. An agent creates a checkout session for a single product or a single scheduled session, sets the buyer, and completes it. Underneath, the adapter calls the same checkout the website calls — so pricing rules, early-bird tiers, discount conditions, tax, capacity, confirmation email, and webhooks all behave identically whether the buyer used a browser or an agent.

Sessions sells services and digital goods, so UCP's fulfillment object is omitted — there is no shipping address, carrier, or delivery window to negotiate. The business remains merchant of record through its own Stripe connected account, which is exactly the payment model UCP assumes.

Capability
dev.ucp.shopping.checkout
Transports
rest, mcp
Payment handler
com.sessions.stripe
Identity scope
ucp:checkout_session

Discovery

Every participating business publishes a manifest at the well-known UCP path on its own origin. Fetch it first: it tells you which capabilities exist, which transports carry them, and how to pay.

There is no opt-in: every public, live business exposes the manifest and both callable bindings. A business that is private or has been deleted 404s, exactly as it does everywhere else on the public API — so UCP never reveals a business the rest of the surface hides.

Item ids are Sessions global ids
A line item's item.id is the same opaque gid://Sessions/… id the public API hands out, so anything you found through the public API or the public MCP server can go straight into a checkout session.
bash
curl https://go.sessions.website/@<handle>/.well-known/ucp

Reading the manifest

Four keys matter. Everything else is spec boilerplate you can ignore.

services
Where to send requests, one entry per transport. Pick rest or mcp; both reach the same capability.
capabilities
What this merchant implements. Today that is dev.ucp.shopping.checkout and nothing else.
payment_handlers
How to pay. Sessions advertises a single Stripe handler carrying the business's own publishable key and connected account.
signing_keys
Empty. Sessions does not yet sign responses or emit signed order webhooks, so no key is advertised rather than one you cannot verify against.
.well-known/ucp
{
  "ucp": {
    "version": "2026-04-08",
    "services": {
      "dev.ucp.shopping": [
        {"transport": "rest", "endpoint": "…/api/ucp/rest"},
        {"transport": "mcp",  "endpoint": "…/api/ucp/mcp"}
      ]
    },
    "capabilities": {
      "dev.ucp.shopping.checkout": [{"version": "2026-04-08"}]
    },
    "payment_handlers": {
      "com.sessions.stripe": [{
        "id": "stripe",
        "available_instruments": [{"type": "card"}],
        "config": {
          "gateway": "stripe",
          "publishable_key": "pk_…",
          "stripe_account": "acct_…",
          "credential_type": "PAYMENT_GATEWAY"
        }
      }]
    }
  },
  "signing_keys": []
}

What you can put in a checkout

A line item points at a Sessions product or a scheduled session, by its global id.

Products
gid://Sessions/Pass/…
A multi-visit pass. Requires a linked identity, because the remaining visits live on an account.
gid://Sessions/Membership/…
A recurring membership. Always escalates — the buyer has to authorise the recurring charge themselves.
gid://Sessions/GiftCard/…
A gift card. Works anonymously.
gid://Sessions/PhysicalProduct/…
A physical good. Always escalates today — shipping is not collected.
Registrations
gid://Sessions/ActivitySession/…
One scheduled class session. Registers the buyer, or escalates when the session collects a waiver or is full.
One item per checkout
Sessions buys one product or books one session per order, so a checkout session takes exactly one line item with quantity 1. For several items, create several checkout sessions.

Status

The session's status is the single thing to branch on.

incomplete
Something is still missing — usually the buyer's email, or a payment credential for a paid item. Update and try again.
ready_for_complete
Priced and complete-able. Nothing is reserved and nothing is charged yet.
complete_in_progress
A completion is running. A second complete is refused rather than charging twice.
requires_escalation
The purchase needs a step the protocol cannot express. Send the buyer to continue_url to finish in the browser.
completed
Fulfilled and immutable. order carries the id, label, and a permalink the buyer can open.
canceled
Abandoned. Terminal.

Escalation

Some purchases involve a step no commerce protocol has vocabulary for: signing a waiver, answering an intake question, authorising a recurring charge, passing a bank's 3-D Secure challenge. Rather than completing an order that is missing something the business legally or operationally needs, the session comes back requires_escalation with a continue_url.

Escalation can happen at create (the session collects a waiver, the item is a membership) or at complete (the card needs a challenge). Treat it as a normal outcome, not an error: hand the buyer the link and stop polling.

Escalation is not failure
The checkout page behind continue_url picks up exactly where the agent left off, so the buyer finishes rather than starts over.

The two bindings

Same capability, same objects, same messages. Pick whichever your platform already speaks — the reference for each lives with the rest of the public API.

/api/ucp/rest
Five HTTP routes under /api/ucp/rest. The natural fit for a server-side commerce integration, and the binding the wider UCP ecosystem targets first.
/api/ucp/mcp
The same five operations as JSON-RPC tools at /api/ucp/mcp. The natural fit for a conversational assistant already connected to Sessions for discovery — it can carry a session id straight from browse_sessions into create_checkout on the same connection.

Identity linking

Checkout works anonymously for most items — pass a buyer email and Sessions creates or finds the account, exactly as guest checkout does on the website. Linking the buyer's real Sessions identity is what unlocks account-bound purchases, because a pass's credits have to live on an account.

ucp:checkout_session
is the OAuth scope an agent requests to transact on a buyer's behalf. It uses the existing Sessions OAuth provider — authorization code with PKCE, discovered through the standard authorization-server metadata document — so there is no UCP-specific auth flow to implement.

The handshake is the same one the MCP servers use. OAuth reference

Payments

The manifest names a Stripe handler with the business's publishable key and connected account. Tokenize the card directly against that account, then send the resulting payment-method token as the instrument's credential when you complete. Sessions never sees the card number, and no PCI scope moves to your platform.

The business is merchant of record
Charges are direct charges on the business's own Stripe account. Refunds, disputes, and receipts are the business's — not the platform's and not yours.

Errors

Protocol errors and business outcomes are deliberately different things, and you branch on them differently.

Protocol errors — a non-2xx with `{code, content}`
400 · invalid_request
The request is malformed: no line item, more than one, a quantity above 1, or a body that isn't a JSON object.
404 · not_found
No such checkout session, no such route — or no such business on this host.
409 · sessions.invalid_state
The session can no longer be changed: it is completed, cancelled, mid-completion, or its quote expired.
429 · rate_limited
Rate limited. Back off for the interval in Retry-After.
Business outcomes — a 200 carrying `messages`
out_of_stock
The session filled up. Severity distinguishes a hard stop from a waitlist the buyer could still join.
item_unavailable
The item isn't for sale — hidden, outside its sale window, cancelled, or already past.
eligibility_invalid
A rule rejected this buyer or this code: an unmet discount condition, an intro offer already used, a closed registration window.
missing_buyer_info
Something has to come from the buyer before this can complete — their email, or a payment credential.
payment_failed
The card was declined, or it needs a challenge. Severity says which.
sessions.escalation_required
A step the protocol can't express is in the way. continue_url is set.
sessions.checkout_session_expired
The quote aged out. Create a new checkout session rather than completing a stale price.

Read severity before deciding what to do: recoverable means retry as-is, requires_buyer_input means collect something, requires_buyer_review means show the buyer before continuing, and unrecoverable means stop.

Idempotency

Send an Idempotency-Key on every mutation. A repeated create with the same key returns the original session instead of a second one, so a retry after a timeout never leaves a duplicate behind.

Completion is idempotent on its own terms too: completing an already-completed session returns the same order without charging again, and the underlying charge is keyed on the session so a racing retry reuses the original payment.

Discount and gift-card codes

UCP's discount capability isn't implemented, so codes ride in a Sessions-namespaced extension on create and update rather than pretending to be a capability we don't have. They are validated server-side; a rejected code returns a recoverable message and leaves the session priced at full price.

extension
"com.sessions.codes": {"discount": "SPRING20", "gift_card": "GC-…"}

References

Sessions implements the spec as published; these are the primary sources.

Protocol overview
The protocol overview — services, capabilities, payment handlers, and the discovery manifest. ucp.dev/specification/overview
Checkout capability
The checkout capability: the session object, its status machine, totals, and messages. ucp.dev/specification/checkout
HTTP / REST binding
The HTTP binding — routes, headers, and the protocol-error vs business-outcome split. ucp.dev/specification/checkout-rest
MCP binding
The Model Context Protocol binding — tool names, the meta argument, and the dual-output result shape. ucp.dev/specification/checkout-mcp
Embedded checkout binding
The embedded binding, for hosts that want to frame a merchant checkout rather than link to it. Sessions implements it, and every public business has it. ucp.dev/specification/embedded-checkout/

Sessions pins one dated version of the spec, advertised in every manifest and echoed in every payload.

Next