---
title: "Daily DEX token prices"
method: GET
path: "/{chain}/dex/prices"
tags: ["DEX"]
---

# Daily DEX token prices

`GET /{chain}/dex/prices`

## Request

- Base URL: `https://api.blockvectra.com/v1/data`
- URL: `https://api.blockvectra.com/v1/data/{chain}/dex/prices`
- Auth: API key in header `x-api-key`

Daily volume-weighted average price (VWAP) and volume for a DEX token over a specified date range (up to 90 days). Not paginated: `next_cursor` is never present.
**Snapshot freshness**: prices come from a daily table that the data store refreshes once a day, so the latest day can be missing or partial for up to about a day. `as_of_block` here is the service's current indexed head, not the block height of the snapshot; read the snapshot time from `meta.refreshed_at`, and treat the data as stale when `refreshed_at` is `null`.

## Path parameters

- `chain` string, required

## Query parameters

- `token` string, required: 20-byte address. `0x`/`0X` prefix optional; either hex digit case is accepted.
- `quote` string: 20-byte address. `0x`/`0X` prefix optional; either hex digit case is accepted.
- `from` string, date, required
- `to` string, date, required

## Response `200`

Daily price/volume rows for `[from, to]` (empty array if none).

- DexPriceListEnvelope: `next_cursor` is never present (this endpoint has no pagination).
  - `data` DexDailyPrice[], required
    - `day` string, date, required: `YYYY-MM-DD`, UTC calendar day.
    - `token` string, required: 20-byte address, canonical form always `0x` + 40 lowercase hex digits.
    - `token_symbol` string, nullable, required
    - `token_name` string, nullable, required
    - `quote_token` string, required: 20-byte address, canonical form always `0x` + 40 lowercase hex digits.
    - `quote_symbol` string, nullable, required: `"ETH"` when `quote_token` is the zero address.
    - `quote_name` string, nullable, required: `"Ether"` when `quote_token` is the zero address.
    - `base_decimals` integer, nullable, required
    - `quote_decimals` integer, nullable, required: `18` when `quote_token` is the zero address.
    - `swap_count` integer, required
    - `base_volume_raw` string, required: Non-negative integer that may exceed 2^53, rendered as a plain decimal string — never a JSON number, never scientific or hex notation.
    - `quote_volume_raw` string, required: Non-negative integer that may exceed 2^53, rendered as a plain decimal string — never a JSON number, never scientific or hex notation.
    - `base_volume` string, required: Human-adjusted (decimals-scaled) fixed-point value rendered as a plain decimal string — never a JSON number.
    - `quote_volume` string, required: Human-adjusted (decimals-scaled) fixed-point value rendered as a plain decimal string — never a JSON number.
    - `vwap` string, required: Human-adjusted (decimals-scaled) fixed-point value rendered as a plain decimal string — never a JSON number.
    - `first_price` string, required: Human-adjusted (decimals-scaled) fixed-point value rendered as a plain decimal string — never a JSON number.
    - `last_price` string, required: Human-adjusted (decimals-scaled) fixed-point value rendered as a plain decimal string — never a JSON number.
    - `min_price` string, required: Human-adjusted (decimals-scaled) fixed-point value rendered as a plain decimal string — never a JSON number.
    - `max_price` string, required: Human-adjusted (decimals-scaled) fixed-point value rendered as a plain decimal string — never a JSON number.
    - `first_price_numerator` string, required: Non-negative integer that may exceed 2^53, rendered as a plain decimal string — never a JSON number, never scientific or hex notation.
    - `first_price_denominator` string, required: Non-negative integer that may exceed 2^53, rendered as a plain decimal string — never a JSON number, never scientific or hex notation.
    - `last_price_numerator` string, required: Non-negative integer that may exceed 2^53, rendered as a plain decimal string — never a JSON number, never scientific or hex notation.
    - `last_price_denominator` string, required: Non-negative integer that may exceed 2^53, rendered as a plain decimal string — never a JSON number, never scientific or hex notation.
    - `min_price_numerator` string, required: Non-negative integer that may exceed 2^53, rendered as a plain decimal string — never a JSON number, never scientific or hex notation.
    - `min_price_denominator` string, required: Non-negative integer that may exceed 2^53, rendered as a plain decimal string — never a JSON number, never scientific or hex notation.
    - `max_price_numerator` string, required: Non-negative integer that may exceed 2^53, rendered as a plain decimal string — never a JSON number, never scientific or hex notation.
    - `max_price_denominator` string, required: Non-negative integer that may exceed 2^53, rendered as a plain decimal string — never a JSON number, never scientific or hex notation.
    - `refreshed_at` string, date-time, required: `YYYY-MM-DDTHH:MM:SSZ`, UTC, second precision.
  - `meta` Meta, required: Metadata present on every success response.
    - `chain` string, required: Chain identifier; the value of the `{chain}` path parameter.
    - `chain_slug` string, required: Canonical uppercase chain slug; `chain` is always its lowercase form.
    - `chain_external_id` string, required: CAIP-2 formatted external chain identifier (`eip155:{chain_id}`).
    - `as_of_block` integer, required: The newest fully written block (the `blocks` table's maximum height); the only serving bound for block-scoped endpoints. For snapshot endpoints (balances, holders, nfts, dex prices, stocks) it is the service's current indexed head, not the block height of the snapshot: read the snapshot time from `meta.refreshed_at`, and treat the data as stale when `refreshed_at` is `null`.
    - `safe_block` integer, nullable, required: A marker only: the node's consensus `safe` block. Always present; `null` while no value is known (the node has no such tag, or the indexer has not read one yet). Only grows, never below `finalized_block`, and may be above or below `as_of_block`. It never truncates, rejects or bounds a response; see Finality in the API description.
    - `finalized_block` integer, nullable, required: A marker only: the node's consensus `finalized` block. Always present; `null` while no value is known (the node has no such tag, or the indexer has not read one yet). Only grows, and may be above or below `as_of_block`. It never truncates, rejects or bounds a response; see Finality in the API description.
    - `coverage` 'full' | 'partial', required: `"partial"` appears only from `GET /{chain}/addresses/{address}/transactions` and `GET /{chain}/addresses/{address}/transfers`, when `clamp=true` narrowed the served window, and from those two, `GET /{chain}/tokens/{token}/transfers` and `GET /{chain}/dex/swaps` when the block window starts before the lower bound of the dataset the endpoint reads -- the chain's first indexed block, or higher while that dataset is still being backfilled (see Coverage in the API description and each endpoint's window description). Every other endpoint reports `"full"`.
    - `refreshed_at` string, date-time, required: `YYYY-MM-DDTHH:MM:SSZ`, UTC, second precision.

