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

# Issuing a card

> Fund the user's balance, then create single-use or multi-use cards for your agent.

An issued card is a virtual card Agentcard creates for the user, funded from their balance. It can never spend more than the balance behind it. Your agent creates cards through the Agentcard MCP server, connected with the user's connection token, so the user's cards and balance stay scoped to your connection.

## Connect your agent

One MCP client per user, pointed at `https://mcp.agentcard.sh/mcp` with the user's connection token as the bearer. Never share a client across users: the bearer decides whose cards the agent can see.

```typescript theme={null}
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("https://mcp.agentcard.sh/mcp"),
  { requestInit: { headers: { Authorization: `Bearer ${user.agentcardAccessToken}` } } },
);
const client = new Client({ name: "your-app", version: "1.0.0" });
await client.connect(transport);
const { tools } = await client.listTools();
```

Register whatever `listTools()` returns rather than a hardcoded list. Tools Agentcard ships later then appear without a deploy on your side. On `401`, refresh the connection with your org token and reconnect.

## Fund the balance

The balance is the user's cash. Users add it in USD with Apple Pay or Google Pay, and it is held as USDC.

From the agent, `add_funds` prepares a single-use checkout link and moves no money by itself. The user opens it and pays in their own browser:

```json theme={null}
{ "tool": "add_funds", "arguments": { "amount_cents": 5000 } }
```

The first time, funding needs a one-time phone verification. `add_funds` sends the code and says where it went. Ask the user for it, call `verify_phone`, then call `add_funds` again. The verification stays fresh for 60 days.

From your server, the same thing is `POST /api/v2/wallet/fund`, which returns a `checkout_url` to show in your UI, and `GET /api/v2/wallet/fund/{session_id}` to learn when the money landed. Agentcard covers the provider fee: send the exact amount the user should receive.

`get_balance` shows what is spendable. A deposit that shows as "confirming" is already on the way. Do not ask the user to pay again.

## Create a card

```json theme={null}
{ "tool": "create_card", "arguments": { "source": "issued", "amount_cents": 2500 } }
```

<ParamField body="source" type="string" required>
  `issued`. Draw on the user's balance. Without it, `create_card` may set up the user's own card in the Vault instead.
</ParamField>

<ParamField body="amount_cents" type="number" required>
  What the card can spend, in cents. Minimum 100. Connections through your organization have no maximum.
</ParamField>

<ParamField body="type" type="string">
  `single_use` (default) closes after the first approved charge. `multi_use` stays open until its limit is spent, for subscriptions or merchants that charge repeatedly. Optional `expires_at` auto-closes it.
</ParamField>

<ParamField body="scope_preset" type="string">
  `ai_labs` locks the card to AI-lab merchants (OpenAI, Anthropic, Gemini). Anything else declines at authorization.
</ParamField>

Sandbox returns a test card immediately. In production, `create_card` may return one of these first:

| Response                  | Meaning                                   | What to do                                                           |
| ------------------------- | ----------------------------------------- | -------------------------------------------------------------------- |
| `kyc_required`            | The user has not verified their identity. | [Complete KYC](/issuing/completing-a-kyc), then retry.               |
| `wallet_funding_required` | The balance is short.                     | `add_funds`, then retry.                                             |
| `deposit_confirming`      | Money is on the way.                      | Wait the suggested interval, then retry. Do not fund again.          |
| `user_info_required`      | Consent or phone missing.                 | Consent is recorded server-side with `POST /api/v2/connect/consent`. |

Every card arrives as a `card.created` webhook.

## Or let the user do it in the wallet

If you would rather not drive the flow from your agent, text or embed a [wallet link](/api-reference/wallet-links/overview). The hosted wallet runs KYC, funding and card creation itself, and you learn about each step through the same webhooks.

## Rules for your agent

```text theme={null}
- Confirm with the user before creating a card. Cards are live and charged for real when used.
- Create the card right before the purchase, sized to it. Don't stockpile cards.
- Use multi_use only for merchants that charge repeatedly.
- If create_card returns deposit_confirming, wait and retry. Never ask the user to pay twice.
- A connection authorized through your SANDBOX credentials issues test cards that no real merchant accepts.
```
