Universal Commerce Protocol
An agent reaches your checkout with a cart, a payment instrument and a signed mandate proving nobody tampered with the terms. None of that answers the question you have to answer before you charge the card: was this agent allowed to commit this order, under your rules, right now?
requires_escalation is in every published UCP release, and a checkout that reports it MUST carry a continue_url.
UCP’s checkout status enum runs incomplete, requires_escalation, ready_for_complete, complete_in_progress, completed, canceled. The specification describes the second one as covering “regulatory requirements, merchant policies, or capabilities the agent does not yet support”.
So the protocol has a state for this cannot complete on its own, and here is where it continues — and says nothing about who decides a checkout belongs there, or what evidence that decision leaves behind. Those are the two things you are accountable for when an order is placed outside your own systems at 02:17.
An escalation is not a decline. The order waits for a named person instead of being refused, and the agent can retry once that person has answered.
The verdict tokens travel unchanged. A checkout is not the place to invent a fourth vocabulary.
| Verdict | What happens | In UCP |
|---|---|---|
| ALLOW | The completion proceeds. | No status is claimed. Authority raising no objection is not a claim that the checkout is otherwise ready — that answer belongs to the business. |
| ESCALATE | The completion is held, not refused. | status becomes requires_escalation, and continue_url — which UCP makes mandatory in that state — is where a human authority resolves it. |
| BLOCK | The completion is refused. | There is no UCP status meaning “never”, so the call fails with an error carrying a vendor-namespaced code. UCP permits freeform codes. |
Approval is evidence, not a verdict. Resolving an escalation re-runs the original request through the protocol with the approval in context, and the new outcome is what decides. A recorded approval never becomes an allow on its own.
AP2 names exactly two signers, and neither of them is an authority.
AP2 names exactly two signers, and no third party may generate or sign a mandate claim. So AP2 proves the terms were not tampered with and that consent was captured — it cannot express whether the principal held the authority to commit those terms. That is a different question, and it travels alongside the mandates rather than inside them.
This is why the verdict rides as a vendor extension and inside UCP’s own signals object, never as a mandate. It is also why the two compose instead of competing: the mandate proves the order was not altered, and the dossier proves the order was permitted.
UCP negotiates by exact dated version, so availability is not a footnote.
Escalation therefore goes through the status enum, which every release carries. An outstanding Action is added only where the negotiated release has one. The current extension targets 2026-08-25; the April status/continue_url path remains supported. If you are designing a merchant integration against Actions or request_constraints, check which release your platform negotiated first — the reference has the table.
Built. The verdict mapping above, version-aware, with a signed Decision Dossier behind every answer and a refusal that carries a namespaced error code — UCP permits freeform codes. The extension is published: capability declaration, JSON Schema, and worked examples, validated against the specification before release.
Verified on the way in. When AP2 is negotiated, the business’s own merchant_authorization is re-checked against the checkout that arrived — detached JWS, ES256/384/512, key by kid, RFC 8785 canonicalisation. If anything altered the line items, totals or currency after you signed the terms, the completion is refused before policy is even asked. The checkout mandate’s issuer signature, expiry, and binding to this exact order are checked too. Generate the signing key to turn that check on — until then the signature is reported as not checked rather than as verified, which is honest and inert. Registering one also commits you to it: once an organisation has had a key, a checkout that negotiated AP2 is refused whenever no active key remains, rather than quietly going unchecked. The private half is created in your browser and never reaches us.
Enforcing by default. A checkout sent without an explicit mode is evaluated in ENFORCEMENT. The alternative was inheriting the organisation’s configured mode, which is usually shadow — and a shadow checkout reports ready_for_complete even on an escalation, because shadow records and never holds. A deliberate shadow run is still one field away.
Not built. SD-JWT selective-disclosure digests and key binding on the checkout mandate. Those belong to the AP2 credential specification rather than to UCP, and a partial implementation that reported success would be worse than one that says what it skipped — so every response carries what was checked and what was not.
Not claimed. Decionis is not a member, partner or certified implementer of UCP, and no merchant is running this extension in production yet. The protocol is named here because it is what arrives at a merchant’s checkout.
The extension reference has the schema and the examples. The merchant’s side of an agent-placed order covers ACP and AP2 alongside this, and what each leaves to you.