---
title: "Pay with x402 and get an API key (agents)"
method: POST
path: "/agent/credits"
---

# Pay with x402 and get an API key (agents)

`POST /agent/credits`

## Request

- Base URL: `https://api.spacecontext.app/v1`
- URL: `https://api.spacecontext.app/v1/agent/credits`
- Auth: one of:
  - none
  - HTTP bearer

For an agent with a wallet and no account: pay in USDC on **Base** or **Solana** with [x402](https://x402.org) v2 and receive an API key. No key, no sign-in: the payment is the credential, and the paying address is the account. Any x402 v2 client works (for example `@x402/fetch` with `@x402/evm` and `@x402/svm`): the network fee is paid by the facilitator, the payer needs only USDC.

1. Call without `PAYMENT-SIGNATURE`: 402 `PAYMENT_REQUIRED` with the `PAYMENT-REQUIRED` header (base64 JSON, also in the body as `payment_required`). `accepts` has one entry per network, Base first: scheme `exact`, the network (CAIP-2), the amount in atomic USDC units (6 decimals: US$1.00 = `1000000`), the USDC contract or mint, the address to pay, and `extra` (the EIP-712 domain of USDC on Base; on Solana `feePayer`, the facilitator account that pays the network fee). `extensions.bazaar` describes the call for x402 catalogs.
2. Pick one entry, sign it, and send **the same request, with the same body**, adding `PAYMENT-SIGNATURE` (base64 JSON PaymentPayload with that entry, unchanged, as `accepted`). On Base the payload is an EIP-3009 `transferWithAuthorization`; on Solana a transaction partially signed by the payer: SetComputeUnitLimit, SetComputeUnitPrice, a `TransferChecked` of exactly the amount into the USDC account of `payTo`, optional memo, fee payer `extra.feePayer`. The payment is verified and settled by the facilitator; the answer carries `PAYMENT-RESPONSE` with the transaction.

On mainnet (Base `eip155:8453`, Solana `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`) the payment is credited to the account's wallet (`amount_cents`, then US$1.00 per live scan; reading, search and answers are included; agents have no free scan; the credit does not expire) and the key is **live**. On testnets (Base Sepolia `eip155:84532`, Solana devnet `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1`) USDC is free, so the payment credits nothing: the key is a **test** key (demo space, no charges, no model). The same paying address always gets the same account; a Base wallet and a Solana wallet are two accounts.

**Store `api_key` from your first purchase: it is shown once.** A signed authorization can be submitted by whoever holds it, so a payment alone returns a key only when it opens the account. Later payments from the same wallet top up the same account and return only `api_key_prefix`. An existing key is replaced only with that key: `rotate_key: true` plus `Authorization: Bearer <the current key>` (the previous key is revoked). The first key of the other mode (e.g. a live key for an account that so far paid on testnet) needs `Authorization: Bearer <one of the account's current keys>`. Both are checked before any payment is taken (403 `AGENT_KEY_REQUIRED`, nothing charged). A payment replayed with the same transaction is recognised: nothing is credited or minted twice.

400 `PAYMENT_INVALID` when the signature header is malformed or does not match the requirements (amount, network, asset, address, fee payer, the payer's signature), before anything is sent to the facilitator. 402 `PAYMENT_FAILED` when the facilitator rejects or cannot settle the payment (`reason`; nothing was charged). 503 `PAYMENTS_UNAVAILABLE` when the chosen network cannot be served right now (nothing was charged). 404 when agent payments are off on this deployment. Limited per IP.

## Headers

- `PAYMENT-SIGNATURE` string

## Request body

- AgentCreditRequest
  - `amount_cents` integer: US cents to pay (and, on mainnet, to credit): US$1.00 is one live scan. x402 clients cap a payment at US$1 by default; raise their limit to pay more at once
  - `rotate_key` boolean: Make a new key and revoke the current one. Needs `Authorization: Bearer <the current key>`

## Response `200`

Paid: the account, its credit (mainnet) and its key

- AgentCredit
  - `object` 'agent_credit', required
  - `network` 'eip155:8453' | 'eip155:84532' | 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp' | 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', required
  - `payer` string, required: Lowercase on Base; base58 as written on Solana
  - `transaction` string, required: The transaction hash (Base) or signature (Solana)
  - `livemode` boolean, required: true on mainnet: live credit and a live key
  - `amount_cents` integer, required
  - `balance_cents` integer, nullable, required: The wallet after this payment; null on testnet (nothing is credited)
  - `api_key` string: Only when the key was created by this call: store it, it is not shown again
  - `api_key_prefix` string, nullable, required: The account's key of this mode; null when it has none
  - `notice` string, required: What to do with the key (store it now, or use the one stored)
  - `docs` string, uri, required

## Other responses

- `400`: Invalid body, or `PAYMENT_INVALID`
- `402`: `PAYMENT_REQUIRED` (pay first) or `PAYMENT_FAILED` (rejected or not settled; nothing was charged)
- `403`: `AGENT_KEY_REQUIRED`: changing the keys of an existing account needs one of its current keys (nothing was charged)
- `404`: Error response
- `429`: Too many requests. Retry after the number of seconds in `Retry-After`.
- `500`: Settled but not recorded: reconciled by hand (`transaction`)
- `502`: The settlement could not be confirmed (`nonce` on Base, `signature` on Solana)
- `503`: Error response

---

[API](https://skmtc.dev/spacecontext/apis/space-context-api.md) · [All operations](https://skmtc.dev/spacecontext/apis/space-context-api/llms.txt) · [OpenAPI document](https://skmtc.dev/spacecontext/apis/space-context-api/revisions/1dca940259b4?raw)
