Skip to main content
An AI agent does not sign up. It pays. Every API on the JoJ API marketplace answers keyless requests with a machine-readable HTTP 402 offer that an agent wallet can settle in one round trip — over x402 (USDC on Base) or the Machine Payments Protocol (MPP). The paying wallet becomes the agent’s identity: what it buys, it keeps.

Three ways to buy

Plan purchases, top-ups and per-request calls all work from the same wallet; the first payment creates the account.

Discover what is for sale

Every API host publishes its catalog and discovery documents (no auth): /openapi.json and /.well-known/x402 are reserved on every API host and always answered by the gateway itself, without authentication — also when the provider has not enabled agent payments (then without payment annotations). The {api} host is the gateway subdomain shown on the API’s page (for jojapi.com/hub/api/web-search the calls go to web-search.jojapi.net).

Pay per request

  1. Call the endpoint without a key: GET https://{api}.jojapi.net/v1/search?q=…
  2. The gateway answers 402 Payment Required with:
    • PAYMENT-REQUIRED — a base64 x402 v2 PaymentRequired object (accepts[] with the exact USDC amount, network, asset and payTo, plus the bazaar and payment-identifier extensions)
    • one or more WWW-Authenticate: Payment … MPP challenges (methods evm, and stripe / tempo where enabled)
    • a JSON body with reason: "payment_required", price_usd, and the catalog link
  3. Sign the payment with your wallet and repeat the request with PAYMENT-SIGNATURE: <base64 PaymentPayload> (x402) or Authorization: Payment <credential> (MPP).
  4. The gateway verifies the payment with the facilitator, forwards your request to the API, and settles only if the upstream answered 2xx-4xx. The response carries PAYMENT-RESPONSE (x402) or Payment-Receipt (MPP) with the on-chain transaction.
Upstream 5xx and gateway errors are never charged. If settlement fails after the upstream answered, the body is withheld and a fresh offer is returned (reason: "settlement_failed") — pay again to retry.
Identity in a paid call is the wallet that signed it. Per-wallet rate limits apply (default 5 requests/second, 300/minute per API); rate-limited requests are never charged.

Buy a plan and get an API key

Pay the offer (x402 or MPP) and repeat the POST with the credential. Include the payment-identifier extension (a client-generated id) — it makes the purchase idempotent: repeating the request with the same id returns the same result, key included, even if the first response was lost. The 200 response contains:
Use the key like any consumer: X-JoJAPI-Key: jk_… or Authorization: Bearer jk_…. The key is bound to that subscription. Buying a second plan of the same API creates a second subscription with its own key — nothing is cancelled; existing lists what you already hold. Pass {"replace": "<subscription ref>"} in the body to cancel one on purpose (no refund of the remaining period). Free plans need no payment but a wallet signature — see Sign-In-With-X below.

Renewal

Plans bought by agents are prepaid periods; nothing is charged automatically. When the period ends, requests with that key answer 402 with reason: "renewal_required" and an offer for the plan price. Pay it against POST https://{api}.jojapi.net/_jojapi/agent/renew (send the key too) and a new period starts from now, counters reset. Early renewal is refused with not_expired.

Fund a pay-as-you-go balance

The offer is for exactly amount_usd. On payment the balance is credited to the paying wallet’s account, a PAYG subscription is created on each API in subscribe (its first PAYG plan unless plan is given) and the response returns the key for each newly created subscription. Later top-ups from the same wallet land on the same account and return only key hints (…ab12), never the key again. The balance is account-wide: every PAYG key of the account spends it. When it runs out, requests answer 402 with reason: "insufficient_balance" and a top-up offer bound to that account — anyone may pay it, the credit goes to the account of the key, and the paying wallet is not linked to it.

Identity, wallets and Sign-In-With-X

  • One wallet = one account. The identity key is chain-agnostic on EVM (the same address on Base, Polygon or Arbitrum is one account); Solana addresses are separate identities.
  • Nothing is ever merged by guesswork. To use two wallets on one account, link them with a double signature: POST …/_jojapi/agent/identities/link signed by the existing wallet (SIGN-IN-WITH-X header) with the second wallet’s proof in the body ({"link": <siwx proof>}).
  • Identity-only routes use Sign-In-With-X (CAIP-122): request the route, receive 402 with extensions["sign-in-with-x"], sign the SIWE / SIWS message, repeat with SIGN-IN-WITH-X: <base64 proof>. Nonces are single-use, 5 minutes.
The same routes exist under https://agents.jojapi.com/apis/{api-slug}/…, and account routes without an API under https://agents.jojapi.com/.

Payment rails

Legacy x402 v1 (X-PAYMENT) is not supported.

Errors

Refunds

On-chain payments are final. You are never charged for upstream 5xx or gateway errors; you are charged for 4xx answers from the API (a wrong parameter is still a served request). Disputes are handled as balance credits on the agent’s account — contact the marketplace with the payment reference.