> ## Documentation Index
> Fetch the complete documentation index at: https://docs.conduit.financial/llms.txt
> Use this file to discover all available pages before exploring further.

# Offramp and pay out

> Convert a customer's crypto into their USD virtual account and pay a bank recipient by SWIFT from it, with one orders call

An **offramp** converts crypto into fiat in the customer's virtual account. Add an `autoPayout` block, and Conduit then pays a bank recipient from that virtual account. You create both with one `POST /v2/orders` call, but they are two resources: the **order** (the conversion) and a chained **withdrawal** (the payout). Each has its own status and its own webhooks.

> [!NOTE]
>
> **Test this flow in sandbox.** See [OFFRAMP orders (sandbox)](https://docs.conduit.financial/sandbox/offramps.md) for the simulated path, the document-review step and failure controls.

## Prerequisites

* An `active` customer with a USD virtual account ([Add virtual accounts](https://docs.conduit.financial/guides/add-virtual-accounts.md)).
* The crypto to convert: in a wallet of the customer, or sent to a funding address that the order gives you. For the funding address, register the sending address first ([Deposit-funded orders](https://docs.conduit.financial/concepts/deposit-funded-orders.md#register-the-sending-address-first)).
* A supporting document for the payout's `purpose`, uploaded with [`POST /v2/documents`](https://docs.conduit.financial/api-reference/documents/upload-a-document) (purpose `transaction_support`). `intercompany` and `personal_transfer_of_funds` take a whitelisted recipient instead ([Payout requirements](https://docs.conduit.financial/guides/send-payout.md#payout-requirements)).
* Your API key.

## Step 1 — Create the order with a SWIFT autoPayout

This order is funded by a deposit: it names `sourceAsset` and no `source`. To convert from a wallet the customer already holds, send `source` instead ([Convert](https://docs.conduit.financial/guides/convert.md)).

```bash theme={null}
curl https://api.conduit.financial/v2/orders \
  -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "idempotency-key: $(uuidgen)" \
  -H "content-type: application/json" \
  -d '{
    "sourceAsset": { "code": "USDC", "chain": "ethereum" },
    "destination": { "type": "virtual_account", "id": "vac_..." },
    "lockSide": "source",
    "amount": "10000.000000",
    "autoPayout": {
      "rail": "swift",
      "purpose": "payment_for_goods_or_services",
      "documents": ["doc_..."],
      "swift": { "purposeOfPayment": "Invoice INV-2026-042" },
      "recipient": {
        "type": "business",
        "legalName": "Example Supplier GmbH",
        "countryOfRegistration": "DEU",
        "iban": "DE89370400440532013000",
        "bic": "COBADEFFXXX",
        "postalAddress": {
          "addressLine1": "1 Example Strasse",
          "city": "Frankfurt",
          "postalCode": "60311",
          "country": "DEU"
        }
      }
    }
  }'
```

* `autoPayout` takes the same `purpose`, `documents` and recipient fields as a fiat [`POST /v2/payouts`](https://docs.conduit.financial/api-reference/payouts/create-a-payout). On `swift`, send `iban` or `accountNumber`. `bankAddress` is optional: Conduit derives it from `bic`.
* Conduit checks the payout's requirements when it creates the order. A payout that would be refused is refused here, before any money moves.
* The response carries `depositInstructions`. Send the order's `totalDebit` to that address before `lockExpiresAt`. On a `source`-locked order, `totalDebit` equals `amount` ([How much an order debits](https://docs.conduit.financial/guides/money-movement-lifecycle.md#how-much-an-order-debits)).

## Step 2 — The order succeeds

When the funds clear, the order executes on its own. It converts the crypto and credits the customer's virtual account. Then `order.succeeded` fires.

`order.succeeded` means the virtual account is credited. It does not mean the recipient is paid. An account whose bank pays only on the order's instruction, such as a naira account, is the exception: there the order succeeds only when the bank has paid the recipient.

## Step 3 — Follow the chained withdrawal

After the credit, Conduit starts the payout as its own transaction, `type: "withdrawal"`, with `linkedOrderId` set to the order. Find it in either of these ways:

* [`GET /v2/transactions?linkedOrderId=ord_...&type=withdrawal`](https://docs.conduit.financial/api-reference/transactions/list-transactions).
* The `transaction.created` webhook with `type: "withdrawal"` and `linkedOrderId` set to the order.

`GET /v2/orders/{id}` also lists the ids of every transaction of the order in `linkedTransactionIds`, but not their types.

Conduit's payout fee comes out of the converted amount, so the recipient receives `destinationAsset.amount` less that fee, and less any margin you declared on the payout with `autoPayout.markupBps` or `autoPayout.markupAmount`. The withdrawal then moves like any payout ([Send a payout](https://docs.conduit.financial/guides/send-payout.md)):

| Event | What it means |
| - | - |
| `transaction.created` | The withdrawal exists. Its amount is reserved in the virtual account. |
| `transaction.under_review` | The withdrawal is held for review, for example of its supporting document. Read `hasRfi` to learn whether Conduit asks you for something. |
| `transaction.completed` | The bank accepted the payment. A SWIFT payment can take days. |
| `transaction.rejected` | A document review declined the withdrawal. It ends `failed` with `failureCode: compliance_rejected`. |
| `transaction.failed` | The withdrawal failed. Branch on `failureCode`, for example [`rail_policy_rejected`](https://docs.conduit.financial/errors/rail-policy-rejected), [`rail_unavailable`](https://docs.conduit.financial/errors/rail-unavailable), [`insufficient_funds_at_settle`](https://docs.conduit.financial/errors/insufficient-funds-at-settle), [`provider_rejected`](https://docs.conduit.financial/errors/provider-rejected), [`compliance_review_rejected`](https://docs.conduit.financial/errors/compliance-review-rejected) or [`compliance_hold`](https://docs.conduit.financial/errors/compliance-hold). A completed payment that the recipient's bank later sends back also moves to `failed`, with [`returned_by_sender`](https://docs.conduit.financial/errors/returned-by-sender). |

A failure of the withdrawal does not change the order: it stays `succeeded`, and `order.failed` does not fire.

## Recover from a failed payout

The withdrawal's `status` tells you where the money is and whether you may pay again:

| Withdrawal `status` | Where the money is | Pay again? |
| - | - | - |
| `pending` or `processing`, any `stage` | Reserved in the virtual account. The payout can still complete, including a payment the bank has not confirmed yet. | **No.** Wait for a terminal status. A second payout could pay the recipient twice. |
| `failed` or `cancelled`, other than the two rows below | Released to the virtual account's available balance. Nothing reached the recipient. | **Yes**, after you fix the cause. |
| `failed` with `compliance_hold` | Held by Conduit. It is not released to the virtual account. | **No.** Contact support. |
| `failed` with `returned_by_sender` | The recipient's bank sent a completed payment back. Conduit settles the return, which can carry a bank fee. | Contact support first, then pay again from what the virtual account holds. |
| `completed` | With the recipient. | No. |

To pay again, send a standalone [`POST /v2/payouts`](https://docs.conduit.financial/api-reference/payouts/create-a-payout) from the customer's virtual account, with a new `idempotency-key`. A new order is not needed: the converted money is already in the virtual account.

* **Held for review.** The withdrawal reads `stage: "under_review"` or, when Conduit asks you for a document, `stage: "awaiting_customer_action"` with `hasRfi: true`. Answer the request ([A payout that needs a document](https://docs.conduit.financial/guides/send-payout.md#a-payout-that-needs-a-document-and-attaches-none)). Do not pay again while it is held.
* **Document declined.** `transaction.rejected` names the `acceptedDocumentTypes`. Pay again with one of them.
* **No withdrawal after `order.succeeded`.** The payout did not start, and the converted amount stays in the virtual account. Contact support before you pay it out yourself.

## See also

* [Deposit-funded orders](https://docs.conduit.financial/concepts/deposit-funded-orders.md) — the funding address, its deadline and returns.
* [Send a payout](https://docs.conduit.financial/guides/send-payout.md) — payout stages, requirements and failure codes.
* [Onramp](https://docs.conduit.financial/guides/onramp.md) — the reverse direction.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.