Skip to content
autonym.dev
ContentsHide contents

Bindings

B4. REST binding

spec 1.0-draft-1

Status: normative. Binds the A8 recipient API to HTTP. Document version 1.0-draft-1.

B4.1 Contract and routes

The complete recipient contract is OpenAPI 3.1, generated from the same schema definitions as MCP. The file uses JSON syntax, which is valid YAML. This is a draft contract, not a deployed endpoint. Public discovery is unauthenticated; every recipient action is authenticated and authorised.

Use HTTPS, exact <origin>/v1 audience, and Autonym-Version:1.0 on protocol responses. Every access token is DPoP-bound (A6.3): a request carries Authorization:DPoP plus the DPoP header, and a token presented as Bearer is refused. Reject repeated scalar query parameters, malformed values, unknown fields and unknown protocol versions with invalid_request. Comma-separated domain/key lists have no empty items or duplicates. Maximum body size is 64 KiB, including nested values; a larger body fails payload_too_large. A context response has at most 1,000 entries; reject an over-limit request without a partial unmarked disclosure.

Method Path Result
GET /.well-known/autonym Provider discovery
GET /v1/grant Current authenticated grant
GET /v1/domains Eligible granted domains/keys, without counts
GET /v1/context Signed disclosure, one counted read
GET /v1/context/{domain} Same, with conditional-request support
POST /v1/proposals Contribution event acknowledgement
GET /v1/proposals/{id} Own proposal status only
POST /v1/proposals/{id}/confirm Exact-statement confirmation/review
DELETE /v1/proposals/{id} Withdraw own proposal
GET /v1/purge-instructions At most 100 outstanding signed instructions for this client
POST /v1/purge-instructions/{jti}/ack Purge acknowledgement

The path ID and body ID must match wherever both occur. Mutating requests other than contribution events require a client-scoped UUIDv4 Idempotency-Key, canonical-payload equality, and 30-day deduplication. A reused key with a different payload fails idempotency_conflict.

B4.2 Conditional reads

An ETag is a quoted opaque HMAC under a dedicated provider key of JCS containing the client, grant ID/revision, the A9 canonical request, sorted selected alias/version/level triples, temporal selection epoch and the previous envelope deadline. Store its association with that exact signed envelope and response hash. Never use a content-only ETag.

A matching If-None-Match may return 304 only while the prior envelope is still valid, its entire selection and authority still match, and the grant has not exhausted its read limit. This writes a read_not_modified event and counts towards rate limits but does not increment reads_used. It cannot extend a signed deadline. At or after any time boundary return a new counted signed response if permitted, or the relevant error. Revocation, counter checks and dependency checks cannot be bypassed through 304. Responses use Cache-Control:no-store; this conditional facility is only for a recipient's explicitly held, still-valid transient object.

B4.3 Errors and limits

errors.json is the closed registry, and problem.json is the exact RFC 9457 representation. Each registered code has one urn:autonym:error:<code> type, one status and one title, and names the sections whose text raises it; a response carries exactly that status. No rejected value, record content, credential or existence hint appears in an error. Authentication/token-endpoint errors retain their OAuth-defined representation, and a 401 also carries the A6.1 WWW-Authenticate challenge. The registry separately lists the OAuth codes this specification cites and the codes the B1 grant binding takes from its base specification (B1.9); they keep the representation their own specifications define and are not registered codes. handle_moved is deliberately removed; API migration does not redirect credentials or disclose a destination.

An unknown path answers not_found. An unexpected failure answers internal_error, and a provider that cannot reach its key storage or grant state answers not_ready (A15.3); neither says why.

The provider enforces at least per-client and per-grant rate limits and answers 429 rate_limited with Retry-After. Default ceiling is 60 authorised requests per minute per grant and 600 per minute per client; a provider may lower these published operational limits, but cannot silently increase consent limits.

Checks: TRANSPORT-01, WIRE-01, TEMP-03, CORE-01, LOG-01, PURGE-01, MIGRATE-01.

References to other standards and projects describe intended technical alignment only and do not imply endorsement or partnership.