Skip to main content
Effective from the Rain + Coinbase launch. AgentCard is migrating its issuing rail from a card-on-file model to Rain — stablecoin-collateralized Visa cards funded by a per-user non-custodial Coinbase CDP wallet holding USDC on Base. Until launch, cards continue to be funded by the cardholder’s saved payment method.
From launch, every user has a USDC wallet. USDC arriving in the wallet is automatically deposited on-chain into the user’s Rain collateral contract, and card spending power equals that deposited collateral — it updates within minutes of funds landing in the wallet. The wallet itself is a pass-through: in steady state its balance is ~0 because deposits sweep to Rain, where they back card authorizations. If you try to create a card while a deposit is still confirming, the API returns deposit_confirming with a retry hint (typically under a couple of minutes) — the money is on the way; don’t ask the user to pay again. A user can hold multiple wallets; exactly one is the primary — the wallet registered with Rain whose deposits back card issuance. Cards aren’t tied to a wallet, so switching the primary just re-registers the new address with Rain and new deposits flow through the new primary.

What changes at launch

One-time cutover:
  • All existing cards on the previous rail are cancelled. Uncaptured holds are released — no money is taken. Monthly card quotas reset, and affected users are emailed.
  • Every user must complete (re-)KYC via Rain’s consumer application before their first new card (this replaces the previous identity verification flow).
Deprecated at launch, removed ~30 days later:
  • Payment-method-on-file endpoints (/api/v1/cardholders/:id/payment-method/*) — see Attach a payment method
  • The approvals flow and 202 approval responses
  • Test mode (sk_test_* keys)
Unchanged — no integration changes needed:
  • The card object shape: id, last4, expiry (MM/YY), balanceCents, spendLimitCents, status
  • Get Card Details still returns the full PAN/CVV. Credentials are now fetched from the issuer on demand and never stored at rest — a security improvement.
  • Webhook event names (card.created, transaction.authorized, card.cancelled, …)
  • API key authentication for B2B
Stripe remains in use only for subscription/plan billing. Order-confirm flows no longer capture PaymentIntents for Rain cards — settlement is automatic on the card rail, and markup is invoiced via the organization’s billing subscription.

Funding the wallet

Two ways to add USDC:
  1. Fiat onramp (default) — Coinbase Onramp guest checkout via Apple Pay or Google Pay. US-only, with Coinbase guest limits: roughly 15 lifetime / 10 daily transactions per guest, 22–10,000 per transaction, and US non-VoIP phone verification (re-verified via OTP every 60 days).
  2. Direct USDC transfer — send USDC to the wallet’s address on Base.

Endpoints

These endpoints authenticate with the user’s JWT (the wallet belongs to the end user), and ship ahead of launch.

GET /wallet

Returns the caller’s primary wallet (as wallet) plus all wallets (wallets), each with a live USDC balance.
200
{
  "wallet": {
    "address": "0xAbC123...",
    "chain": "base",
    "stablecoin": "USDC",
    "balanceUsdc": "25.00",
    "collateralContract": "0xDeF456...",
    "status": "active"
  },
  "wallets": [
    {
      "id": "wal_abc123",
      "address": "0xAbC123...",
      "chain": "base",
      "stablecoin": "USDC",
      "balanceUsdc": "25.00",
      "collateralContract": "0xDeF456...",
      "status": "active",
      "isPrimary": true
    }
  ]
}
If the live balance read fails temporarily, the endpoint still returns 200 with "balanceUsdc": "0" and "balanceUnavailable": true. Returns 404 no_wallet when no wallet has been provisioned yet.

POST /wallet/provision

Idempotently provisions the caller’s primary CDP wallet. Returns the same { "wallet": { ... } } shape. Returns 503 wallet_provider_not_configured when wallet provisioning is not enabled on the environment.

POST /wallet/additional

Provisions an extra (non-primary) wallet. Additional wallets can receive USDC, but only the primary backs card issuance. Returns { "wallet": { ... } } in the per-wallet shape of the wallets list (with id and isPrimary: false).

POST /wallet/primary

Makes one of the caller’s wallets the primary and re-registers its address with Rain (the collateral contract follows the new primary).
Request
{ "wallet_id": "wal_abc123" }
Returns 200 { "wallet": { ... } } (the new primary). If Rain re-registration fails transiently the switch still happens locally and the response carries "rainRegistrationFailed": true. Returns 404 wallet_not_found for a wallet that doesn’t exist or isn’t yours.

POST /onramp/sessions

Creates a Coinbase Onramp guest-checkout order delivering USDC to the caller’s wallet.
Request
{
  "amount_cents": 5000,
  "payment_method": "apple_pay"
}
amount_cents must be between 200 and 1000000 (22–10,000); payment_method is apple_pay or google_pay.
200
{
  "session": {
    "id": "onr_abc123",
    "status": "pending",
    "fiatAmountCents": 5000,
    "paymentMethod": "apple_pay"
  },
  "payment": {
    "checkoutUrl": "https://pay.coinbase.com/..."
  }
}
Open checkoutUrl in a browser to pay. Errors: 404 no_wallet, 422 amount_out_of_range, 422 phone_verification_required, 422 guest_region_blocked (US-only; includes failure_code), 502 onramp_provider_error, 503 onramp_not_configured.

GET /onramp/sessions/:id

Poll a session to track delivery of funds.
200
{
  "session": {
    "id": "onr_abc123",
    "status": "completed",
    "fiatAmountCents": 5000,
    "fiatCurrency": "USD",
    "usdcAmount": "49.50",
    "feesCents": 50,
    "paymentMethod": "apple_pay",
    "failureCode": null,
    "completedAt": "2026-06-10T12:05:00.000Z",
    "createdAt": "2026-06-10T12:00:00.000Z"
  }
}

KYC (Rain consumer application)

Card issuance on the Rain rail requires an approved Rain consumer application. Until KYC is approved, card creation returns:
422
{
  "error": "kyc_required",
  "message": "This cardholder must complete identity verification (KYC) before creating a card."
}
The consumer identity flow (submit_user_info MCP tool / CLI prompts) gains two optional fields that feed the Rain application: occupation (SOC code or free text) and account_purpose. Integrations that don’t send them keep working.

Card creation errors

When the wallet can’t back a requested card, POST /api/v1/cards returns:
422 (wallet_funding_required)
{
  "error": "wallet_funding_required",
  "required_cents": 2500,
  "available_cents": 1000,
  "message": "The wallet needs $15.00 more USDC to create this card."
}
503 (wallet_balance_unavailable)
{
  "error": "wallet_balance_unavailable"
}
wallet_balance_unavailable means the wallet’s balance could not be read (temporary provider/RPC issue) — retry shortly. See Error Codes for the full list.

MCP tools and CLI

For agents connected via MCP, two tools cover the wallet:
  • get_wallet — wallet address, chain, and USDC balance (provisions the wallet on first use)
  • fund_wallet — creates an onramp session and returns the checkout URL
From the CLI: agent-cards wallet (show / provision) and agent-cards wallet fund --amount <dollars>.