---
title: "Buy minutes with stablecoin over HTTP 402 — no card, no checkout, no human"
method: POST
path: "/api/v1/billing/x402/topup/{amount}"
tags: ["billing"]
---

# Buy minutes with stablecoin over HTTP 402 — no card, no checkout, no human

`POST /api/v1/billing/x402/topup/{amount}`

## Request

- Base URL: `https://www.callagent.pro`
- URL: `https://www.callagent.pro/api/v1/billing/x402/topup/{amount}`
- Auth: HTTP bearer

Unlike /api/v1/billing/topup, this settles inside the request and the balance has already moved by the time you read the response.

Call it once with no payment header and it answers **402** with a `PAYMENT-REQUIRED` header describing what to pay. Sign an EIP-3009 `TransferWithAuthorization` for that amount with your wallet key, retry the identical request with the signature in `PAYMENT-SIGNATURE`, and the 200 below comes back with the credit applied. A `PAYMENT- RESPONSE` header carries the settlement details. Most x402 client libraries do this handshake for you.

The price comes from `{amount}`, which must be one of `accepts.denominations_eur` from GET /api/v1/billing/x402 — the body cannot influence what is charged. Per-payment and rolling daily ceilings are enforced before a challenge is ever issued.

`POST /api/v1/agents` accepts the same challenge, so an agent can pay for the phone agent it is creating in the same request.

## Path parameters

- `amount` string, required

## Response `200`

Paid, settled and credited. `paid` is what left the wallet (USDC); `credited` is what the balance gained (EUR). They are different currencies on purpose — reporting one of them is how an account becomes impossible to reconcile.

- object
  - `credited` string: EUR added to the balance
  - `credited_currency` string
  - `paid` string: Amount charged in the settlement asset
  - `paid_currency` string
  - `transaction` string: On-chain settlement reference; the credit is idempotent on this
  - `balance` number: EUR balance after crediting
  - `cost_per_minute` number
  - `minutes_added` integer, nullable

## Other responses

- `401`: Missing or invalid Bearer key
- `402`: Payment required, or a payment that did not settle. On the first (unsigned) call this is the normal challenge — read the `PAYMENT-REQUIRED` header and retry with a signature. A 402 with `error: payment_required` on a signed retry means nothing settled and nothing was credited.
- `429`: Too many requests — see the endpoint's rate limit tier (agent-api 120/min, agent-api-heavy 6/min, agent-api-secrets 10/min)
- `500`: Settled but not credited — `transaction` identifies the payment and the incident is logged for review. Do not retry: the credit is idempotent on the transaction and a retry pays twice.

---

[API](https://skmtc.dev/callagent/apis/callagent-pro-agent-api.md) · [All operations](https://skmtc.dev/callagent/apis/callagent-pro-agent-api/llms.txt) · [OpenAPI document](https://skmtc.dev/callagent/apis/callagent-pro-agent-api/revisions/38072cf8a24b?raw)
