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

# Cards

> Virtual payment cards for AI agents:issuance, controls, and lifecycle.

## Overview

Cards are the core primitive. Each card is a virtual payment instrument backed by your USDC or pathUSD treasury balance. Agents use cards to pay for APIs, services, and resources.

## Card lifecycle

```mermaid theme={null}
stateDiagram-v2
    [*] --> ACTIVE: Funded from balance
    [*] --> PENDING_FUNDING: Pay-and-issue (tx_hash)
    PENDING_FUNDING --> ACTIVE: On-chain confirmed
    PENDING_FUNDING --> FUNDING_FAILED: Timeout (30min)
    ACTIVE --> FROZEN: cardsFreeze
    FROZEN --> ACTIVE: cardsUnfreeze
    ACTIVE --> USED: Single-use card spent
    ACTIVE --> EXPIRED: TTL elapsed
    ACTIVE --> CLOSED: cardsClose
    FROZEN --> CLOSED: cardsClose
    EXPIRED --> CLOSED: cardsClose
    USED --> CLOSED: cardsClose
```

`CLOSED` is a terminal, one-way state. A closed card stops working immediately and leaves the wallet view, but its records are never deleted: full history stays available through the account activity feed.

## Issue a card

<CodeGroup>
  ```typescript TypeScript theme={null}
  const card = await mag3nt.cards.cardsCreate({
    purpose: "Research Agent",
    limitAmount: 50,        // Max spend (USDC/pathUSD)
    network: "eip155:8453", // Base
    asset: "USDC",
    singleUse: false,       // Reusable
    expiresIn: 24,          // Hours (0 = never)
  });
  ```

  ```python Python theme={null}
  card = sdk.cards.cards_create(
      purpose="Research Agent",
      limit_amount=50,
      network="eip155:8453",
      asset="USDC",
      single_use=False,
      expires_in=24,
  )
  ```
</CodeGroup>

## Bulk issuance

Create up to 1,000 cards atomically:

```typescript theme={null}
const batch = await mag3nt.cards.cardsBulkCreate({
  cards: [
    { purpose: "Agent Alpha", limitAmount: 25 },
    { purpose: "Agent Beta", limitAmount: 25 },
    { purpose: "Agent Gamma", limitAmount: 50 },
  ],
  network: "eip155:8453",
  asset: "USDC",
});
// All-or-nothing: if total exceeds balance, none are created
```

## Spending controls

### MCC locks

Restrict which merchant categories a card can pay:

```typescript theme={null}
await mag3nt.cards.cardsUpdateControls(cardId, {
  mccLocks: "5411,5812", // Only grocery and restaurants
});
```

### Freeze / unfreeze

Instantly block all transactions on a compromised card:

```typescript theme={null}
await mag3nt.cards.cardsFreeze(cardId);
// Card is immediately blocked:no payments can process

await mag3nt.cards.cardsUnfreeze(cardId);
// Card is restored to ACTIVE
```

## Move funds back to treasury

Sweep a card's unspent balance back into your treasury, where it can be withdrawn off-platform. For `EXPIRED` cards this always performs a full sweep. For `ACTIVE` or `FROZEN` cards, omit the amount to sweep everything, or pass an amount for a partial claim (the card stays active with the remainder). Pending charges and mandate holds are excluded from the sweepable balance, so a claim can never strand an in-flight payment.

```typescript theme={null}
// Full sweep
await mag3nt.cards.cardsClaim(cardId);

// Partial claim: pull $5 back, leave the rest on the card
await mag3nt.cards.cardsClaim(cardId, { amount: 5 });
```

## Close a card

Retire a card you no longer need. Closing is a one-way action allowed only when the card is empty and has no open obligations:

* Remaining balance is zero (sweep with a claim first if needed)
* No in-flight pending transaction
* No open payment stream
* No active, unexpired AP2 mandate

```typescript theme={null}
await mag3nt.cards.cardsClose(cardId);
```

A closed card disappears from the wallet view. Its history is preserved and remains accessible from the account activity feed.

## Audit trail

Every transaction is recorded with full metadata. Read a single card's history, or the whole wallet's activity across every card (including closed ones):

```typescript theme={null}
// One card
const txns = await mag3nt.cards.cardsListTransactions(cardId);
for (const txn of txns.transactions) {
  console.log(`${txn.amount} USDC/pathUSD to ${txn.merchant} via ${txn.protocol}`);
}

// All cards, including closed: each row is tagged with card_purpose and card_status
const all = await mag3nt.transactions.list();
```

## Sandbox & testnet

mag3nt uses **network-based** environment isolation:no separate test API keys needed. Issue a card on a testnet network to activate sandbox mode:

<CodeGroup>
  ```typescript TypeScript theme={null}
  const testCard = await mag3nt.cards.cardsCreate({
    purpose: "Testing Agent",
    limitAmount: 100,
    network: "eip155:84532",  // Base Sepolia = sandbox
    asset: "USDC",
  });
  ```

  ```python Python theme={null}
  test_card = sdk.cards.cards_create(
      purpose="Testing Agent",
      limit_amount=100,
      network="eip155:84532",  # Base Sepolia = sandbox
      asset="USDC",
  )
  ```
</CodeGroup>

### How it works

\| `eip155:8453` (Base) | `production` | Real USDC |
\| `solana:mainnet` (Solana) | `production` | Real USDC |
\| `eip155:4217` (Tempo) | `production` | Real USDC or pathUSD |
\| `eip155:84532` (Base Sepolia) | `sandbox` | Test USDC:no real value |

Every payment response includes an `environment` field:

```json theme={null}
{
  "success": true,
  "environment": "sandbox"
}
```

<Note>
  Sandbox transactions deduct from your card balance just like production, but use test tokens with no real value. Use sandbox to validate your integration before going live.
</Note>

### Same API key, same endpoints

Your API key works for both environments. The card's network is the boundary:not the key, not the endpoint. A single account can have both mainnet and testnet cards simultaneously.
