Universal Commerce Protocol
UCP lets a business publish rules an agent platform reads before it submits a request. That sounds like somewhere a merchant's policy could live. For discrete rules it is; for anything computed it is not, and the boundary is worth knowing before you design around it.
A UCP Value Constraint is enum or const over a field. It has no arithmetic and no comparison across fields.
So this publishes cleanly — the platform learns the rule and stops sending requests that break it:
{
"path": "$['line_items'][*]",
"properties": { "quantity": { "const": 1 } }
}And this cannot be published at all, in any form: net margin, after every discount, shipping cost and channel fee, must clear the floor. There is no expression for it, because a constraint states which values a field may take and margin is not a field — it is arithmetic over several of them, using a cost basis the platform does not hold and should not.
That is not a defect in UCP. Constraints exist to save a round-trip on rules the platform can check itself, and the specification is explicit that the merchant’s response remains authoritative. The mistake would be reading the mechanism as a policy engine and designing a merchant integration that assumes rules can be pushed to the platform. Most interesting rules cannot.
Two categories of rule, answered in two different places.
Discrete allow-lists and pinned values: permitted quantities, settled currencies, a SKU allow-list, a shipping method. Publishing these narrows what arrives and saves both sides a rejected request.
Anything computed: margin against a verified cost basis, stacked promotions against what the order is finally worth, live availability at the instant of checkout, whether this agent is within its discretion. These are decided when the request arrives, against facts only the merchant holds.
UCP already carries the three answers a merchant needs. They are existing primitives, not extensions.
| UCP primitive | What the spec says | Verdict |
|---|---|---|
| Operation succeeds | The merchant response is authoritative for the state after an operation. | ALLOW |
| Outstanding Action | Actions gate extension-defined work and prevent a Cart or Checkout operation from succeeding until they are processed. | ESCALATE |
| Error | A decline carries an error code. | BLOCK |
The escalation case is the one worth noticing. An outstanding Action is not a decline — it holds the operation until the work is processed, which is exactly what a merchant needs when an order should wait for a person rather than be refused. The primitive already exists in the protocol and is mostly unused for policy.
Built. A verdict can be returned in the shape above: an allow omits actions entirely, as the specification requires; an escalation returns an outstanding Action keyed to a reference the resolve endpoint accepts; a block returns a refusal.
Not built. Verifying an inbound UCP request the way ACP webhook signatures and AP2 mandates are verified. This is a mapping of an answer onto UCP’s vocabulary, not a UCP-verified integration, and nothing here should be read as though it were.
Not asserted. The refusal path leaves the UCP error code unset rather than guessing one, because the specification’s error-code section was not retrievable when the mapping was written. A plausible-looking code would produce something that reads as conformant and is not.
Decionis is not a member, partner or certified implementer of UCP. The protocol is named here because it is what arrives at a merchant’s checkout.
The merchant’s side of an agent-placed order covers ACP and AP2 alongside this, and what each leaves to you.