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.
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.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.curl https://go.sessions.website/@<handle>/.well-known/ucpReading the manifest
Four keys matter. Everything else is spec boilerplate you can ignore.
servicesrest or mcp; both reach the same capability.capabilitiesdev.ucp.shopping.checkout and nothing else.payment_handlerssigning_keys{
"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.
gid://Sessions/Pass/…gid://Sessions/Membership/…gid://Sessions/GiftCard/…gid://Sessions/PhysicalProduct/…gid://Sessions/ActivitySession/…Status
The session's status is the single thing to branch on.
incompleteready_for_completecomplete_in_progresscomplete is refused rather than charging twice.requires_escalationcontinue_url to finish in the browser.completedorder carries the id, label, and a permalink the buyer can open.canceledEscalation
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.
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/api/ucp/mcpIdentity 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.
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.
Errors
Protocol errors and business outcomes are deliberately different things, and you branch on them differently.
400 · invalid_request404 · not_found409 · sessions.invalid_state429 · rate_limitedRetry-After.out_of_stockitem_unavailableeligibility_invalidmissing_buyer_infopayment_failedsessions.escalation_requiredcontinue_url is set.sessions.checkout_session_expiredRead 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.
"com.sessions.codes": {"discount": "SPRING20", "gift_card": "GC-…"}References
Sessions implements the spec as published; these are the primary sources.
Protocol overviewCheckout capabilityHTTP / REST bindingMCP bindingEmbedded checkout bindingSessions pins one dated version of the spec, advertised in every manifest and echoed in every payload.