> ## Documentation Index
> Fetch the complete documentation index at: https://perps-api.vooi.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Markets

> Identify a market across exchanges and pick the right string to pass to asset-scoped endpoints

A VOOI market is one tradable perpetual on one exchange. Use [`GET /exchange/markets`](/docs/api-reference/exchange/get-available-trading-markets) to discover every market and to learn the fields you pass to every asset-scoped endpoint.

## Market identity

Each row in `/exchange/markets` is uniquely identified by the triple `(exchange, baseSymbol, quoteSymbol)`. That's the canonical key — use it to pin a market client-side, persist a "last selected" choice, or re-resolve a saved selection against a fresh catalog.

Each row also carries a `unifiedSymbol` — the cross-exchange grouping key. It is the alias key (`alias:aapl`) when the instrument trades under different symbols on different venues, and the plain `baseSymbol` otherwise. Group by it to line one instrument up across venues; see [Aliases](#aliases).

The `id` field is a passthrough of the venue's native market id (symbol on Aster, Binance, and Bybit such as `BTCUSDT`, underscore-separated symbol on MEXC such as `BTC_USDT`, encoded asset index on Hyperliquid, market number on Lighter and Robinhood, `BASE-QUOTE` string on Extended such as `BTC-USD`, `BASE-QUOTE.P` string on Ondo such as `BTC-USD.P`). It is unique per exchange but **not a VOOI-owned stable identifier** — venue ids can shift when exchanges rename or reindex contracts. Prefer the triple above for persistence.

## The `asset` query parameter

These endpoints take an `asset` string that must resolve to exactly one market on the given exchange:

* [`GET /exchange/quotes`](/docs/api-reference/exchange/get-quotes-for-markets)
* [`GET /exchange/market-settings`](/docs/api-reference/exchange/get-current-user-settings-for-a-market)
* [`GET /exchange/estimate-slippage`](/docs/api-reference/exchange/get-slippage-for-provided-notional-and-side)
* [`GET /exchange/updates-orderbook`](/docs/api-reference/exchange/subscribe-to-order-book-updates-via-sse)

Three accepted forms:

| Form | Example | Resolves to |
| - | - | - |
| Base symbol | `ETH` | The only market on that exchange with `baseSymbol="ETH"`. 400 if more than one matches. |
| Full pair | `ETHUSDC` | The exact `baseSymbol + quoteSymbol` concatenation. Always unambiguous. |
| Cross-exchange alias | `alias:gold` | The venue-specific commodity pair (see below). |

<Note>
  The alias form (`alias:…`) is resolved only by [`GET /exchange/quotes`](/docs/api-reference/exchange/get-quotes-for-markets) (and as the funding-strategy grouping key). For `/exchange/market-settings`, `/exchange/estimate-slippage`, and `/exchange/updates-orderbook`, pass a resolved venue symbol — the base-symbol or full-pair form.
</Note>

<Note>
  Pass `baseSymbol + quoteSymbol` whenever you already have them from `/exchange/markets`. It never errors and it survives the ambiguity case below. This is what the VOOI Ultra client does.
</Note>

### Ambiguity

`(exchange, baseSymbol)` alone is not guaranteed unique — an exchange may list the same base against multiple quote currencies. On Aster today, `BTC`, `ETH`, and `SOL` each trade against both `USDT` and `USD1`, so passing the bare base on that venue returns:

```text theme={null}
400 Bad Request
Ambiguous asset "BTC" on aster — matches BTC/USD1, BTC/USDT. Use the full pair name to disambiguate.
```

### Aliases

Some instruments trade under different symbols on different venues — gold is `XAUUSDT` on Aster, `XAU` on Lighter and Extended, and `xyz:GOLD` on Hyperliquid. The alias form (`alias:gold`) lets a client refer to the same conceptual market with one string across venues. The namespace covers commodities, US and Asian equities, ETFs and index products, FX, and pre-IPO names, and it moves as venues list new contracts.

You don't need to track the mapping yourself: read **`unifiedSymbol`** off each `/exchange/markets` row. It is the alias key when the instrument is aliased and the plain `baseSymbol` otherwise, so grouping rows by `unifiedSymbol` lines one instrument up across every venue that lists it. `unifiedSymbol` is also the grouping key on [`GET /funding-strategies`](/docs/api-reference/funding-strategies/list-funding-arbitrage-strategies) and the [arbitrage scanner](/docs/arbitrage-scanner).

An alias can resolve to more than one market on the same exchange when a venue lists the same instrument on multiple DEXes — for example `alias:eur` matches both `xyz:EUR` and `mkts:EUR` on Hyperliquid. [`GET /exchange/quotes`](/docs/api-reference/exchange/get-quotes-for-markets) then returns one entry per matching market, not one per exchange.

Aliases are an input convenience for the `asset` parameter; `/exchange/markets` rows always expose the venue-native `baseSymbol` next to `unifiedSymbol`.

## Asset categories

Every market row carries a `category` naming the asset class of the underlying:

| Category | Covers |
| - | - |
| `crypto` | Digital assets, including tokenized-RWA protocol tokens and crypto-native index perps such as `BTCDOM` and `DEFI` |
| `stocks-us` | Equities listed on a US exchange, including foreign companies trading as depositary receipts |
| `stocks-asia` | Equities listed on an Asian exchange and not on a US one — an Asian company with a US listing is `stocks-us` |
| `etf-index` | Equity, commodity, and macro index products and ETFs, including funds whose exposure is a metal or commodity |
| `commodities` | Physical goods priced directly — metals, energy, agricultural and hardware spot indices — including gold-backed tokens |
| `forex` | Currency pairs and the dollar index |
| `pre-ipo` | Private companies traded ahead of listing |

The category belongs to the underlying rather than the venue, so every market sharing a `unifiedSymbol` reports the same one.

[`GET /exchange/markets/categories`](/docs/api-reference/exchange/get-asset-classes-in-use) returns the categories at least one open market currently belongs to, sorted alphabetically. A category is absent when nothing open carries it, so the list is safe to render directly as a filter's option set.

## Quote currencies today

* **Lighter** and **Robinhood** quote every perpetual in **USDC**.
* **Hyperliquid** quotes most perpetuals in **USDC**, including the HIP-3 DEXes it currently surfaces (`xyz:` and `mkts:`). Individual HIP-3 DEXes can pick their own quote currency — always read `quoteSymbol` from the row. See [Hyperliquid HIP-3 DEXes](#hyperliquid-hip-3-dexes) below.
* **Aster** quotes most markets in **USDT**; some top pairs are also listed against **USD1**, Aster's own stablecoin. It does not use USDC.
* **Binance** quotes most markets in **USDT**, with some pairs against **USDC** or **USD1**.
* **Extended** quotes every perpetual in **USD** (`quoteSymbol` is `USD`).
* **Bybit** lists perpetuals against both **USDT** and **USDC**.
* **MEXC** quotes every perpetual in **USDT**.
* **Ondo** quotes every perpetual in **USD**; balances, fees, and funding settle in **USDC**.

When building the full-pair form, read `quoteSymbol` from the `/exchange/markets` row and concatenate — don't hard-code the stablecoin.

## Hyperliquid HIP-3 DEXes

Hyperliquid hosts independent perpetual DEXes under [HIP-3](https://hyperliquid.gitbook.io/hyperliquid-docs/hyperliquid-improvement-proposals-hips/frontier-style-hip-3) alongside its default USDC perp DEX. They list non-crypto perpetuals — equities, commodities, FX, stablecoin pairs — and each DEX picks its own quote currency. VOOI surfaces every HIP-3 market under `exchange=hyperliquid`, prefixing `baseSymbol` with the DEX slug:

| DEX prefix | Operator | Quote | Examples |
| - | - | - | - |
| `xyz:` | [trade.xyz](https://trade.xyz/) | USDC | `xyz:AAPL`, `xyz:GOLD`, `xyz:BRENTOIL` |
| `mkts:` | — | USDC | `mkts:TSLA`, `mkts:SILVER`, `mkts:US500`, `mkts:EUR` |

Filter for them with `exchanges=hyperliquid` like any other Hyperliquid market. Read `quoteSymbol` from the row when you need the venue-side quote — it lines up with the `token` field on the matching [`/exchange/accounts`](/docs/trading-positions#account-balances) row, so funds you hold in a given DEX collateralize positions on that DEX.

Some Hyperliquid markets — most HIP-3 markets in particular — only support isolated margin. They appear in `/exchange/markets` like any other row, but [`POST /exchange/margin-mode`](/docs/api-reference/exchange/set-margin-mode-for-a-market) rejects an attempt to switch them to cross. Read the current mode from [`GET /exchange/market-settings`](/docs/api-reference/exchange/get-current-user-settings-for-a-market) before opening a position there.

## Open interest and 24h change

Two unified fields are easy to mis-read because their conventions differ across venues — VOOI normalizes them so a single client formula works everywhere:

* `openInterest` — USD notional, **one-sided**. Multiply by 2 if you want the two-sided total that some venues publish natively.
* `price24hPercent` — signed percent over the last 24 hours (e.g. `-2.27` means down 2.27%, not `-0.0227`).

`price`, `volume24h`, and `fundingRate` follow the conventions you'd expect — quote-currency price, 24h quote-volume, decimal funding rate. `fundingRate` is normalized to an **hourly** rate on every venue; `fundingInterval` reports how many hours apart the venue actually settles funding (1 on Hyperliquid, 8 on MEXC by default, and so on), and `nextFundingTime` is the next settlement.

`maxLeverage` is the market's ceiling. It's typed as a number, so don't assume it's an integer.

## Trading schedule

Each `/exchange/markets` row carries a `schedule` object describing when the market accepts orders:

| Field | Type | Meaning |
| - | - | - |
| `session` | string | TradingView session string (see below). |
| `timezone` | string | IANA timezone the session is expressed in (e.g. `America/New_York`). |
| `corrections` | string | Optional session adjustments. |
| `sessionHolidays` | string | Optional holiday closures. |

`session` is either `"24x7"` for a round-the-clock market, or a TradingView range of the form `"HHMM-HHMM:DAYS"` — open and close times followed by day codes where `1` is Sunday through `7` is Saturday. For example `"0930-1600:23456"` is 09:30–16:00 on Monday through Friday.

Crypto and perpetual venues report `"24x7"`. Today, only Extended emits a real weekday session — a full-day weekday window (`"0000-0000:23456"`, expressed in `Etc/UTC`) for its `_24_5` symbols. Interpret `schedule` against the current time — applying `corrections` and `sessionHolidays` — to know whether a market is currently tradable; orders sent outside a venue's session are rejected by that venue.

<Note>
  The `open` boolean reflects whether the venue currently lists the market as tradable (delisting, reduce-only, or inactive, depending on the exchange), **not** session hours. Don't use `open` to infer whether a market is closed for the session — read `schedule` for that.
</Note>

## Exchange-specific metadata (`data`)

Each `/exchange/markets` row carries a `data` field with venue-shaped extras the unified shape doesn't cover. Fields are optional and structured differently per exchange — read what you need by `exchange`:

| Exchange | Field | Meaning |
| - | - | - |
| `aster` | `data.stepSize` | Decimal-string lot size. Order quantities must be a multiple of this; round client-side before submitting or the venue rejects the order. |
| `aster` | `data.filters` | Passthrough of the venue's per-symbol filter array. The `MIN_NOTIONAL` entry's `notional` and the `LOT_SIZE` entry's `minQty` define the per-symbol order minimums — see [Minimum order size](/docs/trading-preparing-orders#minimum-order-size). |
| `aster` | `data.brackets` | Per-position risk brackets used for cross-margin maintenance — `notionalFloor`, `notionalCap`, `maintenanceMarginRate`, `cumFastMaintenanceAmount`. |
| `hyperliquid` | `data.marginTiers` | Optional tiered max-leverage / maintenance-margin schedule when the market uses one. |
| `lighter` | `data.maintenanceMarginFraction` | Maintenance-margin fraction for the market. |
| `lighter` | `data.minBaseAmount` | Minimum order size in base units. Orders below it are rejected unless they are `reduceOnly` — see [Minimum order size](/docs/trading-preparing-orders#minimum-order-size). |
| `lighter` | `data.assetType` | `"CRYPTO"` or `"RWA"`. Flags real-world-asset markets (equities, commodities, FX) so a UI can group or label them separately from native crypto perps. |
| `extended` | `data.tradingConfig` | Venue trading configuration for the market. Includes `minOrderSize` (minimum order quantity in base units) and `minOrderSizeChange` (the lot step) — see [Preparing orders](/docs/trading-preparing-orders). |
| `bybit` | `data.minNotionalValue`, `data.minOrderQty`, `data.qtyStep` | Per-market order minimums and the lot step. `data.riskLimitTiers` carries the tiered margin schedule, and `data.maxOrderQty` / `data.maxMarketOrderQty` the per-order caps. |
| `mexc` | `data.minVol`, `data.contractSize`, `data.priceUnit` | MEXC sizes orders in contracts: multiply `minVol` by `contractSize` for the minimum in base units. `data.maintenanceMarginRate` and the `riskIncr*` fields describe the margin schedule. |
| `ondo` | `data.baseIncrement`, `data.quoteIncrement` | Size and price steps. `data.marginInfo` carries the per-position margin brackets and `data.takerFee` the taker fee. |

The shape is typed as `unknown` in the API reference because it's exchange-dependent. Treat anything not listed above as opaque; it may appear, change, or be removed without affecting the unified fields on the same row.

## Persisting "last selected market"

Store `(exchange, baseSymbol, quoteSymbol)` from the selected row. On the next session, re-fetch `/exchange/markets` and look the row up by equality on those three fields. If the row is gone — venues list and delist contracts — fall back to a default. Do **not** persist `id`.

## Funding-strategy endpoints

[`GET /funding-strategies/spread-chart`](/docs/api-reference/funding-strategies/funding-spread-chart-data) charts the spread between two legs; [`GET /funding-strategies/funding-rate-history`](/docs/api-reference/funding-strategies/funding-rate-history-for-a-single-market) returns one market's hourly history. The asset parameters on both accept the same forms as `asset` above — when the market came from `/exchange/markets`, pass `baseSymbol + quoteSymbol`.

<Note>
  The spread-chart reference example shows `longAsset: "BTCUSDT"` and `shortAsset: "BTC"` to illustrate that both the full-pair and bare-base forms are accepted. `BTCUSDT` is a real Aster contract. The bare `"BTC"` form works against Hyperliquid or Lighter (single USDC match) but is **ambiguous on Aster** today — if the other leg is Aster, pass the full pair.
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="Quotes and slippage" icon="calculator" href="/docs/trading-quotes">
    Price a trade on a specific market
  </Card>

  <Card title="Real-time updates" icon="rss" href="/docs/trading-streams">
    Subscribe to the order-book stream for a market
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.