outcome field). Customer-wallet crypto deposits on supported chains run on a real public testnet and are not simulated — you fund a wallet by sending real testnet crypto to its address from a faucet, and it is detected automatically (Use a real testnet). Stellar is supported; a Tron wallet cannot receive here — Tron is excluded from the default claim, and even a wallet you claim for it explicitly cannot transact (422 CHAIN_NOT_SUPPORTED on any quote, order or payout). Deposit-funded orders must also receive real testnet transfers at their published funding address. See Sandbox overview for the full posture.
This page covers three deposit types, one per fundable resource:
- Fiat deposits land on a customer’s virtual account via a simulate endpoint. The deposit is ingested asynchronously; no bank transfer occurs.
- Crypto deposits on supported chains land on a customer’s wallet from a real testnet faucet sent to the wallet’s address. The deposit goes through the same compliance screening and sender-information gate as any external deposit.
- Deposit-funded order transfers land on the funding address the order publishes. The transfer is an ordinary
deposittransaction you can read back. See Deposit-funded orders for the concept.
Prerequisites
- Your organization’s sandbox API key, and an
activecustomer. SetSANDBOX_API_KEY,CUSTOMER_ID,VA_ID(virtual account), andWALLET_IDin your shell. - For fiat: the virtual account must be
active. Deposit in the currency it holds —USDon the sandbox accounts you get by default. - For crypto: the wallet must be
activeand have a deposit address. - Base URL:
https://api.sandbox.conduit.financial.
The
idempotency-key header is required on the POST endpoints that the API
reference marks with it. A
successful response is kept for 30 days — replay the same key to safely retry;
use a fresh key for a new operation.Fiat deposit — happy path
Inject a synthetic deposit into a customer’s virtual account, in the currency that account holds.POST https://api.sandbox.conduit.financial/v2/sandbox/customers/{customerId}/virtual-accounts/{virtualAccountId}/deposits/simulate
Request body:
References reach the deposit’s
source only when the deposit is external_bank_inbound, which requires at least one senderInfo field to be set; without senderInfo the deposit is external_unknown, which carries no references in source. Replaying the same externalReference returns the first deposit, references included, whatever rail or omitWireReferences the replay sends.
202 Accepted means the deposit was accepted for processing. Processing is asynchronous — exactly as it is in production, where no endpoint creates a deposit synchronously — so the response body carries only externalReference: the sandbox_… reference the deposit is detected under. It is derived from your organization and the reference you sent, or from the deposit details when you omitted it. Send it back verbatim: the acknowledged reference — not your original string — is the one to filter on. Observe the deposit through the transaction.created webhook, or read it back with GET /v2/transactions?type=deposit&externalReference=…. Re-sending the same externalReference from your organization re-acknowledges the existing deposit rather than creating a duplicate. The customer’s USD balance updates within a few seconds, and your webhook endpoint receives transaction.completed.
Fiat deposit — compliance failure paths
Fiat deposits use the same suffix protocol as crypto deposits, matched against the last 8 digits of the sender’s bank account number (non-digit characters stripped). Pass asenderInfo.accountNumber ending in a documented suffix to force a specific compliance outcome.
The deposit-specific suffix values are listed in the Suffix catalog below. For the consolidated suffix table across deposits and withdrawals, see Scenario suffixes.
Crypto deposits
Send real testnet funds to the customer wallet address or to the funding address in a deposit-funded order’sdepositInstructions. The sandbox detects the transfer and credits it after chain finality and compliance checks. Use a supported chain and a testnet faucet. Crypto deposit simulation endpoints are unavailable. Watch transaction.created or query GET /v2/transactions?type=deposit&chain=<chain>&txHash=<transfer-hash>.
For a deposit-funded order, register the sending address first. Send the order’s totalDebit to the published funding address before lockExpiresAt. A transfer from an unregistered address is returned. See Deposit-funded orders.
Resolving a held funding transfer
When a transfer into a funding address is held for compliance review, resolve it on the order:POST https://api.sandbox.conduit.financial/v2/sandbox/orders/{orderId}/deposits/simulate/compliance-decision
reject holds the funds permanently, with no webhook for the loss — they are never returned to the sender and never fund the order. The transfer’s own transaction reads failed with no failureCode, and once lockExpiresAt has passed, the order cancels at the next sweep with order.cancelled. approve releases the hold and the funds go on to fund the order, which works even once lockExpiresAt has passed — the transfer arrived in time, so the order is still pending waiting on this decision; it is available only while the review is still open, and returns 409 once the review has already rejected the transfer — a rejected review can only be rejected. 202 Accepted returns the order as of the call. 404 SANDBOX_ORDER_NO_PARKED_FUNDING means nothing is currently held for review.
For a full walkthrough — register the sender, create the order, read the address, fund it, watch it auto-execute — see Offramps.
Sender information for a real crypto deposit
When a real transfer needs sender information, the deposit waits at the sender-information gate. Send the originator details toPOST /v2/transactions/{depositId}/sender-information while it is pending, with register: true to register the sending address so its later deposits skip the gate. The sandbox deadline is about 10 minutes after Conduit detects the deposit. Use the deadlineAt value from the webhook. After it, the deposit stays held. See Use a real testnet.
Suffix catalog
Suffixes are matched against the last 8 characters of the source identifier:- Crypto deposits: last 8 hex characters of
sourceAddress(case-insensitive on EVM; Base58 verbatim on Solana). A testnet faucet is the source of a faucet-funded deposit, so the faucet’s address — not a wallet you control — is what gets matched; a faucet deposit cannot be made to match a suffix. To force a scenario, send from a wallet you control whose address ends in the suffix, or use a reserved originator name (below). - Fiat deposits: last 8 digits of
senderInfo.accountNumber(non-digit characters stripped before matching).
Crypto deposit suffixes (matched on sourceAddress)
Reserved originator names
When you cannot control the source address — a faucet deposit, for example — submit sender information withentityType: "BUSINESS" and one of these names as originator.legalName (plus a country) to force the matching compliance scenario instead:
Fiat deposit suffixes (matched on senderInfo.accountNumber digits)
† On deposits, a non-CLEAR compliance classification (high-risk or sanctions match) holds the deposit rather than failing it outright: it stays
pending, uncredited, until the decision lands. Resolve it in sandbox with POST https://api.sandbox.conduit.financial/v2/sandbox/transactions/{depositId}/simulate/compliance-decision and { "outcome": "reject" }, which freezes it with the public failure code compliance_hold; approve is not available on an already-rejected review. If the deposit is the source funding event for the oldest pending autoExecute: true ONRAMP order it could cover, that order also fails with reasonCode: "provider_rejected".
Webhook events
transaction.failed payloads carry a failureCode when the cause is actionable. transaction.awaiting_sender_information includes daysRemaining and deadlineAt. The sandbox deadline is compressed to ~10 minutes, so the past-deadline path is fast to test: the deposit stays held.
Errors
See Errors for the full catalog. Deposit-relevant failure codes:VIRTUAL_ACCOUNT_ASSET_MISMATCH(422) — the fiat simulate body’sassetAmount.codeis not the currency the virtual account holds. Fetch the virtual account to read its currency, then resend with that code.compliance_hold— compliance screening returned a non-CLEAR decision (high-risk or sanctions match); the deposit is frozen and cannot be credited.returned_by_sender— the inbound transfer was returned by the originating institution before it could be credited. Sandbox triggers this branch via theoutcome: "returned"field on the deposit simulate endpoint.sender_info_timeout— legacy: Conduit no longer sets it on new deposits. An older deposit carries it when its sender-information deadline passed.
Diagrams
Crypto deposit state machine
Sender-information gate — timeline
Related pages
- Sandbox overview — full sandbox posture and what’s mocked
- Scenario suffixes — the consolidated compliance magic-suffix catalog for deposits and withdrawals
- Withdrawals — crypto withdrawal lifecycle and cosign flows
- Virtual Accounts — virtual account model and deposit instructions