This reference lists the current HTTP and SSE surfaces. For system behavior and accounting semantics, read Trading Model. For operator workflows, read Admin Guide.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/auth/register |
— | Register a user with { "userName": "..." }, create the default account, and return the first API key |
POST |
/api/auth/keys |
key | Create an additional API key for the current user |
DELETE |
/api/auth/keys/:id |
key | Revoke an API key |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/account |
key | Get the current user's default account |
GET |
/api/account/portfolio |
key | Get balances, open positions, open orders, unrealized PnL, funding totals, and perp risk fields |
GET |
/api/account/timeline |
key | Get the user's unified audit feed |
Portfolio read-model notes:
- position rows may include
symbolNamewhen the market adapter can resolve a human-readable label forsymbol - prediction-market position rows may include
sidewith the resolved outcome label such asYesorNo - order rows in
openOrdersandrecentOrdersmay includesymbolNameandoutcomefor the same reason - responses include a
valuationsummary withstatus,issues, priced/unpriced position counts, and known marked-value/PnL totals - factual positions are preserved even when a quote is unavailable; in that case per-position derived values remain
null totalValueandtotalPnlarenullwhenever valuation is partial instead of silently dropping unpriced positions
Query params:
limit, default pagination behavior from shared schemaoffset
Current timeline event types:
orderorder.cancelledjournalfunding.appliedposition.liquidated
Notes:
- liquidation timeline entries are sourced from the dedicated
liquidationsaudit table - the backing filled liquidation order is hidden from timeline results to avoid duplicate entries
- Polymarket timeline items try to resolve human-readable market names and outcomes
- the timeline record shape is shared with the dashboard through
@unimarket/core
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/orders |
key | Place an order |
GET |
/api/orders |
key | List orders (`view=open |
GET |
/api/orders/:id |
key | Fetch a single order |
DELETE |
/api/orders/:id |
key | Cancel a pending order |
Required fields:
marketreferencesidetypequantityreasoning
Optional fields:
limitPriceleveragereduceOnly
Rules:
reasoningis required for state-changing writesleverageandreduceOnlyare valid only for perp markets- quantity is validated against per-reference trading constraints
- normal market-order execution uses directional executable prices:
buy -> ask,sell -> bid - limit orders remain
pendinguntil the background reconciler fills or cancels them - when
market+symbolfilters require symbol normalization and normalization fails,GET /api/ordersreturns an explicit error instead of an empty result
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/positions |
key | List open positions |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/journal |
key | Create a journal entry |
GET |
/api/journal |
key | List journal entries (limit, offset, optional filters) |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/markets |
key or admin | Discover registered markets, capabilities, browse options, and price-history defaults |
GET |
/api/markets/:market/search |
key or admin | Search market references |
GET |
/api/markets/:market/browse |
key or admin | Browse active market references |
GET |
/api/markets/:market/trading-constraints |
key or admin | Get reference-level quantity and leverage constraints |
GET |
/api/markets/:market/quote |
key or admin | Get one enriched quote |
GET |
/api/markets/:market/quotes |
key or admin | Get enriched quotes in batch |
GET |
/api/markets/:market/orderbook |
key or admin | Get one orderbook |
GET |
/api/markets/:market/orderbooks |
key or admin | Get orderbooks in batch |
GET |
/api/markets/:market/funding |
key or admin | Get one funding rate for funding-capable markets |
GET |
/api/markets/:market/fundings |
key or admin | Get funding rates in batch |
GET |
/api/markets/:market/price-history |
key or admin | Get historical candles, resolved range, and summary metrics |
GET |
/api/markets/:market/resolve |
key or admin | Get settlement or resolution status |
searchrequires a non-emptyqsearchaccepts an optionalsortbrowseis explicit and accepts a market-specificsortstring- browse options and explicit search sort options are discoverable from
GET /api/markets - invalid
sortvalues return400 INVALID_INPUT - adapters may enrich sparse upstream search previews before returning discovery results
- both endpoints return paginated discovery payloads shaped like:
{
"results": [
{
"reference": "btc",
"name": "BTC-PERP",
"price": 94321.1,
"volume": 12003455.2,
"liquidity": 882100.4,
"endDate": null,
"fundingPreview": {
"rate": 0.0001,
"nextFundingAt": "2026-03-16T10:00:00.000Z",
"timestamp": "2026-03-16T09:42:00.000Z",
"direction": "long_pays_short",
"intervalHours": 1,
"annualizedRate": 0.876
},
"metadata": {}
}
],
"hasMore": true
}- discovery results are not required to be execution-ready exchange ids
- adapters normalize the supplied
referencelazily whenquote,orderbook,resolve,price-history, or order placement is called - funding-capable markets may include a structured
fundingPreviewon discovery results when preview data is available annualizedRateis a simple APR reference derived from the market funding cadence, not a compounded yield- Polymarket discovery metadata may include
outcomeTokenIdsaligned withoutcomes, which lets dashboards map outcome buttons likeYesandNoto concrete token references
GET /api/markets returns per-market discovery metadata, including:
capabilitiesbrowseOptionssearchSortOptionspriceHistoryornull
When present, priceHistory includes:
nativeIntervalssupportedIntervalsdefaultIntervalsupportedLookbacksdefaultLookbacksmaxCandlessupportsCustomRangesupportsResampling
Example:
{
"reference": "BTC",
"constraints": {
"minQuantity": 0.00001,
"quantityStep": 0.00001,
"supportsFractional": true,
"maxLeverage": 50
}
}Fallback behavior when a market does not implement custom constraints:
minQuantity = 1quantityStep = 1supportsFractional = falsemaxLeverage = null
Example:
{
"reference": "BTC",
"price": 94321.1,
"bid": 94320.9,
"ask": 94321.3,
"mid": 94321.1,
"spreadAbs": 0.4,
"spreadBps": 0.042408309301,
"timestamp": "2026-03-08T00:00:00.000Z"
}Notes:
priceis the execution-facing reference pricemidfalls back topricewhen either side is missingspreadAbsandspreadBpsarenullwhen both sides are not available- use discovery
fundingPreviewfor shortlist preparation andGET /api/markets/:market/fundingfor an explicit fresh funding read
Example:
{
"reference": "BTC",
"rate": 0.0001,
"nextFundingAt": "2026-03-08T01:00:00.000Z",
"timestamp": "2026-03-08T00:00:00.000Z",
"direction": "long_pays_short",
"intervalHours": 1,
"annualizedRate": 0.876
}Preferred query:
GET /api/markets/:market/price-history?reference=BTC&interval=1h&lookback=7dAdvanced custom range:
GET /api/markets/:market/price-history?reference=BTC&interval=1h&startTime=2026-03-01T00:00:00.000Z&endTime=2026-03-08T00:00:00.000ZRules:
- use
lookbackfor the common case - use
asOfonly to anchor reproducible historical analysis - use either
lookbackorstartTime + endTime - read supported intervals and defaults from
GET /api/marketsbefore requesting candles
Example response shape:
{
"reference": "iran-hormuz",
"interval": "4h",
"resampledFrom": "1h",
"range": {
"mode": "lookback",
"lookback": "30d",
"asOf": "2026-03-08T00:00:00.000Z",
"startTime": "2026-02-06T00:00:00.000Z",
"endTime": "2026-03-08T00:00:00.000Z"
},
"candles": [],
"summary": {
"open": null,
"close": null,
"change": null,
"changePct": null,
"high": null,
"low": null,
"volume": null,
"candleCount": 0
}
}| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/events |
key | Subscribe to the user's SSE event stream |
The SSE stream starts with:
system.ready
Current user-scoped event types:
order.filledorder.cancelledposition.settledfunding.appliedposition.liquidated
Replay is supported through:
Last-Event-ID?since=<event_id>
The structured liquidation event includes:
liquidationIdmarketsymbolsidequantitytriggerPriceexecutionPricetriggerPositionEquitymaintenanceMargingrossPayoutfeeChargednetPayoutcancelledReduceOnlyOrderIdsliquidatedAt
Note:
- timeline and settlement/liquidation audit surfaces still expose internal normalized
symbolfields because accounting is stored against resolved execution identifiers
The full operator workflow is documented in Admin Guide. The main admin-only endpoints are:
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/admin/users/:id/deposit |
Add funds to a user's default account |
POST |
/api/admin/users/:id/withdraw |
Remove funds from a user's default account |
POST |
/api/admin/traders |
Create a dedicated trader user + default account |
GET |
/api/admin/overview |
Get cross-user portfolio and market summary |
GET |
/api/admin/users/:id/portfolio |
Get one user's current balance, positions, open orders, and recent orders |
GET |
/api/admin/users/:id/symbol-trades |
Get one user's recent trades for a specific market symbol |
GET |
/api/admin/users/:id/timeline |
Get one user's unified audit feed |
POST |
/api/admin/users/:id/orders |
Place an order on behalf of a user |
GET |
/api/admin/equity-history |
Get historical equity snapshots by user |
All admin endpoints require Authorization: Bearer <ADMIN_API_KEY>.
Admin read-model notes:
GET /api/admin/overviewis read-only and does not write equity snapshots as a side effectGET /api/admin/equity-historyis backed by the background equity snapshotter workerGET /api/admin/users/:id/portfoliomirrors the user portfolio read-model, including optionalsymbolName, prediction-marketside, and order-leveloutcomelabels when adapters can resolve them- overview and admin portfolio reads expose explicit partial valuation state instead of silently omitting unpriced positions
GET /api/admin/users/:id/symbol-tradesreturns a normalization error when the requested symbol cannot be resolved for that market
Admin order-placement notes:
POST /api/admin/users/:id/ordersaccepts the same payload shape asPOST /api/orders- optional
accountIdmust match the target user's default account Idempotency-Keyreplay protection is supported for retry-safe admin writes
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/health |
— | Health check including API version |
The API loads environment variables from repo root in this order:
.env.local.env
Existing process environment variables keep highest priority.
Relevant runtime settings:
RECONCILE_INTERVAL_MSSETTLE_INTERVAL_MSFUNDING_INTERVAL_MSLIQUIDATION_INTERVAL_MSEQUITY_SNAPSHOT_INTERVAL_MSMAINTENANCE_MARGIN_RATIODEFAULT_TAKER_FEE_RATE${MARKET}_TAKER_FEE_RATESERVE_WEB_DIST