> ## 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.

# Quote a conversion or payout

> Price a conversion, payout, or withdrawal before you commit to an order, then redeem the quote at its locked rate

A **quote** prices a move before you create it. Send an asset pair and an amount to [`POST /v2/quotes`](/api-reference/quotes/price-a-conversion-payout-or-withdrawal) and you get back one or more priced options — no resource ids, no recipient, and no margin of your own. It answers "what would this cost" so you can show a customer a price before they commit.

A quote carries no margin of your own — Conduit's rate and fees only. Apply your own margin when you create the order, not on the quote: see [Redeem the option](#redeem-the-option) for which margin field a redemption accepts.

<Note>
  **Test this flow in sandbox.** Drive a conversion end-to-end with simulated
  money first — start with the [sandbox quickstart](/sandbox/quickstart), then
  [conversion simulation](/sandbox/conversions) — then apply the same request
  shape to a quote.
</Note>

## Prerequisites

* Your API key.
* A source and destination asset pair enabled for your organization. An unpriceable pair returns `422 UNSUPPORTED_PAIR`.

## Step 1 — Price it

Send `source`, `destination`, `lockSide`, and `amount`. Two more things decide what you get back: whether `source` and `destination` name the **same asset**, and whether you include `destinationCountry` — the payout recipient's domicile. There's no separate mode field — these two signals discriminate three modes.

### Conversion only

Different assets, no `destinationCountry`. One option, with `rail: null` — there's no payout leg to route.

```bash theme={null}
curl https://api.conduit.financial/v2/quotes \
  -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "source": { "code": "USDC", "chain": "ethereum" },
    "destination": { "code": "USD" },
    "lockSide": "source",
    "amount": "10000"
  }'
```

```json theme={null}
{
  "id": "qte_iK2ZWeqhFWCEPyYngFb51y",
  "sourceAsset": { "code": "USDC", "chain": "ethereum" },
  "destinationAsset": { "code": "USD" },
  "lockSide": "source",
  "amount": "10000",
  "options": [
    {
      "id": "qop_BMWXaSCrUZoL8g5ubbbPIa",
      "rail": null,
      "rate": {
        "referenceRate": "1",
        "totalSpreadBps": "20",
        "endUserRate": "0.998"
      },
      "fees": [
        {
          "charge": "conversion",
          "type": "fixed",
          "assetAmount": { "code": "USDC", "chain": "ethereum", "amount": "5" }
        }
      ],
      "sourceAmount": { "code": "USDC", "chain": "ethereum", "amount": "9995" },
      "destinationAmount": { "code": "USD", "amount": "9975.01" },
      "recipientAmount": { "code": "USD", "amount": "9975.01" },
      "totalDebit": { "code": "USDC", "chain": "ethereum", "amount": "10000" }
    }
  ],
  "expiresAt": "2026-08-19T12:01:00.000Z",
  "createdAt": "2026-08-19T12:00:00.000Z"
}
```

### Conversion and payout

Different assets **plus** a `destinationCountry`. One option per rail actually available: the domestic US rails (`fedwire`, `rtp`, `fednow`) are evaluated for a USA recipient regardless of what country you send, so they appear whenever the corridor otherwise supports them; `swift` is the one rail actually routed to the `destinationCountry` you send.

```bash theme={null}
curl https://api.conduit.financial/v2/quotes \
  -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "source": { "code": "USDC", "chain": "ethereum" },
    "destination": { "code": "USD" },
    "lockSide": "source",
    "amount": "10000",
    "destinationCountry": "US"
  }'
```

```json theme={null}
{
  "id": "qte_84yRnBUbHoWC8FJowoRoWD",
  "sourceAsset": { "code": "USDC", "chain": "ethereum" },
  "destinationAsset": { "code": "USD" },
  "lockSide": "source",
  "amount": "10000",
  "options": [
    {
      "id": "qop_8s7bA16J7PglOU3shVv5UT",
      "rail": "rtp",
      "rate": {
        "referenceRate": "1",
        "totalSpreadBps": "25",
        "endUserRate": "0.9975"
      },
      "fees": [
        {
          "charge": "conversion",
          "type": "fixed",
          "assetAmount": { "code": "USDC", "chain": "ethereum", "amount": "5" }
        },
        {
          "charge": "payout",
          "type": "fixed",
          "assetAmount": { "code": "USD", "amount": "1" }
        }
      ],
      "sourceAmount": { "code": "USDC", "chain": "ethereum", "amount": "9995" },
      "destinationAmount": { "code": "USD", "amount": "9970.01" },
      "recipientAmount": { "code": "USD", "amount": "9969.01" },
      "totalDebit": { "code": "USDC", "chain": "ethereum", "amount": "10000" }
    }
  ],
  "expiresAt": "2026-08-19T12:01:00.000Z",
  "createdAt": "2026-08-19T12:00:00.000Z"
}
```

