---
title: "Current valid tick grid for one market"
method: GET
path: "/v1/markets/tick-size"
tags: ["Markets"]
---

# Current valid tick grid for one market

`GET /v1/markets/tick-size`

## Request

- Base URL: `https://md.kairos.trade`
- URL: `https://md.kairos.trade/v1/markets/tick-size`
- Auth: one of:
  - none
  - API key in header `X-Client-Id` and API key in header `X-Api-Key` and API key in header `X-Api-Secret`

Returns the grid of valid price increments the venue CURRENTLY enforces for a market — the same grid the order executor validates against. It describes the grid; it never snaps or rounds a price. Served from the market metadata cache, which the orderbook streamer keeps current with the venue's live tick changes. Rate-limit bucket: LIGHT.

- **polymarket** — a single flat range over `[0, 1]`; the venue flips 0.01↔0.001 at the price extremes. Pass `asset_id` (the CLOB token id) to read the per-token tick, which is where a live change lands first.
- **kalshi** — the market's `price_ranges` (a tapered grid). `min_tick` is the finest step. If only the deprecated flat `tick_size` is present the response is a single flat range flagged `synthetic: true`.
- **predictfun** — `supported: false`; the venue exposes no per-market tick. No grid is fabricated.

Query parameters and the response body are wire-compatible with the Data API's `GET /markets/tick-size`; `as_of` (when the grid was read from the metadata cache) is additive. `start` / `end` / `step` / `min_tick` are decimal strings so precision is never lost. Cached for 5 seconds (`public, max-age=5` with a strong ETag).

## Query parameters

- `provider` 'kalshi' | 'polymarket' | 'predictfun', required
- `contract_id` string, required
- `asset_id` string

## Response `200`

The market's current tick grid, or the explicit unsupported payload for predictfun.

- union
  - TickGrid: A market's current valid tick grid. Wire-compatible with the Data API `GET /markets/tick-size` response; `as_of` is additive.
    - `provider` 'kalshi' | 'polymarket', required
    - `contract_id` string, required
    - `asset_id` string, nullable, required: The Polymarket token id the grid was read for; null when the lookup was market-level.
    - `ranges` TickRange[], required
      - `start` string, required
      - `end` string, required
      - `step` string, required
    - `min_tick` string, required: The finest step across all bands — the smallest increment the market will ever accept.
    - `source` 'metadata_cache' | 'kalshi_price_ranges' | 'streamer_projection', required: Which upstream fact the grid was built from. `streamer_projection` is the orderbook streamer's projected finest venue step, used for a Kalshi market whose live band layout is not currently cached.
    - `synthetic` boolean, required: True when the grid is a single flat band standing in for a layout that is not currently known — the minimum tick is correct, the band boundaries are not described.
    - `price_level_structure` string, nullable, required: Kalshi's `price_level_structure` when present; null otherwise.
    - `as_of` string, date-time, required: When this grid was read from the market metadata cache (UTC). The cache itself is kept current by the orderbook streamer's live tick-change ingestion.
  - TickGridUnsupported: Explicit "no per-market grid" answer for predictfun. No grid is fabricated.
    - `provider` 'predictfun', required
    - `contract_id` string, required
    - `supported` false, required
    - `reason` string, required

## Other responses

- `304`: Not Modified — `If-None-Match` matched the current ETag.
- `400`: Unknown provider, a provider with no per-market grid (hyperliquid, opinion), or an empty `contract_id`.
- `401`: No valid credential presented. Every path returns `code: unauthorized`; the triggers differ: - An `Authorization` header on a deployment where bearer auth is not enabled (`bearer authentication is not enabled`). - A bearer token that fails verification (`invalid or expired session`), or whose token/session has been revoked (`session has been revoked`). - An incomplete or wrong API-key header set. Sending *any* of `X-Client-Id`, `X-Api-Key`, `X-Api-Secret` commits the request to the API-key path, so a partial set is rejected rather than silently degrading to anonymous limits (`valid X-Client-Id, X-Api-Key, and X-Api-Secret headers are required`). - No credential material at all while the anonymous free tier is unavailable — switched off for the deployment, forced off through the runtime kill switch, or not yet resolvable on a replica that has never read the flag (it fails closed).
- `403`: API key presented from a source IP not in that credential's whitelist.
- `404`: The metadata cache has no such market (after its ClickHouse and live-venue read-through).
- `429`: Two different gates return this status, both with `code: rate_limited`: - **Per-credential (or per-IP, when anonymous) weighted budget exhausted.** The message is `rate limit exceeded`, or, for anonymous callers, `anonymous rate limit exceeded — request an API key for higher limits (…)`. `Retry-After` is the whole number of seconds until the current one-minute window rolls over, floored at 1. All four `X-RateLimit-*` headers are present. - **Per-IP admission gate.** An in-process, pre-authentication guard that keeps a flood off the shared credential cache and database. The message is `too many requests from this address` and `Retry-After` is a flat `60`. Because this fires *before* authentication, the response carries **no** `X-RateLimit-*` headers at all.
- `502`: `tick_unavailable` — the market exists but carries no usable grid (no Polymarket tick; a Kalshi market whose cached `raw` is the catalog row rather than the venue object, so it has no `price_ranges`; or a venue object with neither `price_ranges` nor `tick_size`); `upstream` — the metadata cache answered with an unexpected status.
- `503`: `cache_cold` — the metadata cache is still warming (with `Retry-After: 5`); `unavailable` — no metadata cache is configured; or `rate_limiter_unavailable`.

---

[API](https://skmtc.dev/kairos/apis/kairos-market-data-api.md) - [All operations](https://skmtc.dev/kairos/apis/kairos-market-data-api/llms.txt) - [OpenAPI document](https://skmtc.dev/kairos/apis/kairos-market-data-api/revisions/01e987f59a04?raw)