## Other responses

- `400`: `error.code = "bad_request"`: missing `token`/`from`/`to`; invalid `token`/`quote`; `from`/`to` not a valid `YYYY-MM-DD` calendar date; or `from` after `to`.
- `401`: HTTP 401: a missing API key returns missing_api_key; an unknown, disabled, or revoked key returns the same invalid_api_key error envelope. error.code and error.data.reason contain the reason. Rejected requests are not billed.
- `402`: Payment required: the paid balance or the free grant is exhausted. The response body is `{"error":{"code":"insufficient_balance"}}`. Rejected requests are not billed.
- `404`: `error.code = "not_found"`: the target object was not found, or `{chain}` is not a registered or public chain (returns HTTP 404 with `error.code = "not_found"`, not billed).
- `409`: `error.code = "span_exceeded"`: `to - from` is more than 90 days.
- `422`: `error.code = "no_coverage"`: no data here, which is permanent except while a dataset is being backfilled (a windowed endpoint's lower bound can move down as the backfill proceeds, so retry later). Either the chain does not have this endpoint's capability, or the requested block (or whole block window) is before the chain's first covered block (`coverage.from_block`) -- for the windowed endpoints, the lower bound of the dataset they read, which is that block or higher while the dataset is still being backfilled -- or the capability needs history from genesis (`balances`, `holders`, `nfts`) and `coverage.from_block` is not `0` yet or the indexed blocks have holes, or (traces) the block falls in a permanent trace coverage gap. A block window entirely before the lower bound is reported as this `422` even when its `to_block` is also above `as_of_block`. See Coverage in the API description (the history start in examples is a placeholder; read `GET /chains` `coverage.from_block` at runtime).
- `429`: Rate limited. `{"error":{"code":"rate_limited"}}` when the key CU rate limit is exceeded (the response includes `Retry-After`) or the account call rate limit is exceeded (no `Retry-After`). `{"error":{"code":"cost_exceeds_burst"}}` when a single request exceeds the key burst capacity; split the request, retrying as sent never succeeds. Rejected requests are not billed.
- `503`: `error.code = "unavailable"`: the service is temporarily unavailable, timed out, busy on this chain (no query slot freed up in time, see `limits.max_concurrent_queries` in `GET /chains`), or shutting down (see "Errors" above). Always carries an HTTP `Retry-After` header (seconds); wait at least that long before retrying.

---

[API](https://skmtc.dev/blockvectra/apis/blockvectra-data-api.md) · [All operations](https://skmtc.dev/blockvectra/apis/blockvectra-data-api/llms.txt) · [OpenAPI document](https://skmtc.dev/blockvectra/apis/blockvectra-data-api/revisions/c5b949e955b5?raw)
