CryptoCadet

Reference

HTTP gateway API

Everything the CLI does to pay for an item is plain HTTP, so any client can do it. This page is for building your own.


Items live at https://api.v4.cryptocadet.app/v4/g/<handle>/<slug>. Proxy items also accept a sub-path, /v4/g/<handle>/<slug>/<path>, and any method. Hosted items accept GET and HEAD. All amounts are strings in micro-dollars (USDC base units): "50000" is $0.05.

The 402 response

A paid item requested without payment answers 402. A free item is served straight away. The body:

402 Payment Required
{
  "error": "payment_required",
  "message": "Payment required",
  "x402Version": 1,
  "resource": "https://api.v4.cryptocadet.app/v4/g/acme/market-brief",
  "product": {
    "name": "Market brief",
    "description": "One-page summary for agents",
    "kind": "hosted",
    "seller": "seller@example.com"
  },
  "price": { "amount": "0.05", "currency": "USD", "micros": "50000" },
  "per": "query",
  "restricted": false,
  "accepts": [
    {
      "scheme": "cryptocadet-credits",
      "rail": "credits",
      "header": "X-CryptoCadet-Agent",
      "format": "ccx_agent_…",
      "maxAmountRequired": "50000",
      "resource": "https://api.v4.cryptocadet.app/v4/g/acme/market-brief",
      "description": "Spends the agent owner’s card-funded credits"
    },
    {
      "scheme": "cryptocadet-v4",
      "rail": "usdc",
      "network": "base",
      "chainId": 8453,
      "asset": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
      "maxAmountRequired": "50000",
      "payTo": "0xSellerPayoutAddress",
      "resource": "https://api.v4.cryptocadet.app/v4/g/acme/market-brief",
      "quoteUrl": "https://api.v4.cryptocadet.app/v4/gateway/quotes",
      "quoteBody": { "handle": "acme", "slug": "market-brief" },
      "proofHeader": "X-PAYMENT",
      "proofFormat": "{\"quoteId\",\"txHash\",\"redeemToken\"} as JSON or base64 JSON",
      "router": "0xffe91f1582080c85f7651fa32de2186df1b9343b",
      "routerMethod": "payWithToken(address,address,uint256)",
      "calldataSuffix": "quoteId (16 bytes, uuid without dashes)",
      "feePercent": 3
    }
  ]
}
  • accepts lists the ways to pay, in the x402 style. Pick one by rail.
  • The usdc entry is present only when the seller has a payout address and the item isn't private. The router fields appear when payments go through the CryptoCadetRouter, as they do on Base mainnet.
  • For a private item, per is "grant" and restricted is true.
  • When a payment attempt is refused, the 402 body also carries a code and a specific message (see Errors).

Paying with card credits

Send an agent token in the header the 402 names:

Request
curl https://api.v4.cryptocadet.app/v4/g/acme/market-brief -H "X-CryptoCadet-Agent: ccx_agent_…"

Authorization: Bearer ccx_agent_… also works; for proxy items that header is removed before the request is forwarded, so the token never reaches the seller. The server checks the token, its caps and allowed sellers, and your balance, then charges and serves the item in one step. No retry is needed.

WarningSend an agent token only to https://api.v4.cryptocadet.app. Anyone who holds it can spend your credits up to its caps. The CLI enforces this for you.

Paying with USDC

  1. Get a quote. POST the quoteBody to the quoteUrl. No account is needed.

    Request
    curl -X POST https://api.v4.cryptocadet.app/v4/gateway/quotes \
      -H "Content-Type: application/json" \
      -d '{"handle":"acme","slug":"market-brief"}'
    
    201 Created
    {
      "quote": {
        "quoteId": "4f9c2a1e-8b7d-4c3a-9e21-0d5f6a7b8c9d",
        "chainId": 8453,
        "token": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
        "recipient": "0xSellerPayoutAddress",
        "amount": "50000",
        "purpose": "per_call",
        "expiresAt": 1793520300,
        "router": "0xffe91f1582080c85f7651fa32de2186df1b9343b",
        "serverSig": "…"
      },
      "redeemToken": "ccr_…",
      "resource": "https://api.v4.cryptocadet.app/v4/g/acme/market-brief"
    }
    

    Keep the redeemToken private: it proves you are the one who requested and paid this quote. serverSig is an Ed25519 signature; the public key is at GET /v4/quotes/pubkey.

  2. Pay it on Base. From your wallet, call approve(router, amount) on the USDC contract, then call payWithToken(recipient, token, amount) on the router, with the quote's quoteId appended to the calldata as 16 bytes (the UUID's 32 hex digits without dashes). The router sends the seller 97% and the 3% fee in that transaction. If router is null, transfer amount of token to recipient directly.

  3. Repeat the request with proof. Put the quote id, the transaction hash and the redeem token in X-PAYMENT, as JSON or base64-encoded JSON:

    Request
    PROOF=$(printf '%s' '{"quoteId":"4f9c2a1e-…","txHash":"0x…","redeemToken":"ccr_…"}' | base64 | tr -d '\n')
    curl https://api.v4.cryptocadet.app/v4/g/acme/market-brief -H "X-PAYMENT: $PROOF"
    

The gateway checks the payment on-chain before serving. It must have enough block confirmations, so a request sent right after the transaction may get 422 VERIFY_FAILED: wait a few seconds and send the same proof again. Redeem before the quote's expiresAt. One paid quote buys one access; sending the proof again after it has been redeemed returns PROOF_REDEEMED.

Response headers

HeaderMeaning
X-CryptoCadet-Accesspaid, unlock (first read of an unlock grant), granted_read (already unlocked), free_read, or own (the seller reading their own item, no charge)
X-CryptoCadet-ChargeThe charge id, when something was charged
X-CryptoCadet-ChargedThe amount charged, in micro-dollars
X-CryptoCadet-Railcredits or usdc

For a proxy item, the rest of the response (status, headers, body) is the seller's, except Set-Cookie, which is dropped.

Errors

Refused payments answer 402 with the full body above plus code and message. Other errors answer { "error": "<message>", "code": "<code>" }, where code may be absent.

StatusCodeMeaning
402INSUFFICIENT_CREDITSNot enough credits. Top up.
402AGENT_PER_CALL_CAPThe price is above the token's per-call cap.
402AGENT_DAILY_CAPThe token has reached its 24-hour cap.
402BAD_PROOFX-PAYMENT is malformed, the quote was not issued for this item, or the redeemToken is missing or wrong.
402PROOF_REDEEMEDThis payment has already been used.
402CREDITS_ONLYA USDC proof was sent for a private item. (Asking for a quote for one answers 400 with the same code.)
401Unknown or revoked agent token.
403The token may not buy from this seller, or the private item isn't shared with you.
404No such item, or it is disabled.
405Hosted items are read with GET.
409TX_ALREADY_USEDThat transaction already paid a different quote.
422VERIFY_FAILEDThe payment isn't verified yet, or doesn't match the quote. Retry shortly if you just paid.
422QUOTE_EXPIREDThe quote expired before it was redeemed.
502ORIGIN_ERRORThe seller's server failed. The body has refunded (true for a refunded credits charge) and chargeId.

Sellers: the headers your origin receives, and how to verify them, are in Selling.