A rail eligible for the route but not for a payout to that corridor (or the reverse) is left out — it's never defaulted in. A corridor with no eligible rail at all still returns `201` with `options: []`, not an error.

### Withdrawal only

The **same** asset on both sides, plus a `destinationCountry`. One option per available rail, and `rate: null` on each — there's no FX leg to price, only a rail fee:

```bash theme={null}
curl https://api.conduit.financial/v2/quotes \
  -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "source": { "code": "USD" },
    "destination": { "code": "USD" },
    "lockSide": "source",
    "amount": "10000",
    "destinationCountry": "US"
  }'
```

```json theme={null}
{
  "id": "qte_u8jzPde0IgxLd6GncfBAep",
  "sourceAsset": { "code": "USD" },
  "destinationAsset": { "code": "USD" },
  "lockSide": "source",
  "amount": "10000",
  "options": [
    {
      "id": "qop_fJBd0Kh8oOOL8dKLzdocJ2",
      "rail": "fedwire",
      "rate": null,
      "fees": [
        {
          "charge": "payout",
          "type": "fixed",
          "assetAmount": { "code": "USD", "amount": "1" }
        }
      ],
      "sourceAmount": { "code": "USD", "amount": "10000" },
      "destinationAmount": { "code": "USD", "amount": "9999" },
      "recipientAmount": { "code": "USD", "amount": "9999" },
      "totalDebit": { "code": "USD", "amount": "10000" }
    },
    {
      "id": "qop_isAjIhKtJ0RlgLKOmxgJTe",
      "rail": "rtp",
      "rate": null,
      "fees": [
        {
          "charge": "payout",
          "type": "fixed",
          "assetAmount": { "code": "USD", "amount": "0.50" }
        }
      ],
      "sourceAmount": { "code": "USD", "amount": "10000" },
      "destinationAmount": { "code": "USD", "amount": "9999.50" },
      "recipientAmount": { "code": "USD", "amount": "9999.50" },
      "totalDebit": { "code": "USD", "amount": "10000" }
    }
  ],
  "expiresAt": "2026-08-19T12:01:00.000Z",
  "createdAt": "2026-08-19T12:00:00.000Z"
}
```

The same asset with **no** `destinationCountry` returns `400 VALIDATION_ERROR` — there's nothing to price.

## Step 2 — Read an option

Each entry in `options[]` prices one path. A conversion-only or payout-mode option is redeemable in Step 3; a withdrawal-mode option (`rate: null`) is preview-only — it prices a rail's fee for a standalone [payout](/guides/send-payout), and redeeming it as an order returns `422 INVALID_ORDER_COMBO`.

| Field               | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rate`              | `null` on a withdrawal option — no FX leg to price. Otherwise carries `endUserRate`, the rate your customer actually gets, spread already applied.                                                                                                                                                                                                                                                                                  |
| `fees[].charge`     | `conversion` (the FX leg's fee, in the source asset) or `payout` (the rail's withdrawal fee, in the destination asset). A conversion-only or withdrawal-only option carries only one kind.                                                                                                                                                                                                                                          |
| `sourceAmount`      | What leaves the source, excluding the source-asset fee.                                                                                                                                                                                                                                                                                                                                                                             |
| `destinationAmount` | On a conversion-only or payout-mode option, the conversion's gross output — before any `payout`-charge fee. On a withdrawal-mode option, already net of the rail fee — there's no separate conversion leg to be gross of.                                                                                                                                                                                                           |
| `recipientAmount`   | What the quote priced the recipient to receive. Equal to `destinationAmount` on a conversion-only or withdrawal-mode option; on a payout-mode option, the `payout`-charge fee is carved out of `destinationAmount` first. A conversion-only option redeemed with its own crypto `autoPayout` still carves a withdrawal fee out at dispatch that the quote never saw, so `recipientAmount` isn't the last word for that combination. |
| `totalDebit`        | What the customer pays on the source side — principal plus source-asset fees.                                                                                                                                                                                                                                                                                                                                                       |

<h2 id="redeem-the-option">
  Step 3 — Redeem the option
</h2>

Create the order with `quoteOptionId` instead of `amount` / `lockSide` — the order inherits both from the option, so sending either alongside `quoteOptionId` returns `400 VALIDATION_ERROR`. A redemption also always names an explicit `source` (wallet or virtual account); `sourceAsset` (deposit funding) is refused alongside `quoteOptionId`, since there's no funding window to check against the option's locked rate. `markupBps` isn't available on a redemption — it's refused alongside `quoteOptionId`, since redemption never recomputes the option's locked rate to fold a percentage into. For a percentage margin, create the order directly with `amount` / `lockSide` instead. `markupAmount` is available, but behaves differently here than on a fresh order: the option's `sourceAmount` and `destinationAmount` are already locked and never recomputed, so `markupAmount` always adds to `totalDebit` — on both lock sides — rather than reducing the principal the way it would on a source-locked order created directly.

A payout-mode option needs `autoPayout` naming the recipient (quotes carry no recipient), and it's subject to the same [documentation and whitelist policy](/guides/send-payout#payout-requirements) as a standalone payout — most purposes need at least one `documents` id:

```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 '{
    "source": { "type": "wallet", "id": "wlt_<source-wallet>", "asset": { "code": "USDC", "chain": "ethereum" } },
    "destination": { "type": "virtual_account", "id": "vac_<destination-va>" },
    "quoteOptionId": "qop_8s7bA16J7PglOU3shVv5UT",
    "autoPayout": {
      "rail": "rtp",
      "purpose": "payment_for_goods_or_services",
      "documents": ["doc_XmI63JozGw82KwD6rQJM9U"],
      "recipient": {
        "rail": "us",
        "type": "individual",
        "firstName": "Jane",
        "lastName": "Doe",
        "accountNumber": "123456789",
        "routingNumber": "021000021",
        "accountType": "checking",
        "postalAddress": { "addressLine1": "1 Market St", "city": "San Francisco", "state": "CA", "postalCode": "94105", "country": "USA" },
        "bankAddress": { "addressLine1": "100 Wall St", "city": "New York", "country": "USA" }
      }
    }
  }'
