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

# Quotes

> Query PropAMM quote points over REST and quote ladder events with the SDK.

When available, `GET /quotes` will return stored PropAMM quote points in global collector-time order. Use `observation_id` to fetch all points sampled in one quote observation.

> **Availability:** `GET /quotes` is documented from the published OpenAPI contract but is not live yet. The SDK quote ladder guidance is below.

## Request

```bash theme={null}
curl "https://api.polaris.supply/quotes?source=bopamm&market=ethereum&limit=2"
```

### Query parameters

| Parameter | Type | Required | Description |
| - | - | - | - |
| `source` | `string` | No | Optional exact source identifier |
| `market` | `string` | No | Optional exact normalized routing market |
| `instrument` | `string` | No | Exact venue-native instrument |
| `observation_id` | `string` | No | Exact, nonempty quote observation ID |
| `start` | `integer` | No | Inclusive collector time in Unix milliseconds. Older history requires a Polaris API key. |
| `end` | `integer` | No | Inclusive collector time in Unix milliseconds. Older history requires a Polaris API key. |
| `limit` | `integer` | No | Page size from 1 to 1000; defaults to 200 |
| `cursor` | `string` | No | Opaque cursor bound to the complete query, including observation\_id |

## Access and behavior

With no bounds, the latest hour is available anonymously; older history requires a Polaris API key. `start` and `end` are inclusive collector timestamps in Unix milliseconds. `observation_id` is an exact nonempty filter and is part of the cursor-bound query.

## Response

| Field | Type | Required | Description |
| - | - | - | - |
| `has_more` | `boolean` | Yes | — |
| `items` | `QuoteObservationItem[]` | Yes | — |
| `next_cursor` | `string / null` | No | — |

### `items[]` fields

| Field | Type | Required | Description |
| - | - | - | - |
| `amount_kind` | `string` | Yes | — |
| `block_hash` | `string` | Yes | — |
| `block_number` | `integer` | Yes | — |
| `collector_timestamp` | `integer` | Yes | — |
| `event_id` | `string` | Yes | — |
| `exchange_timestamp` | `integer / null` | No | — |
| `input_amount` | `string` | Yes | — |
| `input_asset_id` | `string` | Yes | — |
| `input_chain_id` | `string` | Yes | — |
| `input_decimals` | `integer` | Yes | — |
| `instrument` | `string` | Yes | — |
| `market` | `string` | Yes | — |
| `observation_id` | `string` | Yes | — |
| `oracle` | `string / null` | No | — |
| `output_amount` | `string` | Yes | — |
| `output_asset_id` | `string` | Yes | — |
| `output_chain_id` | `string` | Yes | — |
| `output_decimals` | `integer` | Yes | — |
| `pool` | `string / null` | No | — |
| `router` | `string` | Yes | — |
| `schema_version` | `integer` | Yes | — |
| `source` | `string` | Yes | — |
| `source_capture_id` | `string` | Yes | — |
| `transaction_hash` | `string` | Yes | — |
| `transaction_index` | `integer` | Yes | — |

