AP2 Mandates Extension
Basic Information
- Capability Name:
dev.ucp.shopping.ap2_mandate - Version:
2026-01-11 - Official Specification: ap2-mandates.md
Overview
The AP2 Mandates extension enables the secure exchange of user intents and authorizations using Verifiable Digital Credentials.
When this capability is negotiated and active, it transforms a standard checkout session into a cryptographically bound agreement:
- Businesses MUST embed a cryptographic signature in checkout responses, proving the terms (price, line items) are authentic.
- Platforms MUST provide cryptographically signed proofs (Mandates) during the
completeoperation, proving the user explicitly authorized the specific checkout state and funds transfer.
Security Binding: Once this extension is negotiated in the capability intersection, the session is Security Locked. Neither party may revert to a standard (unprotected) checkout flow.
Design
All AP2-specific fields are nested under an ap2 object in both requests and responses. This design provides:
- Schema modularity — Base checkout schema stays clean; AP2 adds one field containing all its data.
- Consistent canonicalization — One rule: exclude
ap2from the business’s signature computation. Future AP2 fields are automatically handled. - Extension coexistence — Multiple security extensions can coexist without namespace collisions.
- Capability signal — Presence of
ap2object clearly indicates AP2 is active.
Discovery & Negotiation
Business Profile Advertisement
Businesses declare support by adding dev.ucp.shopping.ap2_mandate to their capabilities list in /.well-known/ucp.
Business Profile Example:
{
"capabilities": [
{
"name": "dev.ucp.shopping.ap2_mandate",
"version": "2026-01-11",
"spec": "https://ucp.dev/specification/ap2-mandates",
"schema": "https://ucp.dev/schemas/shopping/ap2_mandate.json",
"extends": "dev.ucp.shopping.checkout",
"config": {
"vp_formats_supported": {
"dc+sd-jwt": { }
}
}
}
]
}Activation and Session Locking
- The platform advertises its profile URI (transport-specific mechanism).
- The business fetches the profile and computes the intersection.
- If
dev.ucp.shopping.ap2_mandateis present in the intersection:- The business MUST include
ap2.merchant_authorizationin all checkout responses. - The business MUST NOT accept a
complete_checkoutrequest that lacksap2.checkout_mandate. - The platform MUST verify the business’s signature before presenting the checkout to the user.
- The business MUST include
Cryptographic Requirements
Signature Algorithm
All signatures MUST use one of the following algorithms:
| Algorithm | Description |
|---|---|
ES256 | ECDSA using P-256 curve and SHA-256 (RECOMMENDED) |
ES384 | ECDSA using P-384 curve and SHA-384 |
ES512 | ECDSA using P-521 curve and SHA-512 |
Business Authorization
Businesses MUST embed their signature in the checkout response body under ap2.merchant_authorization using JWS Detached Content format.
Checkout Response with Embedded Signature:
{
"id": "chk_abc123",
"status": "ready_for_complete",
"currency": "USD",
"line_items": [...],
"totals": [...],
"ap2": {
"merchant_authorization": "eyJhbGciOiJFUzI1NiIsImtpZCI6Im1lcmNoYW50XzIwMjUifQ..<signature>"
}
}Mandate Structure
Mandates are SD-JWT credentials with Key Binding (+kb). The platform MUST produce two distinct mandate artifacts:
| Mandate | UCP Placement | Purpose |
|---|---|---|
| checkout_mandate | ap2.checkout_mandate | Proof bound to checkout terms, protects business |
| payment_mandate | payment_data.token | Proof bound to payment authorization, protects funds |
Canonicalization
For signature computation over JSON payloads, implementations MUST use JSON Canonicalization Scheme (JCS) as defined in RFC 8785.
Canonicalization Rule: When computing the business’s signature, exclude the ap2 field entirely.
The Mandate Flow
Step 1: Checkout Creation & Signing
The platform initiates the session. The business returns the Checkout object with ap2.merchant_authorization embedded in the response body.
Example Response:
{
"id": "chk_abc123",
"status": "ready_for_complete",
"currency": "USD",
"line_items": [...],
"totals": [...],
"ap2": {
"merchant_authorization": "eyJhbGciOiJFUzI1NiIsImtpZCI6Im1lcmNoYW50XzIwMjUifQ..<signature>"
}
}The platform MUST verify the signature.
Step 2: User Consent & Mandate Generation
When the user confirms the purchase, the platform MUST facilitate the generation of cryptographically verifiable mandates.
Option 1: Trusted Platform Provider
A trusted platform provider acts on the user’s behalf to generate the mandate credentials.
Option 2: Digital Payment Credential
The user has a VDC issued from a source trusted by the business.
Step 3: Submission (complete_checkout)
Once the mandates are generated, the platform submits them in the completion request:
{
"payment_data": {
"id": "instr_1",
"handler_id": "gpay",
"type": "card",
"credential": {
"type": "PAYMENT_GATEWAY",
"token": "examplePaymentMethodToken"
}
},
"ap2": {
"checkout_mandate": "eyJhbGciOiJFUzI1NiIsInR5cCI6InZjK3NkLWp3dCJ9..."
}
}Error Codes
| Error Code | Description |
|---|---|
mandate_required | AP2 was negotiated, but the request lacks ap2.checkout_mandate |
agent_missing_key | Platform profile lacks a valid signing_keys entry |
mandate_invalid_signature | The mandate signature cannot be verified |
mandate_expired | The mandate exp timestamp has passed |
mandate_scope_mismatch | The mandate is bound to a different checkout |
merchant_authorization_invalid | The business authorization signature could not be verified |
merchant_authorization_missing | AP2 negotiated but response lacks ap2.merchant_authorization |