---
title: codespar_issue
description: Issue and control payment cards for AI agents or end-users. Virtual and physical cards, freeze, unfreeze and cancel, through the card-issuing partner (pan-LATAM issuing). Creates spend instruments; it does not move money.
---

import { Callout } from "fumadocs-ui/components/callout";
import { Tabs, Tab } from "fumadocs-ui/components/tabs";

<MetaToolHeader tool="codespar_issue" />

The agent-spend-card primitive (the Mesada use case). It creates spend instruments, distinct from [`codespar_pay`](/docs/concepts/meta-tools/pay) and [`codespar_charge`](/docs/concepts/meta-tools/charge), which move money.

## Actions

<MetaToolActions tool="codespar_issue" />

## Example

`action: "card-virtual"`, the default: a virtual card, active immediately.

<Split min={380}>
<SplitPane label="Call · tools/call">

```json title="arguments"
{
  "name": "codespar_issue",
  "arguments": {
    "action": "card-virtual",
    "cardholder_id": "cardholder_0000",
    "program_id": "program_0000"
  }
}
```

</SplitPane>
<SplitPane label="Result">

Result shape: see runtime. The tool document says `card-virtual` returns a card that is active immediately and `card-get` reads a card's status; it names no result field (the earlier page used `card_id` from the result to freeze it). The published document is [`/v1/meta-tools.json`](https://api.codespar.dev/v1/meta-tools.json).

</SplitPane>
</Split>

## When to use

- **An agent needs a card** to spend at merchants that take cards: `card-virtual`, bound to a cardholder and a card program at the issuer.
- **A physical card**: `card-physical` with a `shipping_address`.
- **Stop or resume spend**: `card-control` with `control: "freeze"`, `"unfreeze"` or `"cancel"`, and a `reason` stamped on the action.
- **Check state**: `card-get`.

## Arguments

| Field | Type | Required | Description |
|---|---|---|---|
| `action` | `string` | No | `card-virtual` (default) \| `card-physical` \| `card-control` \| `card-get` |
| `cardholder_id` | `string` | To issue | Cardholder id at the issuer |
| `program_id` | `string` | To issue | Card program / BIN (issuer affinity group) |
| `card_id` | `string` | For `card-control`, `card-get` | The card |
| `control` | `string` | For `card-control` | `freeze` \| `unfreeze` \| `cancel` |
| `reason` | `string` | No | Reason stamped on a control action |
| `shipping_address` | `object` | For `card-physical` | Where the physical card ships |
| `metadata` | `object` | No | Provider-specific overrides |

## Errors and what to do

| Error | Cause | What to do |
|---|---|---|
| `invalid_args` | `card-physical` without `shipping_address`, a control or get without `card_id`, an unknown `action`. Nothing is issued. | Fix the call against the Arguments table. |
| `400 issuer_corridor_unsupported` | No enabled issuer serves the (country, currency) corridor on this deployment. Issuing is off by default and enabled per corridor by an `ISSUER_*_ENABLED` flag, no matter what the mandate or key says. | An operator decision: enable the corridor and seed its credentials in the vault (the service refuses to boot with the flag on and the secret missing). On CodeSpar's hosted production the Pomelo corridor is enabled. |
| `403 live_issuer_test_key` / `403 stage_issuer_live_key` | The lane is environment-bound in both directions: a deployment that issues real cards refuses a test-mode key, and one that issues stage cards refuses a live-mode key. | Use the key that matches the deployment. |
| `409 mandate_already_bound` | One card per mandate: a second mint against a mandate that already backs a card. | Reuse the existing card, or sign a new mandate. |

## Money and mandate

No money moves on this tool. A card is a spend instrument: the money moves later, when the card is used, and that spend runs under the same mandate governance as the wallet (spending limits and policy are described under [Wallets](/docs/concepts/wallets)). One mandate backs at most one card.

## Related

- [`codespar_pay`](/docs/concepts/meta-tools/pay): move money (cards are an instrument, not a transfer)
- [`codespar_wallet`](/docs/concepts/meta-tools/wallet): the governed funds behind the card
- [Wallets](/docs/concepts/wallets): spending limits and policy on agent spend
- [Autonomous card payments](/docs/concepts/directed-pay): the mandate that authorizes card spend

## Notes

**Operator setup.** The card-issuing partner uses an API key (`api_key` auth_type). The operator connects the issuing account in `/dashboard/auth-configs`; the cardholder and the program / BIN are provisioned at the issuer and referenced by id.

**From the SDK.** `session.issue(args)` is the typed wrapper; `session.execute("codespar_issue", arguments)` takes the same arguments as the MCP call.
