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
json
{
  "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

HeaderWhereRule
Authorizationevery checkout routeBearer <token>, constant-time
API-Versionevery checkout routemust be 2026-04-17
Content-TypePOST with a bodyapplication/json
Idempotency-Keyevery POST1–255 printable ASCII characters
Request-Idoptionalechoed back, bounded and filtered

Operations

OperationRouteSuccess
createCheckoutSessionPOST /acp/checkout_sessions201
updateCheckoutSessionPOST /acp/checkout_sessions/{id}200
getCheckoutSessionGET /acp/checkout_sessions/{id}200
completeCheckoutSessionPOST /acp/checkout_sessions/{id}/complete200
cancelCheckoutSessionPOST /acp/checkout_sessions/{id}/cancel200
Create a checkout sessionbash
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

SituationAnswer
first requestclaimed atomically before the merchant is called
same key, same body, still running409 idempotency_in_flight with Retry-After
same key, same body, finishedthe stored answer with Idempotent-Replayed: true
same key, different body422 idempotency_conflict
a 5xx resultnot cached — a clean retry runs again

Errors

CauseACP answer
merchant 404404 checkout_session_not_found
merchant 405 on cancel405 checkout_session_not_cancelable
merchant 400 / 422422 invalid_request_body
merchant 409409 checkout_session_conflict
merchant 401 / 403 / 5xx / other502 processing_error
backend timeout504 service_unavailable
gateway load shedding503 service_unavailable

Errors are ACP Error documents — type, code, message, and param where safe. The merchant's body is never forwarded.