API Reference
Complete reference for the CardZero REST API. All requests and responses use JSON. The API base URL is https://api.cardzero.ai.
Authentication
CardZero uses two authentication methods:
Obtained via /auth/claim or /auth/login. Pass in the Authorization header:
Authorization: Bearer eyJhbGci...
Generated during wallet claim. Format: czapi_prefix_secret. Pass in the Authorization header:
Authorization: Bearer czapi_abc123_xxxxxxxx
API Keys are bound to a specific wallet. An Agent can only access the wallet its API Key was generated for. The walletId is derived from the API Key on the server -- it is not passed in the request body for payment endpoints.
Error Responses
All errors follow this format:
{
"error": "ERROR_CODE",
"message": "Human-readable description"
}UNAUTHORIZED -- Missing or invalid tokenFORBIDDEN -- Token valid but no access to this resourceINSUFFICIENT_BALANCE -- Wallet balance too low for payment + feeWALLET_FROZEN -- Wallet is frozen by ownerWALLET_NOT_ACTIVE -- Wallet not yet claimed/deployedNO_SESSION_KEY -- Internal signing key unavailable (auto-managed, rarely seen)SPEND_LIMIT_EXCEEDED -- Per-transaction or daily limit exceededCLAIM_KEY_INVALID -- Claim key expired, used, or wrongUSERNAME_TAKEN -- Username already registeredDUPLICATE_PAYMENT -- Idempotency key already usedEndpoints
Authentication
/v1/walletsCreate a new wallet. This is a zero-gas, off-chain operation. Returns a wallet address (pre-computed via CREATE2) and a one-time claim key.
{
"name": "my-agent-wallet" // optional
}{
"walletId": "wallet_abc123",
"walletAddress": "0x1234...5678",
"claimKey": "czk_lookup_secret",
"status": "pending"
}The wallet address is valid immediately -- you can send USDC to it before claiming. The claim key expires after 7 days.
/v1/auth/claimClaim a wallet, deploy the smart contract on-chain, and create an owner account. Returns JWT token and Agent API Key.
{
"claimKey": "czk_lookup_secret",
"username": "alice",
"password": "min8chars"
}{
"token": "eyJhbGci...",
"userId": "user_xyz",
"walletId": "wallet_abc123",
"walletAddress": "0x1234...5678",
"agentConfig": {
"apiKey": "czapi_prefix_secret",
"walletId": "wallet_abc123"
}
}Takes 20-60 seconds (contract deployment). The API Key is shown only once. Username: 3-20 chars, alphanumeric + underscore. Password: min 8 chars.
/v1/auth/loginLog in with username and password. Returns JWT token for Dashboard access.
{
"username": "alice",
"password": "min8chars"
}{
"token": "eyJhbGci...",
"userId": "user_xyz"
}Wallets
/v1/walletsList all wallets owned by the authenticated user.
{
"wallets": [
{
"id": "wallet_abc123",
"name": "my-agent-wallet",
"chain_address": "0x1234...5678",
"status": "active",
"frozen": 0,
"tx_limit": "5.00",
"daily_limit": "50.00",
"created_at": 1710000000
}
]
}/v1/wallets/:walletIdGet detailed information about a specific wallet, including a Config Summary block.
{
"id": "wallet_abc123",
"name": "my-agent-wallet",
"chain_address": "0x1234...5678",
"status": "active",
"frozen": 0,
"tx_limit": "5.00",
"daily_limit": "50.00",
"expires_at": null,
"created_at": 1710000000
}/v1/wallets/:walletId/balanceQuery the USDC balance of a wallet on Base.
{
"walletId": "wallet_abc123",
"balance": "142.50",
"currency": "USDC"
}/v1/wallets/:walletId/configUpdate spending rules for the wallet. All fields are optional -- only provided fields are updated on-chain.
{
"txLimit": "5.00", // max USDC per transaction
"dailyLimit": "50.00", // max total USDC per day
"expiresAt": 1710864000, // unix timestamp, policy expiry
"whitelist": ["0xabc..."] // allowed recipient addresses
}{
"message": "Config updated",
"txHash": "0x9876..."
}Values are in USDC (human-readable). The contract stores them as 6-decimal integers internally.
/v1/wallets/:walletId/freezeImmediately freeze the wallet. All payment attempts will be rejected until unfrozen.
{
"message": "Wallet frozen",
"txHash": "0x9876..."
}/v1/wallets/:walletId/unfreezeUnfreeze a frozen wallet, allowing payments to resume.
{
"message": "Wallet unfrozen",
"txHash": "0x9876..."
}/v1/wallets/:walletId/api-key/rotateGenerate a new API Key for this wallet. The old key is immediately invalidated.
{
"apiKey": "czapi_newprefix_newsecret",
"walletId": "wallet_abc123",
"message": "API key rotated successfully"
}The new API Key is shown only once. Give it to your Agent to replace the old one.
Payments
/v1/paymentsMake a direct USDC payment from the wallet. The wallet ID is derived from the API Key -- do not pass it in the body.
{
"to": "0xrecipient...",
"amount": "5.00",
"idempotencyKey": "unique-request-id" // optional, prevents duplicate payments
}{
"paymentId": "pay_abc123",
"status": "confirmed",
"txHash": "0x1234...",
"amount": "5.00",
"fee": "0.10"
}A 2% fee is deducted separately from the wallet. The recipient receives the full amount. Session keys are managed automatically.
/v1/payments/:paymentIdCheck the status of a specific payment. Payment IDs are not guessable.
{
"id": "pay_abc123",
"wallet_id": "wallet_abc123",
"to_address": "0xrecipient...",
"amount": "5.00",
"type": "direct",
"status": "confirmed",
"tx_hash": "0x1234...",
"fee_amount": "0.10",
"created_at": 1710000000
}/v1/wallets/:walletId/paymentsList payment history for a wallet. Supports pagination.
{
"payments": [
{
"id": "pay_abc123",
"wallet_id": "wallet_abc123",
"to_address": "0xrecipient...",
"amount": "5.00",
"type": "direct",
"memo": null,
"status": "confirmed",
"tx_hash": "0x1234...",
"fee_amount": "0.10",
"fee_recipient": "0xfee...",
"created_at": 1710000000
}
]
}Query params: ?limit=20&offset=0. Type is 'direct' for regular payments, 'x402' for HTTP auto-payments.
/v1/x402/payMake an x402 protocol payment. Used by Agents to pay for HTTP resources that return 402 Payment Required with x402 headers.
{
"paymentHeader": "base64-encoded-json",
"idempotencyKey": "unique-request-id" // optional
}{
"paymentId": "pay_xyz789",
"status": "confirmed",
"txHash": "0x5678...",
"amount": "0.50",
"fee": "0.01"
}The paymentHeader is a base64-encoded JSON object from the x402 server's 402 response. It contains the recipient, amount, network, and asset information.
Rate Limits
Rate limit headers are included in responses: X-RateLimit-Remaining, X-RateLimit-Reset.