Skip to main content
Everything on this page runs in test mode: one base URL (https://api.agentcard.sh), with test vs live decided by the credential you authenticate with, never by the host. Test-mode activity is simulated end to end — simulated money, instant identity outcomes, fake merchants — but it flows through the same settlement core, produces the same API shapes, and fires the same webhooks (with livemode: false) that live traffic does. If your integration handles everything this page can throw at it, it is ready for production traffic.
The dashboard drives all of this without code: Cards → Issue a test card walks the transaction lifecycle, Users simulates identity outcomes, and Earnings (test view) shows revenue accruing on simulated volume. This page is the API equivalent.

Test cards

Issue cards in test mode exactly as in live — POST /api/v1/cards — after the instant sandbox identity and payment-method steps from the quickstart. Test cards carry fake 4242… numbers, hold simulated balances, and follow the live contract for their type: the first approved authorization consumes a one-time-use card, while a type: "multi_use" card survives repeated charges until its balance is spent.

Attaching a card (BYOC)

The attach flow verifies a real consumer card through Basis Theory and the card network, so in test mode it reads Basis Theory’s BIN enrichment for whatever PAN you enter — the card must classify as eligible: a US-issued consumer Visa, or a consumer Mastercard from any country. Use Basis Theory’s US consumer Visa test card:
The ubiquitous 4242 4242 4242 4242 does not attach — Basis Theory enriches it as a commercial, non-US (Bermuda) card, so it’s correctly rejected (the program is consumer-only, and Visa must be US-issued). In sandbox, the ineligible verdict points you at the card above.
To exercise the ineligible branches (which fall back to the issued-card path — the agent routes to create_card): 4000 0566 5566 5556 (business → commercial_card) and 4900 0000 0000 0011 (unknown funding → funding_unknown). Full list: Basis Theory test cards.

Simulate transactions

Test merchants never charge a test card on their own — these helpers are the merchant. Each one drives the same settlement pipeline a real network event does, so the Payment rows, card state changes, and transaction.* webhooks are byte-for-byte what live produces.

The one-shot charge

POST /api/v1/cards/{id}/test_charge authorizes and settles in one call — the happy path:
Fires transaction.authorized then transaction.cleared, and closes a one-time-use card (a multi-use card stays open until its balance is spent).

The full lifecycle, step by step

Real transactions are not one-shot: they hold as PENDING, settle later (sometimes for less), get reversed, decline, and refund. Each state has its own helper so you can test the handling code paths individually. Authorize — a PENDING hold, the state your webhook consumer must treat as not-yet-final:
Returns the payment id used by the steps below; fires transaction.authorized. An approved authorization consumes a one-time-use card (declines never do). Decline — the branch most integrations forget to build:
Fires transaction.declined with your decline_reason. An authorization for more than the card’s balance auto-declines with insufficient_funds, the way live does — no need to force it. Capture — settle a PENDING authorization, fully or partially:
Fires transaction.cleared at the captured amount. Omit amountCents for a full capture; a partial capture settles for less than the hold, exactly like a merchant finalizing a smaller total. Reverse — void a PENDING authorization instead of settling it:
Fires transaction.voided. (A one-time-use card consumed by the authorization stays closed — live reversals do not resurrect cards either.) Refund — a merchant refund of a settled transaction:
Mirrors the live rail exactly: the refund is not a mutation of the original — it arrives as a separate transaction.cleared with a negative amount_cents (correlate by merchant). Partial refunds are allowed up to the settled amount; the original payment stays SETTLED.
Every helper responds with the events it fired, and each delivery is inspectable in the dashboard under Settings → Webhooks → your endpoint → Deliveries — payload, response code, and retries included.

Simulate identity outcomes

Test-mode verifications never complete on their own (there is no reviewer behind them). Force a verdict with POST /api/v2/kyc/simulateapproved, rejected, or requires_input — and the status plus the identity.verification.updated webhook land exactly like a real review. The full walkthrough, including the test-mode page end users see, is in Identity verification → Testing.

User wallet in test mode

For companies on the user-funded model, sandbox connect identities carry a simulated personal balance, so the whole loop — read the wallet, top it up, watch spending power rise, create cards — runs end to end with no real money and no on-chain account:
  • GET /api/v2/wallet returns the test wallet: livemode: false, address: null (nothing exists on-chain to deposit to), balance_usdc: "0" (the live transit semantics — deposits sweep out the moment they settle), and spending_power_usdc / collateral_usdc0.00 until the first top-up, then the running simulated balance.
  • POST /api/v2/wallet/fund requires the same verified phone as live — run the OTP loop with the sandbox code 111111 — and then settles itself: checkout_url is null because there is no payment step. The response is the normal funding_session shape with status: "pending", polling walks processingcompleted in about two seconds, and the amount is credited to the user’s spending power.
Funding a real connected user with a sandbox credential is a different, unchanged path: that creates provider TEST orders with a real checkout surface (see the funding guide).

Watch revenue accrue

Test-mode settled volume accrues the same earnings signal live volume does. The dashboard’s Earnings page (test view) has a one-click simulated transaction that shows your interchange share appearing in real time — the same math applied to your live volume.

Webhooks in test mode

Endpoints belong to one mode: an endpoint registered in the test view receives only livemode: false events. Register one endpoint per mode to run both, and use the dashboard’s send test event button to prove your handler before any traffic. Everything else — signatures, retries, the event catalog — is identical to live; see Webhooks.

Going live

Nothing on this page exists in live mode: the helpers return 403 sandbox_only on live credentials, and live verdicts come from real merchants and the identity provider. When the flows above all behave, follow Getting to production.