cimplify

Universal Commerce Protocol (UCP)

A signed, capability-discoverable protocol AI agents use to browse, price, check out, and pay across any Cimplify business with verifiable consent.

UCP is the agent-facing surface of every Cimplify business. Agents fetch a manifest, sign their requests, and check out on behalf of a principal with a cryptographic consent proof. There is no human in the loop, but every action is auditable end-to-end.

The agentic commerce landscape

Commerce is being reshaped by AI agents that browse, decide, and pay on behalf of humans. The industry is converging on a set of open patterns for this:

  • Google's Agent Payments Protocol (AP2): an open spec for agent-to-merchant payments with verifiable consent, capability discovery, and auditable mandate trails. AP2 also markets under the "Universal Commerce Protocol" framing.
  • Stripe's Agent Toolkit: agent-aware SDK helpers, restricted_keys scoped to specific actions, and shared receipts.
  • Anthropic's Model Context Protocol (MCP): generic protocol for exposing tools/resources to LLMs. Commerce surfaces can be exposed as MCP servers.
  • Visa Intelligent Commerce / Mastercard Agent Commerce Credentials: card-network mandates that bind a specific agent to a specific scope on the rails.

Cimplify's UCP is our take on the same problem, specifically tuned for the businesses you operate on Cimplify: every business gets a UCP manifest at a stable URL by default, and every storefront the SDK builds is automatically reachable by compliant agents. UCP is designed to interoperate with AP2 (the wire formats overlap intentionally) and to be exposed as an MCP server for agents that prefer that envelope.

You don't need to think about this if you're just building a storefront; UCP runs on the same backend as the public REST API, with the same data shapes. But if you're building an agent that transacts, this is your contract surface.

Why a separate protocol from the public API

Public REST assumes a browser session and a human who authenticates with OTP. UCP assumes a service-to-service identity with cryptographic consent on every mutation. The two share data shapes (cart, checkout, order) but differ in:

  • Authentication: UCP requests are HMAC-signed; public REST uses session cookies + OTP.
  • Authorization: UCP enforces consent scope at every mutation; public REST scopes by session.
  • Discovery: UCP publishes a typed manifest at a stable URL; public REST is documented but not introspectable.
  • Replay protection: UCP timestamps + body hashing prevent replay; public REST relies on idempotency keys.

You can think of UCP as Cimplify's equivalent of an OpenAPI spec served at a stable URL, with built-in auth and consent semantics that fit the agent operator model.

How it works

  1. Discover: fetch https://api.cimplify.io/ucp/v1/<business_handle> to get the business's manifest: capabilities, supported payment bindings, shipping config, contact, hours.
  2. Authenticate: sign every request with HMAC-SHA256 over timestamp.method.path.body_hash. The signature goes in X-Request-Signature: t=<timestamp>,v1=<signature> and the body hash in X-Body-Hash: <sha256_hex>.
  3. Identify: every request also carries an UCP-Agent header with an AgentIdentity payload: who the agent is, who it acts for, and any session it's part of.
  4. Consent: for any action that moves money or creates a binding obligation, attach a ConsentProof signed by the principal: scope (max amount, currency, expiry), action type, signature.
  5. Transact: call the capability endpoints exposed in the manifest. Cart, price, checkout. Same data shapes as the public REST API.

The manifest

GET https://api.cimplify.io/ucp/v1/sweet-bakery
{
  "business": {
    "handle": "sweet-bakery",
    "name": "Sweet Bakery",
    "contact": { "email": "hello@sweetbakery.test", "phone": "+233244000000" }
  },
  "capabilities": {
    "checkout": {
      "binding": "mobile_money",
      "currencies": ["GHS"],
      "min_amount": "5.00",
      "max_amount": "5000.00"
    },
    "shipping": {
      "modes": ["pickup", "local_delivery"],
      "delivery_radius_km": 15
    }
  },
  "endpoints": {
    "cart": "/ucp/v1/sweet-bakery/cart",
    "checkout": "/ucp/v1/sweet-bakery/checkout"
  }
}

Request signing

Every UCP request must be signed. The signing input is:

timestamp + "." + method + "." + path + "." + body_hash

Where body_hash is SHA256(body) for POST/PUT/PATCH, or empty for read methods. The signature is sent as:

X-Request-Signature: t=1715000000,v1=<hex_hmac_sha256>
X-Body-Hash:        <sha256_hex>
UCP-Agent:          <base64_agent_identity>

The server verifies the signature and rejects requests older than 5 minutes.

For mutations that bind the principal (checkout, recurring billing, refunds), the agent includes a ConsentProof:

{
  "action": "purchase",
  "scope": {
    "max_amount": "120.00",
    "currency": "GHS",
    "valid_until": "2026-05-12T18:00:00Z",
    "business_handle": "sweet-bakery"
  },
  "signature": "<principal_signature>",
  "issued_at": "2026-05-10T19:30:00Z"
}

The principal's signature is verified against a public key registered with Cimplify's key directory. Scope is enforced server-side: an agent with a max_amount: 120.00 proof cannot check out a 200 GHS cart.

Example: agent checkout

// 1. Discover what a business sells.
const manifest = await fetch(
  'https://api.cimplify.io/ucp/v1/sweet-bakery',
).then((r) => r.json())

// 2. Build a cart on behalf of the principal.
const cart = await ucp.post(`${manifest.endpoints.cart}`, {
  items: [{ product_id: 'prod_sourdough', quantity: 2 }],
})

// 3. Check out with a verifiable consent proof.
const order = await ucp.post(`${manifest.endpoints.checkout}`, {
  cart_id: cart.id,
  consent_proof: {
    action: 'purchase',
    scope: {
      max_amount: '120.00',
      currency: 'GHS',
      business_handle: 'sweet-bakery',
    },
    signature: principal.sign(challenge),
    issued_at: new Date().toISOString(),
  },
})

Interoperability

Cimplify UCP is designed to bridge cleanly to the broader agentic-commerce stack:

  • AP2 manifests: Cimplify can serve the AP2 manifest format at the same path on request (Accept: application/vnd.ap2+json). Capability shapes are nearly identical; we map our internal types to AP2 names at the edge.
  • MCP servers: every Cimplify business can expose its UCP capabilities as a Model Context Protocol server. Agents that speak MCP can call cart/checkout/order as MCP tools without learning UCP signatures.
  • Stripe agent toolkit: Cimplify's mobile-money and card-rails settlements layer can validate Stripe restricted_keys for agents that already have one.
  • Card-network credentials: when an agent presents a Visa Intelligent Commerce or Mastercard Agent Commerce credential, UCP accepts it as a substitute for the principal-signed ConsentProof with equivalent scope.

The wire format is intentionally boring: HMAC + JSON. Your agent code stays portable across networks; you only re-sign per business.

Status

UCP is in developer preview. The manifest format is stable; the auth scheme may evolve before GA. Production agents should pin to a UCP version header.

On this page