> ## Documentation Index
> Fetch the complete documentation index at: https://docs.totalis.trade/llms.txt
> Use this file to discover all available pages before exploring further.

# Submit or replace quote

> Submit a price quote for an active quote request, or replace your existing quote.

Submit a quote on an active quote request. You hold at most one active quote per request version. Submitting again for the same version replaces it atomically.

When the user edits the legs or bet amount, the request's `version` and `request_hash` change. Listen for `quote_request:updated` on the [SSE stream](/solana/api-reference/quote-service-mm/stream) to detect the change and re-price.

<Note>
  A new version needs no withdraw. A quote is scoped to one `(request, version)` pair. When the request advances, your prior-version quote is invalidated automatically: it leaves the book at once, can no longer be accepted, and never blocks a new submission. `PUT` again with the new `request_version` and `request_hash` from the latest `quote_request:updated` event. You don't need to [withdraw](/solana/api-reference/quote-service-mm/withdraw-quote) the old quote first.
</Note>

## Authentication

API key required. Pass your API key in the `X-API-Key` header.

```
X-API-Key: <key>
```

## Path parameters

<ParamField path="id" type="string" required>
  The quote request ID (UUID).
</ParamField>

## Request body

<ParamField body="request_version" type="integer" required>
  The quote request version you priced. Must match the current version from the SSE stream.
</ParamField>

<ParamField body="request_hash" type="string" required>
  The `request_hash` from the quote request event. Prevents pricing against stale data.
</ParamField>

<ParamField body="payout_odds" type="number" required>
  Payout multiplier on the net stake (`user_stake`), never the gross `bet_amount`; see [Fees](/solana/limits-and-fees#fees). At least 1.0001. The server derives `user_cost`, `total_payout`, and `mm_cost` from it.
</ParamField>

<ParamField body="expires_in_ms" type="integer">
  How long this quote is valid, in milliseconds. Range: 5000-60000. Default: 15000.
</ParamField>

## Response

Returns `201 Created` for a new quote or `200 OK` when replacing an existing quote.

<ResponseField name="data" type="object">
  <Expandable title="data">
    <ResponseField name="quote" type="object">
      The submitted quote.

      <Expandable title="quote">
        <ResponseField name="id" type="string">Quote UUID.</ResponseField>
        <ResponseField name="market_maker_id" type="string">Your market maker ID.</ResponseField>
        <ResponseField name="request_version" type="integer">The request version this quote is for.</ResponseField>
        <ResponseField name="request_hash" type="string">The request hash this quote is for.</ResponseField>
        <ResponseField name="payout_odds" type="number">The payout multiplier.</ResponseField>
        <ResponseField name="user_cost" type="number">The net stake in USDC (`bet_amount - taker_fee`). Equals the request's `user_stake`.</ResponseField>
        <ResponseField name="total_payout" type="number">Total payout in USDC (`user_cost * payout_odds`).</ResponseField>
        <ResponseField name="mm_cost" type="number">Your risk in USDC (`total_payout - user_cost`).</ResponseField>
        <ResponseField name="valid_until" type="string">ISO 8601 timestamp when this quote expires.</ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="book_seq" type="integer">The new quote book sequence number.</ResponseField>
    <ResponseField name="replaced" type="boolean">`true` if this replaced a previous quote.</ResponseField>
    <ResponseField name="taker_fee_bps" type="integer">The taker fee rate this quote was priced at, in basis points (`100` is 1%). Use it to reconcile `user_cost` against the base you priced, and to tell a fee-on quote from a fee-off one.</ResponseField>
  </Expandable>
</ResponseField>

## Conflict reasons

A `409 Conflict` carries the cause in `error.details.reason`:

| Reason | Description |
| - | - |
| `not_found` | Quote request ID does not exist. |
| `expired` | Quote request has expired. |
| `not_active` | Quote request is committed, cancelled, or otherwise inactive. |
| `version_mismatch` | Your `request_version` or `request_hash` (or both) does not match the live request. You priced a stale version, or it changed while you were pricing. Submit both current values from the latest `quote_request` or `quote_request:updated` event. A still-open prior quote never causes this, so there is nothing to withdraw. |
| `self_quote` | You cannot quote your own requests. |

## Errors

| Status | Code | Description |
| - | - | - |
| 400 | `VALIDATION_ERROR` | Invalid body. See `details.issues`. |
| 401 | `UNAUTHORIZED` | Missing or invalid API key. |
| 403 | `FORBIDDEN` | The credential does not start with `api_` (`details.reason: "wrong_api_key_type"`), or the key lacks `mm:quote`. |
| 409 | `CONFLICT` | Quote rejected. See `details.reason` above. |
| 503 | `SERVICE_UNAVAILABLE` | The taker fee rate could not be read (`details.reason: "fee_unavailable"`). The quote was not priced. Retry. |

<RequestExample>
  ```bash theme={null}
  curl -X PUT https://api.totalis.trade/v1/mm/quote-requests/1a6d1f06-9d4f-47cb-994b-3bdfbbef7e40/quote \
    -H "X-API-Key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "request_version": 1,
      "request_hash": "sha256:9f86d08...",
      "payout_odds": 4.0,
      "expires_in_ms": 15000
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  {
    "data": {
      "quote": {
        "id": "b2c3d4e5-6789-0abc-def1-234567890abc",
        "market_maker_id": "did:privy:cm3mm...",
        "request_version": 1,
        "request_hash": "sha256:9f86d08...",
        "payout_odds": 4.0,
        "user_cost": 24.75,
        "total_payout": 99,
        "mm_cost": 74.25,
        "valid_until": "2026-06-01T18:45:45.000Z"
      },
      "book_seq": 5,
      "replaced": false,
      "taker_fee_bps": 100
    }
  }
  ```
</ResponseExample>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.