> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oneshotagent.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Top Up Credits

> Add prepaid credits by paying the same amount in USDC via x402

<img src="https://mintcdn.com/freebutter/jPFJoUgC4P5j3KGx/images/objects/credits.webp?fit=max&auto=format&n=jPFJoUgC4P5j3KGx&q=85&s=248d174542a9e35a0d0ace7791f4e294" alt="" className="docs-object" noZoom width="1200" height="600" data-path="images/objects/credits.webp" />

## Overview

Adds prepaid **credits** from the agent's own wallet. The requested `amount` **is the price**: you pay
`amount` USDC on-chain through x402, and `amount` is added to the credit balance.

[Access-token sessions](/sdk/remote-mcp) (Grok Bot, cloud runners, any client
without a wallet key) spend those credits. The top-up takes two calls:

1. Call with `{ amount }` and no payment. You get a **402** with a
   `payment_request` and a `PAYMENT-REQUIRED` header priced at exactly that amount.
2. Sign the USDC authorization and call again with the `payment-signature`
   header. The payment settles on-chain, the credit is recorded, and you get a
   **200**.

The SDKs do both steps:

```typescript theme={null}
const r = await agent.topUpCredits(25);
console.log(r.credits_balance); // "25.000000"
```

```python theme={null}
r = client.top_up_credits(25)
```

## Authentication

Wallet session only (`X-Agent-ID` + payment signature). An **access-token
session gets `503 route_unavailable_for_access_tokens`**, since credits can't buy
credits. Operators can grant credits directly with
`POST /v1/tools/internal/credits/grant` (or, for a wallet the API has never seen,
`POST /v1/tools/internal/agents/register` with the same grant fields).

## Request

<ParamField body="amount" type="number" required>
  USDC to add, from 0.01 to 1000. Also the amount paid.
</ParamField>

<ParamField body="memo" type="string">
  Note stored on the ledger row (max 1000 chars).
</ParamField>

## Response

<ResponseField name="data.topped_up" type="string">USDC credited, 6 decimals.</ResponseField>
<ResponseField name="data.credits_balance" type="string">Credit balance after the top-up.</ResponseField>
<ResponseField name="data.transaction_id" type="string">Ledger row id.</ResponseField>
<ResponseField name="data.settlement_tx" type="string">On-chain settlement transaction hash. Also the idempotency key: resubmitting a settled payment returns the same row with `already_credited: true`.</ResponseField>

## Errors

| Status | `error` | Meaning |
| - | - | - |
| 400 | `invalid_amount` | Not a number, or outside 0.01 to 1000 |
| 402 | `payment_required` | First call: pay the amount in the `PAYMENT-REQUIRED` header |
| 402 | `payment_verification_failed` | Payment did not verify or settle; nothing credited |
| 500 | `top_up_settled_not_credited` | Payment settled but the ledger write failed. Retry with the same payment (idempotent) or give the operator the `settlement_tx` |
| 503 | `route_unavailable_for_access_tokens` | Access-token session; use the wallet session |

Not available on staging, where credits come from operator grants.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.