---
title: "Resolve Universe Endpoint"
method: POST
path: "/v1/universe/resolve"
tags: ["universe"]
---

# Resolve Universe Endpoint

`POST /v1/universe/resolve`

## Request

- Base URL: `https://api.usekeel.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.usekeel.io/v1/universe/resolve`
- Auth: none declared

Resolve universe criteria into a concrete symbol list.

## Headers

- `Authorization` string, nullable
- `X-Org-Id` string, nullable

## Request body

- ResolveUniverseRequest
  - `mode` string, required: Resolution mode: manual, category, top_volume
  - `market` string: Market: 'perp' (Hyperliquid perpetuals) is the only supported value and the default; any other is refused with 422 UNSUPPORTED_MARKET.
  - `symbols` string[], nullable: Explicit symbols (manual mode)
  - `categories` string[], nullable: Tag categories (category mode)
  - `top_n` integer, nullable: Number of assets (top_volume mode)
  - `exclusions` string[], nullable: Symbols to exclude
  - `inclusions` string[], nullable: Symbols to force include
  - `lookback` '7d' | '30d' | '90d', nullable: Volume ranking lookback: 7d, 30d, or 90d (default 7d)
  - `volume_quartiles` string[], nullable: Volume quartile filter: q1=top 25%, q2=25-50%, q3=50-75%, q4=bottom 25%
  - `min_trailing_dollar_volume` number, nullable: Dollar-liquidity floor (spec 04 §1): keep assets whose trailing-24h traded dollar volume (Σ trade price × size over 1m bars; there is none before 2025-03-23) as of `as_of` is >= this value (quote units). A threshold applied in every mode, not a top-N.
  - `min_trailing_notional_proxy` number, nullable: DEPRECATED alias of `min_trailing_dollar_volume` — the same floor (traded dollar volume; the name predates that). Send `min_trailing_dollar_volume`; sending both is a 422.
  - `current_resolved` string[], nullable: Current resolved list for diff computation
  - `as_of` string, date-time, nullable: The snapshot instant (timezone-aware ISO-8601). Volume windows end here and listing state is evaluated as of it (Q-0983). Omit for now. Pass the backtest start to resolve the pool as of then.

## Response `200`

Successful Response

- ResolveUniverseResponse
  - `resolved` string[], required
  - `resolved_at` string, required: The instant the resolution is as of — identical to `as_of` (the SQL window ended exactly here), not a stamp taken after the query.
  - `as_of` string, required: The snapshot instant the resolver actually used (ISO-8601 UTC). Echoes the request's as_of, or the pinned now() when omitted.
  - `snapshot_note` string, required: ONE SNAPSHOT label: the resolved list is the pool as of `as_of`, never a historical membership rule. Surface it to the user verbatim.
  - `count` integer, required
  - `max_leverages` object, nullable: Per-symbol venue maxLeverage for the resolved list, from trading.instruments. Clients bake it into the Universe declaration (PortfolioMarginCap's input). None when no symbol has a recorded value; symbols without one are omitted (components apply their conservative default). Optional so older clients can ignore it.
  - `diff` object, nullable
  - `symbol_status` object, nullable: Per-symbol listing class over the union of requested and resolved symbols: active | delisted | hip3 | unknown (hip3 = listed on a Hyperliquid HIP-3 dex; Keel does not support HIP-3 markets yet). Present whenever any symbol was classified.
  - `warnings` string[], nullable: Human-readable advisories: unknown symbols (with did-you-mean), delisted symbols (allowed in backtests; live planners skip them), and top_n under-fill ('venue can supply X of Y'). None when clean.
  - `resolution_note` string, nullable: What this resolution kept and dropped from the symbols the caller named, and why (Q-2283, spec 03 U4) — e.g. 'Resolved 2 of 3 symbols: BTC, ETH. Dropped xyz:AAPL — listed on Hyperliquid (HIP-3); Keel does not support HIP-3 markets yet — support is coming soon.' None when every named symbol is active.
  - `dropped` string[], nullable: Named symbols this resolution dropped (HIP-3 or unknown); their reasons are in resolution_note. None when nothing was dropped.
  - `requested_top_n` integer, nullable: Echo of the requested top_n so clients can detect under-fill (count < requested_top_n) and write top_n down to the achievable pool instead of tripping the STALE_UNIVERSE gate forever.
  - `requested_min_trailing_notional_proxy` number, nullable: Echo of the requested dollar-liquidity floor (spec 04 §1), so a client can show that a declared floor was applied — it is a THRESHOLD on trailing-24h traded dollar volume, independent of the lookback the ranking uses. Carries the floor whichever request field named it (`min_trailing_dollar_volume`, or its deprecated alias); the response field keeps its original name. None when no floor was requested.
  - `pool_size` integer, nullable: Live names ranked before any band was cut — the pool 'Top 25%' is 25% OF. Null when no unlimited ranking ran (a plain top_n that filled its LIMIT never saw past it).
  - `band_size` integer, nullable: Names in the SELECTED quartile bands before top_n caps them — the number that explains an under-filled top_n. Null when no quartile filter was applied.
  - `rankings` object, nullable: Per-RESOLVED-symbol rank and trailing notional from the ranking this resolve used, so a volume filter can be verified by eye. Force-included symbols the ranking never saw are absent. Null in manual mode (nothing is ranked).
  - `supply_before_filters` integer, nullable: Ranked names the venue supplied BEFORE bands, floor, exclusions and inclusions — the only honest input to 'the venue cannot supply top_n'. Measuring under-supply after exclusions ratchets a declared top_n down by one on every resolve (audit 04 U-02).

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/usekeel/apis/keel-api.md) · [All operations](https://skmtc.dev/usekeel/apis/keel-api/llms.txt) · [OpenAPI document](https://skmtc.dev/usekeel/apis/keel-api/revisions/3191ca10b0ab?raw)
