Sandbox
Help

RFQ trading on Revolut X

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 for a currency pair, side, and size.
  2. Receive an executable price with a short-lived signed quote token.
  3. Accept the quote to place the order, at exactly the quoted price.

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

All three RFQ endpoints are part of the Crypto Exchange REST API and use the same authentication: an API key with Ed25519 request signing. See Create an API key and 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 with rest.otc.view to request quotes and view limits, and rest.otc.trade 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.

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 to retrieve the exact minimum for a pair.

1. Request a quote

Request a quote by sending this request:

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:

{
  "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.

FieldDescription
quote_idThe unique identifier of the quote.
symbolThe trading pair, in BASE/COUNTER format.
sideThe trade direction: buy or sell.
priceThe executable unit price, adjusted for fees.
qtyThe requested quantity in the base currency, included when the quote was requested by quantity.
amountThe requested amount in the counter currency, included when the quote was requested by amount.
order_book_priceThe Volume Weighted Average Price (VWAP) of the exchange order book for the requested size — your reference for the quote's quality.
expires_atThe quote's expiry as Unix epoch milliseconds.
signatureThe signed quote token. Pass it verbatim to accept the quote.
liquidity_statusWhether 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.

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:

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:

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

The table below describes the fields of the data object:

FieldDescription
transaction_idThe 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.
statusThe 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.
reasonWhy 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:

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:

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

The table below describes the fields of the data object:

FieldDescription
min_amountThe minimum trade size in the pair's counter currency, returned as a decimal string. Quote requests below this minimum are rejected.
symbolThe trading pair, in BASE/COUNTER format.

Rate limits

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:

HTTPDescriptionWhere
403User with id <REGISTERED_IDENTITY_ID> cannot accept quote with id <QUOTE_ID>Accept a quote
422Quote expired or does not existAccept a quote
400Quote token is invalid or tamperedAccept a quote
403Sell temporarily unavailableRequest a quote
422The quote cannot be served at this timeRequest a quote
400OTC quote amount is below minimum trade amount for BTC/USD: <MIN_AMOUNT>Request a 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.

Rate this page