Protocol surfaces
ACP checkout
Experimental ACP 2026-04-17: discovery and the five checkout operations under /acp.
ExperimentalACP stable snapshot
2026-04-17, REST binding, checkout service only. Off unless protocols.acp.enabled is true.Discovery
GET
/.well-known/acp.jsonpublic{
"protocol": {
"name": "acp",
"version": "2026-04-17",
"supported_versions": ["2026-04-17"]
},
"api_base_url": "https://merchant.example.com/acp",
"transports": ["rest"],
"capabilities": { "services": ["checkout"] }
}Public, Cache-Control: public, max-age=3600. Optional metadata (documentation_url, supported_currencies, supported_locales, intervention_types) appears only when configured.
Required headers
| Header | Where | Rule |
|---|---|---|
Authorization | every checkout route | Bearer <token>, constant-time |
API-Version | every checkout route | must be 2026-04-17 |
Content-Type | POST with a body | application/json |
Idempotency-Key | every POST | 1–255 printable ASCII characters |
Request-Id | optional | echoed back, bounded and filtered |
Operations
| Operation | Route | Success |
|---|---|---|
createCheckoutSession | POST /acp/checkout_sessions | 201 |
updateCheckoutSession | POST /acp/checkout_sessions/{id} | 200 |
getCheckoutSession | GET /acp/checkout_sessions/{id} | 200 |
completeCheckoutSession | POST /acp/checkout_sessions/{id}/complete | 200 |
cancelCheckoutSession | POST /acp/checkout_sessions/{id}/cancel | 200 |
curl -s http://localhost:8080/acp/checkout_sessions \
-H "Authorization: Bearer $ACP_BEARER_TOKEN" \
-H "API-Version: 2026-04-17" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"line_items":[{"id":"item_123"}],"currency":"usd","capabilities":{}}'Requests are validated against the vendored schema before the pipeline runs, and your backend's answer is validated before anything is returned. payment_data reaches your backend unchanged; it is never converted into an x402 payment.
Idempotency
| Situation | Answer |
|---|---|
| first request | claimed atomically before the merchant is called |
| same key, same body, still running | 409 idempotency_in_flight with Retry-After |
| same key, same body, finished | the stored answer with Idempotent-Replayed: true |
| same key, different body | 422 idempotency_conflict |
| a 5xx result | not cached — a clean retry runs again |
Errors
| Cause | ACP answer |
|---|---|
| merchant 404 | 404 checkout_session_not_found |
| merchant 405 on cancel | 405 checkout_session_not_cancelable |
| merchant 400 / 422 | 422 invalid_request_body |
| merchant 409 | 409 checkout_session_conflict |
| merchant 401 / 403 / 5xx / other | 502 processing_error |
| backend timeout | 504 service_unavailable |
| gateway load shedding | 503 service_unavailable |
Errors are ACP Error documents — type, code, message, and param where safe. The merchant's body is never forwarded.