---
title: "Get full market metadata (rules, images, contract spec)"
method: GET
path: "/markets/metadata"
tags: ["Markets"]
---

# Get full market metadata (rules, images, contract spec)

`GET /markets/metadata`

## Request

- Base URL: `https://data.kairos.trade`
- URL: `https://data.kairos.trade/markets/metadata`
- Auth: 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 full metadata document for one market. Resolution order: (1) a fast cached-metadata path — for Polymarket, a cache hit derives status/category/images from the cached upstream payload; (2) on a miss, falls back to a live provider-API fetch (Kalshi ticker + event metadata for images; Polymarket; Opinion; predict.fun) — this covers markets too new to be indexed yet (e.g. short-lived 15-minute crypto markets); (3) if the cache hit is non-null but carries **empty** `resolution_rules` (both `primary` and `secondary` blank), an extra provider-API call backfills `resolution_rules` (and `description` if also empty) without discarding the rest of the cached document. Only the cached-metadata path populates `condition_id`/`event_id`/`contract.settlement_ts` — the live provider-API fallback leaves those `null`. Finally, for `polymarket`/`predictfun`, a best-effort liquidity-rewards enrichment mutates `extra` in place (never blocks or fails the response): Polymarket sets `extra.clobRewards` (`[{rewardsDailyRate}]` or `[]`), `extra.rewardsMaxSpread`, `extra.rewardsMinSize`; predict.fun sets `extra.rewards.current` (an active reward-window object, or `null`). 404 only if no source has the market at all.

## Query parameters

- `ticker` string, required
- `provider` string, required

## Response `200`

Full market metadata.

- MarketsMetadataResponse
  - `ticker` string, required
  - `provider` string, required
  - `name` string, required
  - `description` string, required
  - `resolution_rules` MarketsResolutionRules, required
    - `primary` string, required
    - `secondary` string, nullable
    - `source` string, nullable
  - `contract` MarketsContractInfo, required
    - `tick_size` number, nullable
    - `min_price` number, nullable
    - `max_price` number, nullable
    - `lot_size` number, nullable
    - `quote_currency` string, nullable
    - `settlement_ts` string, nullable: Only populated for some response paths; null otherwise.
    - `expires_at` string, nullable
  - `images` MarketsImages, required
    - `icon` string, nullable
    - `banner` string, nullable
  - `external_url` string, nullable
  - `condition_id` string, nullable: Only populated for some response paths; null when the response comes from a provider-API fallback.
  - `event_id` string, nullable: Only populated for some response paths.
  - `ctf_neg_risk` boolean, required
  - `extra` object, required: Raw upstream/provider payload, plus router-side enrichment: for polymarket, `clobRewards` ([{rewardsDailyRate}] or []), `rewardsMaxSpread`, `rewardsMinSize`; for predictfun, `rewards.current` (active reward-window object or null).
  - `active` boolean, required: False if the market is delisted/resolved and not tradable.
  - `match_delay_ms` integer, nullable: Polymarket's matching delay in milliseconds, i.e. how long Polymarket holds an order before matching it. Sports markets hold every order for whole seconds (e.g. 1000 or 3000), and the value can change while a market trades, typically at game start; some crypto "Up or Down" markets hold taker orders for 250. When both apply, this is the longer one. 0 means no delay. null for non-Polymarket markets, for Polymarket markets whose delay Kairos has not observed yet, and when the response comes from a provider-API fallback.

## Other responses

- `400`: Invalid/unknown provider, or a downstream `ValueError`.
- `401`: No valid credential presented — missing/invalid API-key headers, or an invalid/expired session token.
- `403`: Authenticated but not permitted. Three distinct causes: the session user is not invited (`Invite required`), the API key lacks the operation's scope, or API-key access to the requested venue is switched off (`API access is disabled for <provider>`). Admin and API-key callers bypass the invite check; session and admin callers bypass scope and venue checks.
- `404`: Market not found in cached metadata or any provider API.
- `422`: Request failed FastAPI parameter validation.
- `429`: Rate limit exceeded for this route's sliding window, keyed on the session `sub` when authenticated and on the trusted client IP otherwise. Honor `Retry-After`. A per-API-key data ceiling (set per credential) rejects with `{"detail": "API key data rate limit exceeded"}` instead of the `error` envelope below.
- `500`: Metadata lookup failed.

---

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