Sandbox integration
The Sandbox is an isolated Environment where Deposits, Withdrawals, and Ledger run the exact same code as production — the only difference is that blockchain network confirmation is simulated, never real. No real Blockchain Transaction is ever created from a Sandbox, and no Sandbox data ever reaches Production.
Every simulation command requires the target Environment to be of type Sandbox — calling
these routes against a Production Environment returns 422 ENVIRONMENT_NOT_SANDBOX, with no
side effects. This is the central safety mechanism: it's not an error to avoid, it's the
protection that makes it safe to test your integration without any risk to real money.
Faucet — instant test balance
The fastest way to get test balance: observes, credits, and confirms in a single step.
POST /v1/environments/{environmentId}/sandbox/faucet
Important: the depositAddress you send must be exactly the address returned by an already
created Payment Intent for the Transaction you want to
fund — the Sandbox only simulates the network arrival; the module that actually credits the
Account's Available balance is Deposits, by resolving the Payment Intent for that address. An
arbitrary depositAddress (with no matching Payment Intent) makes the Sandbox respond 200
normally, but Deposits silently ignores the event (address from another context) — no balance
is credited. See Ledger and
Transaction/Settlement for the full flow (Transaction →
Payment Intent → Faucet/simulate-deposit).
Simulate a Deposit step by step
To test how your integration reacts to progressive confirmations (instead of the Faucet's instant credit), simulate each step separately:
POST .../sandbox/simulate-deposit— records the observed transaction.POST .../sandbox/simulate-confirmation— records a network confirmation (call as many times as you like, controlling the confirmation count).
Check the state at any time:
GET .../sandbox/observed-addresses/{id}.
Simulate a real Withdrawal's broadcast
A real withdrawals.request() call is Self-Custody end to end (see
Self-Custody): it builds a SigningRequest for you to sign, exactly
like Settlement. Once every leg is signed and submitted, the platform's all-signatures gate
broadcasts automatically — simulate that broadcast's confirmation the same way you would for a
Settlement leg:
POST .../sandbox/simulate-broadcast-confirmation,
using the broadcastAttemptId derived from that leg's own broadcastReference (poll
GET /v1/signing-requests/{signingRequestId} until it appears — see
self-custody-settlement.ts in the Mercatto example for
the exact, real code, reused identically for Withdrawal legs).
POST .../sandbox/simulate-withdrawal (and its own
GET .../sandbox/broadcast-attempts/{id}) is a separate, standalone simulation utility — it
creates its own SandboxBroadcastAttempt, disconnected from any real Withdrawal/ExecutionLeg.
Confirmed live: the real Self-Custody Withdrawal execution strategy never reads or writes it. Do
not build a real Withdrawal integration test around it.
Adjust the Treasury's observed balance (reconciliation)
To test reconciliation scenarios (TreasuryReconciliation), the Sandbox lets you directly adjust
the Treasury's observed balance for an Asset Network:
POST .../sandbox/treasury-balance
Why this is safe
Every simulation flows through the same real Workflow, Ledger, and Settlement — only the
source of the network confirmation event changes (simulated, not a real blockchain). Your
integration, tested in Sandbox, behaves exactly as it would in Production, with the same API, the
same events, and the same data model.