# RFQ trading on Revolut X

:::note[Regional availability]
RFQ trading is available to UK customers.
:::

Revolut X lets you trade large blocks of crypto that would otherwise cause significant price impact on the exchange order book.

## How it works

**Request for Quote (RFQ)** trading happens off the order book: the trade is agreed directly between you and a market maker, so it doesn't go through the normal trading channels — that's why RFQ trading has its own set of endpoints.

The flow has three steps:
1. [Request an RFQ quote](#1-request-a-quote) for a currency pair, side, and size.
2. Receive an executable price with a short-lived signed quote token.
3. [Accept the quote](#2-accept-the-quote) to place the order, at exactly the quoted price.

:::note
If you are rate-limited, use the `Retry-After` response header, which specifies the delay in milliseconds.
See [rate limits](#rate-limits) below.
:::

All three RFQ endpoints are part of the [Crypto Exchange REST API](/docs/api/revolut-x-crypto-exchange 'See the full RFQ API reference.') and use the same authentication: an API key with Ed25519 request signing.
See [Create an API key](/docs/guides/crypto-exchange/get-started/create-an-api-key) and [Authenticate requests](/docs/guides/crypto-exchange/get-started/authenticate-requests).

## Before you begin

Before you start, make sure you have:

- An **API key with RFQ permissions.** Create an API key in the [Revolut X web app](https://exchange.revolut.com/account/api-keys) with [`rest.otc.view`](/docs/api/revolut-x-crypto-exchange#request-rfq-quote 'Request RFQ quotes and view RFQ limits.') to request quotes and view limits, and [`rest.otc.trade`](/docs/api/revolut-x-crypto-exchange#accept-rfq-quote 'Accept RFQ quotes to place RFQ orders.') to accept quotes.
  Agentic clients can use the corresponding `agent.otc.view` and `agent.otc.trade` scopes.
- **Passed KYC (retail) or KYB (business) verification.**
- **High Net Worth categorisation (UK retail clients only).** UK retail clients must be categorised as High Net Worth investors to use RFQ trading.

:::note
Check the minimum trade size before quoting.
RFQ trades have a minimum in the pair's counter currency (e.g., USD for BTC/USD).
Use [Get RFQ limits](#3-check-rfq-limits) to retrieve the exact minimum for a pair.
:::

## 1. Request a quote

Request a quote by sending this request:

```http
POST https://revx.revolut.com/api/1.0/otc/quotes HTTP/1.1
X-Revx-API-Key: <API_KEY>
X-Revx-Timestamp: <TIMESTAMP>
X-Revx-Signature: <SIGNATURE>
Content-Type: application/json

{
  "symbol": "BTC/USD",
  "side": "buy",
  "qty": "2.5"
}
```

Set `side` to `buy` or `sell`, and provide **exactly one** of:
- `qty`: The quantity to trade, in the pair's **base** currency (BTC in `BTC/USD`).
- `amount`: The amount to spend or receive, in the pair's **counter** currency (USD in `BTC/USD`).

The response contains the executable price, the order book reference price, and the signed quote token:

```json
{
  "data": {
    "quote_id": "550e8400-e29b-41d4-a716-446655440000",
    "symbol": "BTC/USD",
    "side": "buy",
    "price": "79979.90",
    "qty": "2.5",
    "order_book_price": "80100",
    "expires_at": 1785313438816,
    "signature": "eyJxdW90ZV9lbnRyeV9pZCI6...",
    "liquidity_status": "filled"
  },
  "metadata": {
    "timestamp": 1785313433816
  }
}
```

The table below describes the fields of the `data` object.

| Field              | Description                                                                                                  |
|:-------------------|:-------------------------------------------------------------------------------------------------------------|
| `quote_id`         | The unique identifier of the quote.                                                                          |
| `symbol`           | The trading pair, in `BASE/COUNTER` format.                                                                  |
| `side`             | The trade direction: `buy` or `sell`.                                                                        |
| `price`            | The executable unit price, adjusted for fees.                                                                |
| `qty`              | The requested quantity in the base currency, included when the quote was requested by quantity.              |
| `amount`           | The requested amount in the counter currency, included when the quote was requested by amount.               |
| `order_book_price` | The Volume Weighted Average Price (VWAP) of the exchange order book for the requested size — your reference for the quote's quality.         |
| `expires_at`       | The quote's expiry as Unix epoch milliseconds.                                                               |
| `signature`        | The signed quote token. Pass it verbatim to accept the quote.                                                |
| `liquidity_status` | Whether the requested size was fully or partially covered by the order book: `filled` or `partially_filled`. |

All financial decimal values are returned as strings.
The response contains only the applicable `qty` or `amount`; fields with no value are omitted rather than returned as `null`.

:::warning[Quotes expire within 5 seconds]
Request a quote only when you are ready to trade, and accept it immediately.
If the token expires, request a new quote — expired tokens are rejected.
:::

## 2. Accept the quote

Accept the quote and place the order by sending this request:

```http
POST https://revx.revolut.com/api/1.0/otc/orders HTTP/1.1
X-Revx-API-Key: <API_KEY>
X-Revx-Timestamp: <TIMESTAMP>
X-Revx-Signature: <SIGNATURE>
Content-Type: application/json

{
  "signature": "eyJxdW90ZV9lbnRyeV9pZCI6..."
}
```

The quote's terms (pair, side, size, price) are bound to the signed token and cannot be modified.
The token is tied to your account.
Treat it as single-use: once the downstream order has been submitted, retrying it does not create a second order.
If acceptance fails before submission, request a new quote rather than relying on replay.

The response returns the placed RFQ order and its immediate execution status:

```json
{
  "data": {
    "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "filled"
  },
  "metadata": {
    "timestamp": 1785313433816
  }
}
```

The table below describes the fields of the `data` object:

| Field              | Description                                                                                                                    |
|:-------------------|:--------------------------------------------------------------------------------------------------------------------------------|
| `transaction_id`   | The unique identifier of the RFQ order returned by the flow. This is not necessarily the final ledger transaction ID. Settlement and finalisation can continue asynchronously. |
| `status`           | The immediate execution status of the RFQ order: `filled` or `rejected`. A `rejected` result comes with a `reason` and is terminal for that quote — request a new quote and retry. |
| `reason`           | Why the order was rejected. Present only when `status` is `rejected`, and omitted otherwise. |

A `rejected` response represents an immediate execution or fincrime decision.
Insufficient balance and other processing failures are returned as HTTP errors instead.

## 3. Check RFQ limits

Check the limits by sending this request:

```http
GET https://revx.revolut.com/api/1.0/otc/limits?symbol=BTC/USD HTTP/1.1
X-Revx-API-Key: <API_KEY>
X-Revx-Timestamp: <TIMESTAMP>
X-Revx-Signature: <SIGNATURE>
```

The response contains the minimum trade amount for the pair:

```json
{
  "data": {
    "min_amount": "100000",
    "symbol": "BTC/USD"
  },
  "metadata": {
    "timestamp": 1785313433816
  }
}
```

The table below describes the fields of the `data` object:

| Field        | Description                                                                                                 |
|:-------------|:-------------------------------------------------------------------------------------------------------------|
| `min_amount` | The minimum trade size in the pair's **counter** currency, returned as a decimal string. Quote requests below this minimum are rejected. |
| `symbol`     | The trading pair, in `BASE/COUNTER` format. |

## Rate limits

| Endpoint | Per-second limit |
|:---------|:-----------------:|
| [Request a quote](#1-request-a-quote) | 10 |
| [Accept a quote](#2-accept-the-quote) | 5 |
| [Check RFQ limits](#3-check-rfq-limits) | 10 |

If you are rate-limited, use the `Retry-After` response header, which specifies the delay in milliseconds.

## Errors

RFQ errors use the standard error response:

| HTTP | Description                                                                                    | Where |
|:-----|:-----------------------------------------------------------------------------------------------|:------|
| 403  | `User with id <REGISTERED_IDENTITY_ID> cannot accept quote with id <QUOTE_ID>`                 | [Accept a quote](/docs/api/revolut-x-crypto-exchange#accept-rfq-quote) |
| 422  | `Quote expired or does not exist`                                                              | [Accept a quote](/docs/api/revolut-x-crypto-exchange#accept-rfq-quote) |
| 400  | `Quote token is invalid or tampered`                                                           | [Accept a quote](/docs/api/revolut-x-crypto-exchange#accept-rfq-quote) |
| 403  | `Sell temporarily unavailable`                                                                 | [Request a quote](/docs/api/revolut-x-crypto-exchange#request-rfq-quote) |
| 422  | `The quote cannot be served at this time`                                                       | [Request a quote](/docs/api/revolut-x-crypto-exchange#request-rfq-quote) |
| 400  | `OTC quote amount is below minimum trade amount for BTC/USD: <MIN_AMOUNT>`                     | [Request a quote](/docs/api/revolut-x-crypto-exchange#request-rfq-quote) |

## What's next

For the full request and response schemas, rate limits, and error samples, see the [RFQ trading section of the Crypto Exchange REST API reference](/docs/api/revolut-x-crypto-exchange#tag-rfq-trading 'The RFQ endpoints in the API reference.').