```

The order executes at the option's **locked** rate and fees — nothing is re-priced. Keep in mind:

* **The option is single-use and short-lived.** `expiresAt` is about a minute out.
* **A payout-mode option's `autoPayout` must match what the option priced.** Its `rail` must equal the option's own, and — for a fiat payout — its `recipient.postalAddress.country` must equal the `destinationCountry` you quoted.
* **A withdrawal-mode option (`rate: null`) can't be redeemed as an order** — it only informs a standalone [payout](/guides/send-payout).
* **Recipient-type pricing is rare, but possible.** If a pricing rule scoped to this payout's recipient type would have priced the option differently, redemption is refused rather than collecting the wrong amount. Create the order directly with `amount` / `lockSide` instead — pricing will resolve against the real recipient.

| Code                                                                     | Cause                                                                                                                                                                                                          |
| ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`QUOTE_NOT_FOUND`](/errors#quote-not-found)                             | The `quoteOptionId` is unknown, or belongs to a different organization.                                                                                                                                        |
| [`QUOTE_EXPIRED`](/errors#quote-expired)                                 | Redeemed after `expiresAt`. Request a fresh quote.                                                                                                                                                             |
| [`QUOTE_ALREADY_USED`](/errors#quote-already-used)                       | Another order already redeemed this option. Request a fresh quote.                                                                                                                                             |
| [`QUOTE_ASSET_MISMATCH`](/errors#quote-asset-mismatch)                   | The order's resolved source/destination assets don't match what the option priced.                                                                                                                             |
| [`QUOTE_RECIPIENT_TYPE_UNPRICED`](/errors#quote-recipient-type-unpriced) | A recipient-type-scoped pricing rule would have priced this option differently.                                                                                                                                |
| `VALIDATION_ERROR`                                                       | `amount`, `lockSide`, `sourceAsset`, or `markupBps` was sent alongside `quoteOptionId`; a payout-mode redemption omitted `autoPayout`; or its `rail` or recipient country didn't match what the option priced. |
| `INVALID_ORDER_COMBO`                                                    | The option is withdrawal-mode (`rate: null`) — it can't be redeemed as an order.                                                                                                                               |

## End-to-end

1. `POST /v2/quotes` — get back `options[]`.
2. Show the customer a price from the option you want (its `endUserRate`, `recipientAmount`, `totalDebit`).
3. `POST /v2/orders` with that option's `quoteOptionId` (plus `autoPayout` for a payout-mode option).
4. The order is created already priced at the quote's locked rate — proceed exactly as you would for any other order: `POST /v2/orders/{orderId}/execute`, or `autoExecute: true` on create. See [Convert crypto](/guides/convert) and [Send a payout](/guides/send-payout) for what happens next.

## See also

* [Convert crypto](/guides/convert) — creating a conversion order directly, without a quote.
* [Send a payout](/guides/send-payout) — the standalone payout endpoint a withdrawal-mode option informs, and the documentation/whitelist policy an `autoPayout` redemption shares.
* [Errors](/errors) — the full `QUOTE_*` error reference.
