order.succeeded fires within seconds of order creation — no manual settle calls are required for the happy path.
Both legs are Conduit-internal movements (there is no external actor delivering fiat or crypto on either side). Because there is no real external actor that can independently fail these legs, 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. - Your sandbox API key exported as
SANDBOX_API_KEY. - The customer’s virtual account ID exported as
VA_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.
Intermediate state is observable only via GET /v2/orders/:id (poll). Terminal status surfaces via webhook: order.succeeded or order.failed or order.cancelled.
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.
202 Accepted. Capture id as ORDER_ID. The mock provider auto-finalizes the source (fiat-in) and destination (crypto-out) legs internally. Webhook: order.succeeded (status: succeeded) fires within seconds — no manual settle calls are needed.
GET /v2/orders/$ORDER_ID to observe progress if needed. No webhook fires for intermediate leg state — only terminal outcomes emit a webhook.
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 reason you supplied), and failedAt. See /sandbox/conversions for more detail.
Source-deposit AML 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 freezes 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 within a few seconds. orders/:id/simulate/conversion-failed remains the lever for conversion-level failures after the order has begun executing.
Simulate rate-lock expiry
Backdates the order’s rate-lock timestamp so the next sweep cycle treats the lock as expired. The order transitions tocancelled with cancellationReason: "expired".
200 OK returning the order at its current state. Webhook: order.cancelled with cancellationReason: "expired". Cancellation lands within ~1 second via an immediate background sweep tick. No need to wait for the scheduled 30-second sweep.
This endpoint enqueues an immediate sweep tick so you can verify your integration handles rate-lock expiry without waiting for the live lock window to elapse.
Order status reference
| Status | Meaning | Possible next statuses |
|---|---|---|
pending | Order created; rate locked. Execution has not started. | succeeded, failed, cancelled |
succeeded | Source debited, conversion completed, destination credited. Terminal. | — |
failed | Execution failed on the source, conversion, or destination leg. Terminal. | — |
cancelled | Order cancelled before execution. cancellationReason is expired or client_cancelled. Terminal. | — |
Intermediate steps (source settled, conversion in progress) are not reflected as order statuses and do not emit webhooks. Poll
GET /v2/orders/{orderId} for current state; only the terminal outcomes (succeeded, failed, cancelled) surface via webhook.Webhook events
| Event | When it fires |
|---|---|
order.succeeded | Order reached succeeded: source debited, destination credited. Carries transactionId, sourceAssetAmount, destinationAssetAmount. |
order.failed | Order reached failed. reasonCode is INSUFFICIENT_FUNDS, PROVIDER_UNAVAILABLE, PROVIDER_REJECTED, INTERNAL_ERROR, or CANCELLED. |
order.cancelled | Order cancelled before execution. cancellationReason is expired or client_cancelled. |
Errors
Simulate endpoints return404 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) describing the failure category.
Sequence diagram
Related pages
- Sandbox quickstart — set up customer, virtual account, and wallet in under 5 minutes
- 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