V2 wire protocol
A normal HTTP 429 carries two signed choices: one durable free reservation and one sealed offer for finite paid capacity.
Implemented profile
- Protected application methods are
GETandHEADonly. - Issuer credentials and client proofs use Ed25519.
- Times and monetary atomic units are canonical decimal strings inside signed payloads.
- One SQLite Durable Object owns each canonical resource and method; the MVP uses
shard: 0. - Settlement mode is explicitly
mockfor local development orx402-exactfor exact EIP-3009 settlement.
Client proof on every operation
X429-Client-Key: ed25519:<raw-public-key>
X429-Client-Time: <13-digit Unix milliseconds>
X429-Request-Nonce: req_<unique identifier>
X429-Client-Signature: ed25519:<signature>
Idempotency-Key: idem_<identifier> # state transitions
The client signs deterministic JSON containing domain, version, method, configured authority, exact path and query, body SHA-256, credential SHA-256, payment-signature SHA-256, public-key thumbprint, timestamp, nonce, and optional idempotency key. The server allows 30 seconds of clock skew. Stateful admission, result, bid, settlement-submission, and redemption operations spend proof nonces durably; the first stateless exact-payment challenge verifies its fresh proof without creating a replay row.
Overload response
HTTP/1.1 429 Too Many Requests
Retry-After: 2
X429-Version: 2
Link: </.well-known/x429.json>; rel="service-desc"
Cache-Control: no-store
{
"type": "x429.offer",
"x429": 2,
"issuer": "https://issuer.example",
"resource": "https://api.example/v1/infer",
"ticket": "<signed x429.ticket envelope>",
"auction": "<signed x429.auction.offer envelope>",
"redeem": {
"method": "same-request",
"ticketHeader": "X429-Ticket",
"paidPermitHeader": "X429-Award",
"clientProofRequired": true
},
"settlement": { "mode": "x402-exact" }
}
The free ticket already owns one future free slot. The auction offer exposes the epoch, K paid slots, reserve, ceiling, asset, network, target window, clearing rule, seed commitment, and configuration hash.
Signed envelope
{
"version": 2,
"alg": "Ed25519",
"kid": "x429-2026-07",
"payload": { "type": "x429.ticket", "protocolVersion": 2, "...": "..." },
"signature": "ed25519:<base64url>"
}
The signature covers the deterministic JSON object containing exactly version, alg, kid, and payload. Verification requires an exact algorithm, key ID, type, issuer, and audience match. There is no fallback key and no embedded credential key.
Free redemption
GET /v1/infer HTTP/1.1
X429-Ticket: <encoded signed ticket>
Idempotency-Key: redeem_<unique>
X429-Client-Key: ed25519:...
X429-Client-Time: ...
X429-Request-Nonce: req_...
X429-Client-Signature: ed25519:...
The proof binds the exact ticket header. The coordinator verifies subject, resource, method, configuration hash, ticket nonce, reservation, and window, then acquires one durable execution identity. A pre-dispatch failure can release it; protected-origin dispatch irrevocably consumes admission, so replay cannot execute the application a second time even when no response returns.
Sealed paid path
POST /x429/v2/bidsonce with the signed ticket, signed auction offer, and a canonical atomic-unit maximum.- Wait until the signed configured close time, then call
GET /x429/v2/bids/{bidId}with a fresh proof and the original ticket. - If won, receive a signed award. Research/mock profiles can use uniform K+1 clearing; deployed exact profiles use the one signed fixed price.
- In exact mode, recheck that the award fits the task deadline, build an EIP-3009 authorization from the returned
PAYMENT-REQUIREDchallenge, durably commit the non-secret recovery record, and only then callPOST /x429/v2/awards/{awardId}/settleonce withPAYMENT-SIGNATURE. A failed commit sends no payment request; a successful response includes the permit andPAYMENT-RESPONSE. - Redeem the permit once in
X429-Awardduring its paid slot.
In research/mock mode, when N is no greater than K, winners clear at the reserve; otherwise all winners clear at the greater of the reserve and the K+1th maximum. In deployed exact mode, N and K are both one and reserve equals maximum, so no competitive price formation occurs. No profile locks funds when a bid is submitted.
Exact auction placement leaves the configured payment timeout, bounded dual-RPC chain-observation timeout, settlement grace, and a fixed 2,000ms permit-delivery lead after close, rounded to a capacity interval. Deployed exact configuration requires at least a 180,000ms observation timeout. The launch templates use 20 seconds + 240,000ms with 60,000ms polls and four attempts + 10 seconds + 2 seconds, or 272 seconds before rounding. The target is bounded by X429_MAX_FUTURE_WINDOWS; if every eligible paid target is occupied, the Worker returns 503 auction_horizon_full instead of crossing the bound. Clients bid only when the latest possible paid slot fits the task deadline; they do not infer usability from auction close alone.
PAYMENT-SIGNATURE. Facilitator success is only a submission claim: in the synchronous deployed profile, two independently administered RPC providers must agree on the Base safe tagged boundary block number and hash, the receipt, exact USDC events, and minimum depth within that boundary before either ledger is confirmed or a permit is issued. Base safe typically takes about two minutes and is not irreversible. Automatic proof is capped at four attempts and 40 RPC requests total; insufficient depth, timeout, disagreement, or provider failure remains indeterminate. Base finalized, typically about 20 minutes, is used only by delayed recovery, refund, expired-unspent, and transaction-discovery paths in the launch profile. The client may retry only explicit payment_confirmation_persistence_pending once with the identical authorization/body/idempotency; otherwise it retains that pending record and must not resubmit. An authenticated operator resolves the intent through POST /x429/v2/admin/payment-intents/{paymentIntentId}/reconcile using dual-RPC chain evidence; after confirmation, the original client calls the signed payment-resume route without a new wallet authorization.Discovery
GET /.well-known/x429.json
V2 Worker discovery publishes the exact issuer and audience, one active Ed25519 key, proof headers, bid/result/settlement endpoints, paymentResume: /x429/v2/payment-intents/{paymentIntentId}/resume, finite lane quotas, epoch rule, atomic reserve and ceiling, asset, network, supported payment mode, and configuration hash. Exact-mode discovery also publishes payment.admissionChainSecurity: two providers, securityLevel: "safe" for the deployed synchronous profile, minimumDepthWithinBoundary, timeout, poll interval, maximum attempts, and maximum RPC requests. Clients still pin issuer, audience, key id, and public key out of band; discovery alone is not trust.
The resume request carries the original signed award, original settlement idempotency key, and fresh proof from the same client identity. It accepts no PAYMENT-SIGNATURE. When confirmation arrives after the original slot, the coordinator allocates one unused future paid slot outside auction target windows and rotates the permit nonce; a full recovery horizon fails closed.
Failure behavior
| Condition | Result |
|---|---|
| Missing or invalid proof | 401; no capacity is consumed. |
| Early free or paid redemption | 425 with the signed window still authoritative. |
| Expired credential | 410; re-enter normal policy. |
| Proof, ticket, permit, or idempotency replay | 409; no second admission. |
| Future scheduling horizon full | 503 rather than a false reservation. |
| Paid auction horizon full | 503 auction_horizon_full; no paid target outside the configured bound and no automatic retry loop. |
| Coordinator overload or storage uncertainty | Fail closed with 503 and no automatic retry loop. |
| Indeterminate payment settlement | 409 or 503 with a locked payment intent and recovery identifier; no permit until authenticated dual-RPC reconciliation. |
| Confirmed payment after its original slot | One unused future paid slot and rotated permit nonce, or fail closed if the configured recovery horizon is full. |
| Unsupported protected method | 405; v2 does not proxy side-effecting application requests. |
Upstream execution
Free and paid redemption acquire a durable execution lease before proxying to the fixed upstream. The Worker sends a short-lived X429-Origin-Assertion bound to the issuer, upstream audience, exact method and target, lane, request id, receipt digest, expiry, and nonce. It is signed by a separate origin-assertion key, not the public protocol issuer key. The upstream pins that dedicated key, verifies every field, and consumes the nonce durably. A lease reduces duplicate work across retries; it is not a general transaction replay system, which is why protected application methods are limited to GET and HEAD.
Starting protected-origin dispatch irrevocably consumes redemption. A dispatch timeout or transport failure returns upstream_outcome_unknown with the signed admission receipt; the receipt proves consumption, not a known application result. Any returned status also consumes admission. Non-redirect responses stream onward; a 3xx is never followed and becomes non-retryable 502. No later transport, body-stream, or client-delivery failure can replay or automatically refund the credential.