txHash is verifiable on the network’s block explorer, it takes minutes to reach finality rather than seconds, and it can occasionally be delayed before it settles.
The fiat-in and crypto-delivery legs both originate inside Conduit (there is no external actor delivering fiat, and the customer does not send the crypto), so there is no mid-flow injection lever for them. Use orders/:id/simulate/conversion-failed (below) to drive the whole order to a failed terminal state, or create the pending auto-execute order first and then inject a source fiat deposit whose senderInfo.accountNumber carries a failure suffix — see Deposits and Sandbox overview.
Prerequisites
- An
activecustomer with at least one virtual account for the source fiat asset. Follow Sandbox quickstart if you haven’t set this up yet. - A claimed, active destination wallet for the crypto asset you want to receive.
- Your sandbox API key exported as
SANDBOX_API_KEY. - The customer’s virtual account ID exported as
VA_ID. - The destination wallet ID exported as
WALLET_ID.
Lifecycle overview
An ONRAMP order moves through these stages: the order is created and rate-locked → the source (fiat-in) and destination (crypto-out) conversion legs finalize automatically →order.succeeded fires. The conversion sub-leg is covered in detail on /sandbox/conversions.
Because both legs are internal movements in sandbox, there are no manual settle calls in the happy path. Use orders/:id/simulate/conversion-failed to force the order to a failed terminal state, or create the pending order and then simulate a source fiat deposit with a deposit suffix.
The order itself only sends a webhook at its terminal state: order.succeeded, order.failed, or order.cancelled. For progress before that, watch the order’s transaction instead — it carries linkedOrderId matching the order, and fires transaction.created when the conversion starts and transaction.completed when the crypto delivery reaches finality (transaction.failed or transaction.cancelled on the matching failure paths).
Full happy path
Step A — Create the order
Create the order by supplying the source virtual account (USD), the destination wallet (USDC), the lock side, and the amount. SetautoExecute: true to let the platform begin execution immediately. The example uses a small amount (1.00) so the crypto it delivers stays under the per-chain, per-UTC-day liquidity cap a new customer has — a larger amount is refused with 422 SANDBOX_ONRAMP_DAILY_CAP_EXCEEDED. See Errors for the cap and how to free headroom.
202 Accepted. Capture id as ORDER_ID. The fiat-in leg finalizes synthetically; the crypto delivery leg then settles — on a real testnet (minutes, real txHash, can be delayed; see the warning above). No manual settle calls are needed. order.succeeded (status: succeeded) fires once delivery reaches finality; see Lifecycle overview for the events that fire before then.
Send to a wallet outside Conduit
Thedestination can be a wallet your customer holds elsewhere. The customer needs no Conduit wallet and signs nothing: the converted crypto goes to recipient.address in one on-chain transfer.
recipientis the same crypto recipient as onPOST /v2/payouts. For a wallet that belongs to someone else, setattestation.custodytothird_partyand add their identity (typeplusfirstName,lastNameandcountryOfCitizenship, orlegalNameandcountryOfRegistration).recipient.chainmust equalasset.chain.purposeanddocumentsfollow the same rules as a payout. A purpose ofintercompanyorpersonal_transfer_of_fundsneeds the address registered first (Registered Addresses).- The order creates two transactions: the conversion, then a
withdrawalto the address, linked by the order id. The withdrawal is screened like any crypto payout and cannot be cancelled once it exists.
Simulate conversion failure
Force the in-flight conversion to fail regardless of which leg it is waiting on. The order terminates infailed; any funds already debited from the source are returned automatically.
200 OK returning the order at its current state. Webhook: order.failed carrying orderId, customerId, clientReferenceId, reasonCode, failureMessage (the standard text for that reasonCode, as in production), and failedAt. The reason you supply is kept as the note on the cancelled transfer, not on the order. See /sandbox/conversions for more detail.
Source-deposit compliance failure
For unfunded ONRAMP tests, create the order withautoExecute: true, then inject the fiat source deposit through the deposits simulator with senderInfo.accountNumber ending in 95009001 or 95009002. The deposit holds for a compliance decision and stays pending — it does not freeze on its own. Reject it with POST https://api.sandbox.conduit.financial/v2/sandbox/transactions/{depositId}/simulate/compliance-decision and { "outcome": "reject" } (see Deposits): the deposit then fails with transaction.failed and failureCode: "compliance_hold", and the oldest pending auto-execute order that matches the deposit and is amount-covered emits order.failed with reasonCode: "provider_rejected". orders/:id/simulate/conversion-failed remains the lever for conversion-level failures after the order has begun executing.
Simulate rate-lock expiry
Expires the order’s rate lock now. The order transitions tocancelled with cancellationReason: "expired".
200 OK returning the order at its current state. Webhook: order.cancelled with reason: "expired". Cancellation lands within seconds. There is no fixed delay: wait for order.cancelled.
Order status reference
Intermediate steps (source settled, conversion in progress) are not reflected as a separate order status. Watch the order’s transaction instead — it carries
linkedOrderId and fires transaction.created and transaction.completed (or transaction.failed / transaction.cancelled) as it progresses. Only the order’s own terminal outcomes (succeeded, failed, cancelled) surface a webhook on the order itself.Webhook events
Errors
Each customer has a cap on the net crypto they can draw from sandbox’s shared testnet liquidity, tracked per chain and per UTC day, which keeps that liquidity available across customers. An onramp (and the outbound leg of a cross-chain conversion) draws liquidity down; an offramp (and the inbound leg of a conversion) returns it and frees the customer’s headroom on that chain. An onramp or conversion that would carry the customer’s net draw for the day over the cap returns422 SANDBOX_ONRAMP_DAILY_CAP_EXCEEDED at order creation or execution. A new customer’s default is about $2 of net crypto per chain per day, so keep test amounts small; ask support to raise it. The cap resets at each UTC midnight: the previous day’s completed draws stop counting and headroom is full again on every chain, except for an onramp still in flight that keeps its reservation until it settles or fails. To free headroom sooner for a priced asset, return crypto with an offramp on the same chain. A testnet asset with no USD price is capped by a per-day transaction count instead; returning crypto does not lower that count, so wait for the next UTC day or ask support to raise it.
On live, Conduit refuses an onramp for a customer in the United States. Sandbox accepts it. See Customers in the United States.
Simulate endpoints return 404 ORDER_NOT_FOUND when the order does not exist or belongs to a different organization. Replays against an already-terminal order return 200 with the order at its current state (idempotent). If execution has not yet started, the simulator arms the failure for when it does. See /errors for the full error shape. The order.failed payload carries reasonCode (insufficient_funds / provider_unavailable / provider_rejected / internal_error / cancelled / insufficient_onchain_balance / source_account_unavailable) describing the failure category.
Sequence diagram
Related pages
- Sandbox quickstart — set up customer, virtual account, and wallet
- OFFRAMP orders — crypto-in → fiat-out counterpart
- Conversions — conversion sub-leg reference
- Sandbox overview — full sandbox posture and what is synthetic
- Webhooks reference — full payload schemas for all
order.*events - Errors — RFC 9457 error shape and
failureCodecatalog