Data Models
All types are exported from@key0ai/key0 and are available as TypeScript imports:
ChallengeState
The state machine for a challenge record. All transitions are atomic and go throughIChallengeStore.transition().
AccessRequest
Sent by the client agent to initiate a payment flow. TherequestId serves as an idempotency key.
message/send (as a data part), x402 HTTP middleware request parsing.
Example:
X402Challenge
Returned by the server after receiving anAccessRequest. Contains all information the client needs to make a USDC payment.
PaymentProof
Sent by the client after completing an on-chain USDC transfer. Contains the transaction hash for verification.message/send (as a data part), ChallengeEngine.submitProof() input.
Example:
AccessGrant
Returned after successful payment verification. Contains the bearer token for accessing protected resources.ChallengeRecord
The internal record stored inIChallengeStore. Contains all challenge state, timestamps, and the access grant once delivered. Not directly exposed in API responses, but useful for understanding the storage layer.
statetransitions are atomic viaIChallengeStore.transition(id, fromState, toState, updates?, meta?).amountRawis the USDC amount in 6-decimal micro-units (e.g.,100000n= $0.10).accessGrantis persisted durably in the PAID state before the DELIVERED transition, using an outbox pattern.
NetworkConfig
Configuration for a supported blockchain network.| Network | Chain ID | USDC Address | Explorer |
|---|---|---|---|
testnet (Base Sepolia) | 84532 | 0x036CbD53842c5426634e7929541eC2318f3dCF7e | sepolia.basescan.org |
mainnet (Base) | 8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | basescan.org |
NetworkName
The two supported network identifiers.| Value | Chain | Chain ID | Description |
|---|---|---|---|
"testnet" | Base Sepolia | 84532 | Test network with test USDC. Use for development. |
"mainnet" | Base | 8453 | Production network with real USDC. |
Plan
Defines a pricing plan in the seller’s catalog.X402PaymentRequiredResponse
The x402 v2 payment-required response. Sent in 402 response bodies and thepayment-required header (base64-encoded).
X402PaymentPayload
The payment payload sent by the client, either in thePAYMENT-SIGNATURE HTTP header (base64url-encoded) or in MCP _meta["x402/payment"].
X402SettleResponse
The settlement receipt, returned in thepayment-response HTTP header (base64-encoded) and in MCP _meta["x402/payment-response"].
Error Codes
All errors use theKey0Error class with standardized codes:
| Code | HTTP Status | Description |
|---|---|---|
TIER_NOT_FOUND | 400 | Plan ID not found in the seller’s catalog. |
INVALID_REQUEST | 400 | Malformed request, missing required fields, or invalid input. |
CHALLENGE_NOT_FOUND | 404 | Challenge ID not found in the store. |
CHALLENGE_EXPIRED | 410 | Challenge TTL elapsed or was cancelled. |
TX_ALREADY_REDEEMED | 409 | Transaction hash already used for another challenge. |
TX_UNCONFIRMED | 202 | Transaction not yet confirmed on-chain. Retry later. |
INVALID_PROOF | 400 | On-chain verification failed (wrong amount, wrong destination, etc.). |
PROOF_ALREADY_REDEEMED | 200 | Challenge already paid. Returns the cached AccessGrant. |
CHAIN_MISMATCH | 400 | Proof chainId does not match the challenge chainId. |
AMOUNT_MISMATCH | 400 | Proof amount does not match the challenge amount. |
PAYMENT_FAILED | 402 | EIP-3009 verification or settlement failed. |
TOKEN_ISSUE_TIMEOUT | 504 | fetchResourceCredentials callback timed out. |
INTERNAL_ERROR | 500 | Unexpected error or concurrent state transition conflict. |

