---
title: "Resolve venue-specific identifiers to canonical Kairos market ids"
method: POST
path: "/v1/market-identifiers/resolve"
tags: ["Markets"]
---

# Resolve venue-specific identifiers to canonical Kairos market ids

`POST /v1/market-identifiers/resolve`

## Request

- Base URL: `https://md.kairos.trade`
- URL: `https://md.kairos.trade/v1/market-identifiers/resolve`
- 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`

Maps up to 200 venue-specific identifiers — market-scoped (a venue's market id, ticker, or condition-like identifier) or outcome-scoped (an outcome/token id) — onto Kairos's canonical `market_id` for that provider. Requests are grouped by (provider, scope) for efficient batch resolution. Not cached (`Cache-Control: no-store`).

Rate-limit bucket: LIGHT, but with a distinct cost model from the other batch endpoints — the request is admitted at a base cost of 1 unit, then the service charges the FULL request-item count (`len(requests) - 1` additional units) as a deferred charge immediately after the body is parsed and size-validated, before any per-item validation runs. This means a batch of N requests always costs N light units even if individual items subsequently fail validation (e.g. a bad `scope`) and the call returns 400.

Unresolved identifiers are reported with `found: false` and `market_id: null` rather than causing the whole call to fail.

**Id spaces.** `scope: market` matches the venue's market identity — a Kalshi ticker, a Polymarket Gamma numeric market id, or a `0x…` condition id. `scope: outcome` matches an on-chain outcome/token id only (the decimal ERC1155 string), never a market id; submitting a market id with `scope: outcome` returns `found: false`. Resolution always returns the canonical `market_id`; it never returns outcome token ids. To go from a market discovered via the Data API's `/search/markets` to its outcome tokens, read `token_ids`/`outcomes` on the search result (or call the Data API's `POST /markets/details`), then feed those token ids to `/v1/synthetics` and `/v1/candles`.

The request body is capped at 1 MiB.

## Request body

- MarketIdentifierResolveRequestBody
  - `requests` MarketIdentifierResolveRequestItem[], required
    - `provider` 'kalshi' | 'polymarket' | 'opinion' | 'predictfun' | 'hyperliquid' | 'kalshi_offchain' | 'dome', required
    - `identifier` string, required: Venue-specific identifier to resolve. Must be non-empty after trimming.
    - `scope` 'market' | 'outcome', required: `market` resolves via the venue's market id/ticker/condition-like identifier; `outcome` resolves via an outcome/token id. No other scope values are accepted (case-insensitive on input).

## Response `200`

Per-item resolution results, in request order.

- MarketIdentifierResolveResponse
  - `results` MarketIdentifierResolveResult[], required: Same length and order as the request's `requests` array.
    - `provider` string, required: Provider exactly as submitted in the request (not canonicalized).
    - `identifier` string, required
    - `scope` 'market' | 'outcome', required
    - `found` boolean, required
    - `market_id` string, nullable, required: Canonical Kairos market_id, or null when unresolved.

## Other responses

- `400`: Unreadable/invalid JSON body, empty `requests`, `requests` exceeds 200, an item's `provider` is unknown, an item's `identifier` is empty after trimming, or an item's `scope` is not `market` or `outcome`. Per-item messages include the offending index (e.g. `requests[2].scope must be market or outcome`); the unknown-provider message does not (it reads `unknown provider "…"`). Validation stops at the first bad item.
- `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 upstream metadata cache answered one of the (provider, scope) group lookups with 404. Identifiers that are merely unresolvable come back as `found: false` with a 200.
- `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.
- `500`: Response encoding failed (internal error, not upstream).
- `502`: A (provider, scope) group lookup failed against the metadata cache — an unexpected upstream status, an undecodable body, or a resolved entry missing its `market_id`.
- `503`: `cache_cold` (metadata cache still warming, `Retry-After: 5`), `unavailable` (no metadata cache 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)
