---
title: Requesting Quotes
description: Create a request for quote, watch the quotes it attracts, and accept one, over REST or WebSocket.
---

An RFQ asks makers to price a trade directly. For what an RFQ is, who sees what, and how last look decides the outcome, see [RFQs](/concepts/rfqs). This walkthrough shows the taker's operations; the maker's side is [Creating Quotes](/walkthroughs/creating-quotes). It assumes the environment and API key from the [Quick Start](/quick-start).

Every RFQ and quote write is [asynchronous](/reference/asynchronous-writes): the response confirms the exchange accepted the submission, and the outcome is read afterward. Over WebSocket you can create RFQs, stream both your RFQs and the quotes answering them, and accept a quote.



## Create an RFQ

**REST**

[Create the RFQ](/api-reference/rest/rfqs/create-rfq) with your `client_rfq_id`, the market by `ticker` or an ad-hoc `legs` list, a size in `quantity` or `cash_quantity`, and the `side` you intend to execute:

```json
{
  "client_rfq_id": "my-rfq-1",
  "ticker": "UDX-EXAMPLE-MARKET-A",
  "side": "buy",
  "quantity": "100"
}
```

The `202 Accepted` response echoes your `client_rfq_id`. The exchange assigns `rfq_id` once the RFQ lands, so [list your account’s RFQs](/api-reference/rest/rfqs/list-account-rfqs) with your `account_id`, filtered by `client_rfq_id` and `status=open` until it appears with status `open`, and keep its `rfq_id`.

**WebSocket**

Subscribe to the `rfqs` channel first, as described under [Follow the RFQ](#follow-the-rfq), so the RFQ's own frames confirm it. Then send `create_rfq`. An `rfq_create_submitted` frame echoing your `client_rfq_id` acknowledges the accepted submission, and the `rfq_opened` frame on your subscription confirms the committed RFQ, correlated by the same `client_rfq_id`. A rejected request returns a `type: "error"` frame and leaves the connection open.

```json
{
  "id": 5,
  "cmd": "create_rfq",
  "params": {
    "client_rfq_id": "my-rfq-1",
    "ticker": "UDX-EXAMPLE-MARKET-A",
    "side": "buy",
    "quantity": "100"
  }
}
```

Name one market by `ticker` or a `legs` array, and size by `quantity` or `cash_quantity`, exactly one of each. An `idempotency_key` is accepted but not yet used for deduplication, so a retry that reuses it can create a second RFQ. See [Create an RFQ](/api-reference/websocket/rfqs/receive-create-rfq-command) for the full parameter contract.

## Follow the RFQ

**REST**

[List your RFQs](/api-reference/rest/rfqs/list-rfqs) for the RFQ's status, and [list the RFQ's quotes](/api-reference/rest/quotes/list-rfq-quotes) by `rfq_id` to watch the quotes it attracts. Reading these responses requires access to the account that created the RFQ. Each quote names its maker only by the opaque `quoter_id`, carries a `side`, `price`, and `quantity`, and is live while its status is `open`. Quotes stop arriving at the RFQ's `expires_at`.

**WebSocket**

Open the `rfqs` channel with the shared `subscribe` command:

- Omit `tickers` to create one subscription covering every RFQ visible to you, including new arrivals.
- Supply a `tickers` list to create one independent subscription per ticker. An RFQ matches a ticker subscription if any leg has that ticker.

```json
{
  "id": 6,
  "cmd": "subscribe",
  "params": {
    "channels": [
      {
        "channel": "rfqs",
        "tickers": ["UDX-EXAMPLE-MARKET-A"]
      }
    ]
  }
}
```

Each subscription is acknowledged with its channel, ticker, and `sid`.

Each change arrives as its own frame carrying that one RFQ at the next `seq`:

| Frame          | RFQ status | Meaning                                             |
| -------------- | ---------- | --------------------------------------------------- |
| `rfq_opened`   | `open`     | Opened and still soliciting quotes.                 |
| `rfq_accepted` | `accepted` | A quote was accepted and last look is running.      |
| `rfq_closed`   | `closed`   | Concluded after last look, canceled, expired, or otherwise closed. |
| `rfq_rejected` | `rejected` | Rejected by the exchange.                           |

A multi-leg RFQ reaches every subscription whose ticker is one of its legs. See [Stream RFQ Data](/api-reference/websocket/rfqs/send-rfq-data) for the full message contract.

## Accept a Quote

**REST**

[Accept the chosen quote](/api-reference/rest/quotes/accept-quote) by its `rfq_id` and `quote_id`, echoing the quote's `price` and `quantity`, the opposite `side`, and a `client_order_id` for the order the trade will create:

```json
{
  "side": "buy",
  "price": "0.55",
  "quantity": "100",
  "client_order_id": "my-rfq-1-fill"
}
```

The `202 Accepted` response carries the `order_id` the trade will use. Acceptance opens last look. [Poll the quote](/api-reference/rest/quotes/get-quote): it reads `accepted` while the window is open, then `confirmed` if the maker confirms or `canceled` if the maker cancels or the window lapses. `confirmed` is the maker's decision, not the trade. The trade lives on the order the accept created: [read the order](/api-reference/rest/orders/get-order) by the `order_id` from the accept response, or [its fills](/api-reference/rest/portfolio/get-fills) correlated by your `client_order_id`. A `filled` order is the trade; a `rejected` order means the exchange rejected the execution even though the maker confirmed.

**WebSocket**

[Accept the chosen quote](/api-reference/websocket/rfqs/receive-accept-quote-command) with `accept_quote`, naming its `quote_id` and `rfq_id` and echoing the quote's `price` and `quantity`, the opposite `side`, and a `client_order_id` for the order the trade will create:

```json
{
  "id": 9,
  "cmd": "accept_quote",
  "params": {
    "quote_id": "c4ca4238",
    "rfq_id": "8f14e45f",
    "side": "buy",
    "price": "0.55",
    "quantity": "100",
    "client_order_id": "my-rfq-1-fill"
  }
}
```

The `quote_accept_submitted` response carries the `order_id` the trade will use — the exchange accepted the submission, not the trade:

```json
{
  "id": 9,
  "type": "quote_accept_submitted",
  "msg": {
    "quote_id": "c4ca4238",
    "order_id": "45c48cce",
    "client_order_id": "my-rfq-1-fill"
  }
}
```

Acceptance opens last look, and the outcome reaches the `quotes` subscription: the quote arrives as `quote_accepted` when the window opens, then `quote_confirmed` if the maker confirms or `quote_canceled` if the maker cancels or the window lapses. `quote_confirmed` is the maker's decision, not the trade: [read the order](/api-reference/rest/orders/get-order) by the response's `order_id` for the execution, `filled` or `rejected`. An `rfq_id` that is unknown — or not yours — answers a `quote_not_found` error; a `quote_id` naming no live quote on that RFQ is rejected (`permission_denied`), exactly as over REST. `idempotency_key` is carried but not deduplicated on yet: treat a lost response as unresolved and check your orders by `client_order_id` before resubmitting.