Rows contain input and output asset identifiers, amounts, decimal scales, and on-chain context when available. The [SDK quote ladder events](#sdk-quote-ladders) below group quotes in a nested event envelope rather than returning one flat REST row per quote point.

## Pagination

Pass `next_cursor` as `cursor` with the same filters. Stop when `has_more` is false, or when `next_cursor` is null for endpoints without `has_more`. A cursor is opaque; do not edit or reuse it with different filters.

## Errors

The OpenAPI contract lists `400`, `401`, `422`, `429`, `503`. Error responses use `error.code`, `error.message`, and `error.resolution`. Narrow an expensive query after `422`. Follow `Retry-After` after `429`.

For the machine-readable contract, see the [OpenAPI document](https://api.polaris.supply/openapi.json).

## SDK quote ladders

The REST endpoint returns flat quote points. The Python SDK method below yields standardized quote ladder events with multiple size points nested under `data.values.quotes`. Use this shape for replay and quote-curve analysis.

Use `client.propamm_quote_ladders()` when you need quote ladders from PropAMMs. This method returns standardized quote ladder events across all supported PropAMM sources.

### Supported sources

All six PropAMMs produce the same standardized v2 JSONL quote-ladder schema. The recorder uses the following static Ethereum address catalogue:

| PropAMM | Source ID | Router | Oracle/Engine | Additional | Notes |
| - | - | - | - | - | - |
| FermiSwap | `fermiswap` | `0x5979...3320` | `0x26e5...f312` | — | Standard |
| BopAMM | `bopamm` | `0xB09A...dD76` | `0xB099...D03C` | — | Standard |
| Kipseli | `kipseli` | `0x342b...ADCD` | `0xFe3D...e185` | — | Standard |
| Metric | `metric` | `0xcb41...ef91` | `0x28d9...1D39` | Pool: `0xe22F...82e0C` | Includes pool |
| Tempest | `tempest` | `0x0000...2149` | — | — | Standard |
| TaurusFi | `taurusfi` | `0x217D...D95a` | `0x8590...4c75` | — | Standard |

### Method signature

```python theme={null}
propamm_quote_ladders(source, market, from_=None, to=None, allow_gaps=False, output="iterator", batch_size=65536)
```

### Parameters

| Parameter | Type | Required | Notes |
| - | - | - | - |
| source | str | Yes | Source ID (e.g., `fermiswap`, `bopamm`, `kipseli`, `metric`, `tempest`, `taurusfi`) |
| market | str | Yes | Normalized market ID (e.g., `ethereum`) |
| from\_ | str/datetime/date/int | No | Inclusive start time (ISO 8601, datetime, date, or epoch milliseconds) |
| to | str/datetime/date/int | No | Exclusive end time (same formats as from\_) |
| allow\_gaps | bool | No | Return covered rows and warn instead of failing on coverage gaps |
| output | str | No | `iterator`, `batches`, or `dataframe` |
| batch\_size | int | No | Maximum rows per Arrow batch; must be positive |

### Return value

A single-pass iterator of normalized quote ladder event dictionaries by default. With `output="batches"`, returns flat PyArrow record batches; with `output="dataframe"`, returns an eager Pandas DataFrame.

### Example response

Standard quote ladder (FermiSwap, BopAMM, Kipseli, Tempest, TaurusFi):

```python theme={null}
[
    {
        'collector_timestamp': 1700000001000,
        'collector_sequence': 1,
        'exchange_timestamp': 1700000000000,
        'exchange_sequence': None,
        'source': 'fermiswap',
        'type': 'record',
        'data': {
            'series': 'quote_ladder',
            'values': {
                'event_id': '0x0000000000000000000000000000000000000000000000000000000000000001:0x0000000000000000000000000000000000000000000000000000000000000003:fermiswap:0x0000000000000000000000000000000000000006:0x0000000000000000000000000000000000000007',
                'chain_id': 1,
                'block_number': 20000000,
                'block_hash': '0x0000000000000000000000000000000000000000000000000000000000000001',
                'parent_hash': '0x0000000000000000000000000000000000000000000000000000000000000002',
                'transaction_hash': '0x0000000000000000000000000000000000000000000000000000000000000003',
                'transaction_index': 4,
                'router': '0x0000000000000000000000000000000000000004',
                'oracle': '0x0000000000000000000000000000000000000005',
                'token_in': '0x0000000000000000000000000000000000000006',
                'token_out': '0x0000000000000000000000000000000000000007',
                'token_in_decimals': 18,
                'token_out_decimals': 6,
                'quotes': [
                    {
                        'amount_in': '10',
                        'amount_out': '20'
                    }
                ]
            }
        }
    }
]
```

Metric quote ladder (includes pool field):

```python theme={null}
[
    {
        'collector_timestamp': 1700000001000,
        'collector_sequence': 2,
        'exchange_timestamp': 1700000000000,
        'exchange_sequence': None,
        'source': 'metric',
        'type': 'record',
        'data': {
            'series': 'quote_ladder',
            'values': {
                'event_id': '0x0000000000000000000000000000000000000000000000000000000000000001:0x0000000000000000000000000000000000000000000000000000000000000003:metric:0x0000000000000000000000000000000000000008:0x0000000000000000000000000000000000000006:0x0000000000000000000000000000000000000007',
                'chain_id': 1,
                'block_number': 20000000,
                'block_hash': '0x0000000000000000000000000000000000000000000000000000000000000001',
                'parent_hash': '0x0000000000000000000000000000000000000000000000000000000000000002',
                'transaction_hash': '0x0000000000000000000000000000000000000000000000000000000000000003',
                'transaction_index': 4,
                'router': '0x0000000000000000000000000000000000000004',
                'oracle': '0x0000000000000000000000000000000000000005',
                'pool': '0x0000000000000000000000000000000000000008',
                'token_in': '0x0000000000000000000000000000000000000006',
                'token_out': '0x0000000000000000000000000000000000000007',
                'token_in_decimals': 18,
                'token_out_decimals': 6,
                'quotes': [
                    {
                        'amount_in': '10',
                        'amount_out': '20'
                    }
                ]
            }
        }
    }
]
```

> **Note:** These examples use artificial addresses and amounts from test fixtures. Real events contain actual blockchain addresses and computed quote amounts.

### Fields

PropAMM quote ladder events use the standard v2 event envelope with the following fields:

#### Event envelope

* `collector_timestamp`: when the recorder observed the envelope (milliseconds)
* `collector_sequence`: monotonic sequence number for the collector session
* `exchange_timestamp`: Ethereum block timestamp (milliseconds)
* `exchange_sequence`: venue-provided sequence number or `null`
* `source`: PropAMM source identifier
* `type`: always `"record"` for standardized events

#### Data structure

Under `data`:

* `data.series`: always `"quote_ladder"`
* `data.values`: quote ladder contents

#### Quote ladder values

* `event_id`: deterministic composite ID (transaction:source:router:token\_in:token\_out, or includes pool for Metric)
* `chain_id`: EVM chain identifier
* `block_number`: block containing the quote ladder
* `block_hash`: canonical block hash
* `parent_hash`: parent block hash
* `transaction_hash`: transaction containing the quote ladder
* `transaction_index`: transaction position within block
* `router`: PropAMM router contract address
* `oracle`: oracle contract address (nullable when not applicable)
* `pool`: pool contract address (Metric only, omitted for other sources)
* `token_in`: input token contract address
* `token_out`: output token contract address
* `token_in_decimals`: decimal precision for input token
* `token_out_decimals`: decimal precision for output token
* `quotes`: array of quote objects

#### Quote objects

Each quote in the `quotes` array contains:

* `amount_in`: input amount as decimal string (preserves full uint256 range)
* `amount_out`: output amount as decimal string (preserves full uint256 range)

### Important details

* **Decimal strings**: Quote amounts use decimal strings to preserve the full Ethereum uint256 range
* **Deterministic IDs**: `event_id` is deterministic across retries; Metric includes its pool address in the ID
* **Market metadata**: Each uploaded `.jsonl.zst` file starts with a metadata row containing `source` and `market`. The market field is intentionally omitted from individual data rows
* **Nullable fields**: `oracle` is nullable when not applicable; `pool` is omitted unless applicable (Metric only)
* **Standardization only**: Only `quote_ladder` records are standardized. Heartbeats, replay telemetry, state updates, and failures remain in raw format
* **No raw embedding**: PropAMM explicitly disables embedding the original raw envelope into standardized rows

### Example

```python theme={null}
from datetime import datetime, timedelta, timezone
from itertools import islice
from polaris_data import PolarisClient

end = datetime.now(timezone.utc)
start = end - timedelta(hours=1)

with PolarisClient() as client:
    ladders = client.propamm_quote_ladders(
        source="fermiswap",
        market="ethereum",
        from_=start,
        to=end,
    )
    print(list(islice(ladders, 2)))
```

### How it works

`client.propamm_quote_ladders()` filters quote ladder rows from the standardized stream using snapshot-first replay. Each PropAMM source produces the same v2 JSONL schema, stored separately by logical source with market identifier.

The standardized events preserve the full fidelity of the original PropAMM quote ladders while normalizing the envelope structure for consistent querying across all six sources.

### Related documentation

* [PropAMMs](/guides/propamms) for discovery, normalization, and quote-curve comparison workflows
* [Events](/schemas/events) for the complete v2 event envelope specification
* [Raw Data](/endpoints/raw) for venue-native capture rows
* [Quickstart](/quickstart) for getting started with the Python SDK
