---
title: Creating Quotes
description: Find the RFQs soliciting your member, answer one with a quote, follow it through last look, and confirm or cancel it, over REST or WebSocket.
---

A quote is a maker's single-sided price for one request for quote. For how quoting and last look work, see [RFQs](/concepts/rfqs); for the taker's side, see [Requesting Quotes](/walkthroughs/requesting-quotes). This walkthrough shows the maker's operations. It assumes the environment and API key from the [Quick Start](/quick-start).

Every 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 quotes, stream every quote you can see, and confirm or cancel your quotes.



## Find RFQs to Quote

**REST**

Poll [the RFQs soliciting your member](/api-reference/rest/rfqs/list-rfqs); those you did not create omit `client_rfq_id`. An RFQ accepts quotes while its status is `open` and until its `expires_at`.

**WebSocket**

Subscribe to the `rfqs` channel with `tickers` omitted to receive every RFQ visible to your member on one `sid`, or list tickers to open one subscription each.

## Create a Quote

**REST**

[Create the quote](/api-reference/rest/quotes/create-quote) naming the `rfq_id`, your `client_quote_id`, one `side`, and a `price` and `quantity`:

```json
{
  "rfq_id": "8f14e45f",
  "client_quote_id": "my-quote-1",
  "side": "sell",
  "price": "0.55",
  "quantity": "100"
}
```

Omit `ticker` for an RFQ composed from legs; when present it must equal the RFQ's market. Add `account_id` when the key is not restricted to one account. The `202 Accepted` response echoes your `client_quote_id`; the exchange assigns `quote_id` once the quote lands.

**WebSocket**

Subscribe to the `quotes` channel first, as described under [Follow the Quote](#follow-the-quote). Then [create the quote](/api-reference/websocket/rfqs/receive-create-quote-command) with `create_quote`. A `quote_create_submitted` frame echoing your `client_quote_id` acknowledges the accepted submission, the `quote_opened` frame carrying the same `client_quote_id` confirms the committed quote, and a rejected command answers with an `error` frame that echoes the command `id`.

```json
{
  "id": 8,
  "cmd": "create_quote",
  "params": {
    "client_quote_id": "my-quote-1",
    "rfq_id": "8f14e45f",
    "side": "sell",
    "price": "0.55",
    "quantity": "100"
  }
}
```

Omit `ticker` for an RFQ composed from legs; when present it must match the RFQ. An `idempotency_key` is carried but not yet used for deduplication, so a retry that reuses it can create a second quote.

## Follow the Quote

**REST**

To read your quotes for one RFQ, filter the account quotes list by `rfq_id`. The RFQ responses list requires access to the requesting account.

[List your quotes](/api-reference/rest/quotes/list-account-quotes) with your `account_id` and filtered by `client_quote_id` for the landed quote and its `quote_id`, then [poll the quote](/api-reference/rest/quotes/get-quote) for its status:

| Status      | Meaning                                                                         |
| ----------- | ------------------------------------------------------------------------------- |
| `open`      | Live and available to the taker.                                                |
| `accepted`  | A taker accepted it; your last-look window is open and `expires_at` is its end. |
| `confirmed` | You confirmed during last look. The trade itself appears in your fills.         |
| `canceled`  | Canceled, expired, or ended without a trade.                                    |
| `rejected`  | Rejected by the exchange.                                                       |

**WebSocket**

Open the `quotes` channel with the `subscribe` command. Every quote visible to your member arrives on one `sid`, your own quotes and the quotes answering your RFQs alike. 

```json
{
  "id": 7,
  "cmd": "subscribe",
  "params": {
    "channels": [
      {
        "channel": "quotes"
      }
    ]
  }
}
```

Each change to a quote arrives as its own frame carrying that one quote at the next `seq`. Match your quotes by `client_quote_id`:

| Frame             | Quote status | Meaning                                                                         |
| ----------------- | ------------ | ------------------------------------------------------------------------------- |
| `quote_opened`    | `open`       | Live on the exchange.                                                           |
| `quote_accepted`  | `accepted`   | A taker accepted it; your last-look window is open and `expires_at` is its end. |
| `quote_confirmed` | `confirmed`  | You confirmed during last look. The trade itself appears in your fills.         |
| `quote_canceled`  | `canceled`   | Canceled, expired, or ended without a trade.                                    |
| `quote_rejected`  | `rejected`   | Rejected by the exchange, or by the maker during last look.                     |

## Confirm or Cancel the Quote

While a quote is `open` you may cancel it. When a taker accepts it, its status becomes `accepted` and its `expires_at` moves to the end of your last-look window: confirm the accepted quote to execute the trade, or cancel it to release it. Doing nothing counts as a cancellation: at `expires_at` the quote becomes `canceled` and no trade occurs.

**REST**

[Cancel the quote](/api-reference/rest/quotes/cancel-quote) or [confirm the accepted quote](/api-reference/rest/quotes/confirm-accepted-quote) by its `rfq_id` and `quote_id`. Each `202 Accepted` response echoes the quote; the committed outcome is read by polling the quote for `canceled` or `confirmed`, and the trade itself from [your fills](/api-reference/rest/portfolio/get-fills).

**WebSocket**

[Confirm](/api-reference/websocket/rfqs/receive-confirm-quote-command) or [cancel](/api-reference/websocket/rfqs/receive-cancel-quote-command) the quote by its `rfq_id` and `quote_id` — the same `cancel_quote` cancels a resting quote and an accepted one alike; there is no separate reject command:

```json
{
  "id": 10,
  "cmd": "confirm_quote",
  "params": {
    "rfq_id": "8f14e45f",
    "quote_id": "c4ca4238"
  }
}
```

Each command answers its own response — `quote_confirm_submitted` or `quote_cancel_submitted` — echoing the quote's `quote_id` and your `client_quote_id`; the exchange accepted the submission, not the outcome:

```json
{
  "id": 10,
  "type": "quote_confirm_submitted",
  "msg": {
    "quote_id": "c4ca4238",
    "client_quote_id": "my-quote-1"
  }
}
```

The committed outcome arrives on your `quotes` subscription: `quote_confirmed` after a confirmation, `quote_canceled` after a cancel. A confirmation is your decision, not the trade: the fill that results is read from [your fills](/api-reference/rest/portfolio/get-fills). Both commands address one of your own quotes; a `quote_id` another member holds is indistinguishable from an unknown one (`quote_not_found`).
