API
Binance Spot-shaped, with the changes in decisions.md D-6. The generated OpenAPI document
(/v1/openapi.json, committed at
docs/openapi.json) is the exact contract; this page is the
map. Signing is in auth.md.
Hosts
| env | REST | WebSocket |
|---|---|---|
| prod | https://api.zaar.network/v1 |
wss://api.zaar.network/v1/ws |
| staging | https://api.staging.zaar.network/v1 |
wss://api.staging.zaar.network/v1/ws |
| local | http://127.0.0.1:8080/v1 |
ws://127.0.0.1:8080/v1/ws |
Conventions
- GET and DELETE take query parameters; POST, PUT and PATCH take a JSON body.
- Amounts, prices and quantities are decimal strings
at the asset's precision (
"0.00100000"). Ids are numbers. Times are ms (X-ZAAR-TIME-UNIT: MICROSECONDfor µs is reserved, not yet served). - Enums are
UPPER_SNAKEstrings, as in Binance (LIMIT,GTC,PARTIALLY_FILLED). - Errors: HTTP 4xx/5xx with
{"code": -1121, "msg": "Invalid symbol."}. Codes follow Binance's numbering where the meaning matches (seezaar-api/src/error.rs, published in the docs). - Rate limits: request weight per key and per IP (token buckets
refilled continuously, default 6000 per minute each;
exchangeInfoweighs 20,depth5–250 bylimit, history lists 20–25, most others 1), reported inX-ZAAR-USED-WEIGHT-1M; over the limit → HTTP 429,-1003. - Every response carries
X-ZAAR-VERSION(the build's git sha,devlocally). - Security type of each endpoint:
NONE, or the scope it needs (READ,TRADE, …). Signed endpoints act on the account inX-ZAAR-ACCOUNT; a user key whose user has exactly one account may omit it. - Fee rates and shares are decimal fractions with 6 places
(
"0.001000"= 0.1%). - Ticker endpoints return one object when
symbolis given, else an array of every market. - History endpoints (
trades,historicalTrades,klines,ticker/*,allOrders,myTrades,transfers, closed orders inGET /v1/order) read the SQLite projection. They wait (up to 2 s) for it to include every entry that was durable when the request arrived, so a client reads its own writes.
Endpoints
General and market data (NONE)
GET /v1/ping |
liveness |
GET /v1/time |
server time |
GET /v1/exchangeInfo |
assets, markets, filters, fee schedule |
GET /v1/depth?symbol&limit |
order book |
GET /v1/trades?symbol&limit |
recent trades |
GET /v1/historicalTrades?symbol&fromId&limit |
older trades |
GET /v1/klines?symbol&interval&startTime&endTime&limit |
candles (1m … 1M) |
GET /v1/ticker/24hr, /ticker/price,
/ticker/bookTicker |
tickers |
Trading (TRADE, READ)
POST /v1/order |
place (LIMIT, MARKET,
LIMIT_MAKER); response = Binance FULL +
account |
POST /v1/order/test |
validate parameters, filters and scope without placing |
DELETE /v1/order?symbol&orderId|origClientOrderId |
cancel |
DELETE /v1/openOrders?symbol |
cancel all on a market |
GET /v1/order, /v1/openOrders,
/v1/allOrders |
query orders |
GET /v1/myTrades?symbol |
fills with fees |
Accounts and transfers (READ, TRANSFER) — new vs Binance
GET /v1/accounts |
accounts reachable by the key |
GET /v1/account |
balances (free, locked) of one
account |
POST /v1/transfer |
{toAccount, asset, amount, clientTransferId} |
GET /v1/transfers?asset&startTime&endTime |
transfer history incl. trades and fees |
Org (USERS_MANAGE, KEYS_MANAGE, ORG_ADMIN) — new
POST /v1/org/users, GET /v1/org/users |
users by externalRef |
PATCH /v1/org/users |
enable or disable a user |
POST /v1/org/accounts |
open an account for a user or the org |
PATCH /v1/org/accounts |
freeze, unfreeze or close an account (also NETWORK_ADMIN) |
POST /v1/org/apps, GET /v1/org/apps |
apps |
POST /v1/apiKeys, GET /v1/apiKeys,
DELETE /v1/apiKeys |
keys (public keys only) |
GET /v1/org/fees |
fee share earned |
Admin (NETWORK_ADMIN) — new
POST /v1/admin/orgs |
create org (with its first ORG_ADMIN key) |
PATCH /v1/admin/orgs |
org status, org fee share |
POST /v1/admin/assets,
PATCH /v1/admin/assets |
create asset, change its status |
POST /v1/admin/markets,
PATCH /v1/admin/markets |
create market, change status/fees |
PUT /v1/admin/fees |
network default fee schedule |
POST /v1/admin/mint,
POST /v1/admin/burn |
paper money in and out |
GET /v1/admin/stats |
seq, state hash, counts |
WebSocket /v1/ws
JSON text frames, Binance-style. Requests:
{"id": 1, "method": "SUBSCRIBE", "params": ["btc-usd@trade", "btc-usd@depth", "btc-usd@kline_1m"]}
{"id": 2, "method": "UNSUBSCRIBE", "params": ["btc-usd@trade"]}
{"id": 3, "method": "LIST_SUBSCRIPTIONS"}
{"id": 4, "method": "session.logon", "params": {"apiKey": "...", "timestamp": 0, "signature": "..."}}
{"id": 5, "method": "userDataStream.subscribe", "params": {"account": 7}}Also session.status, session.logout and
userDataStream.unsubscribe {subscriptionId?}. Replies:
{"id", "result"} for the stream methods,
{"id", "status": 200, "result"} for session.*
and userDataStream.*; any error is
{"id", "status", "error": {"code", "msg"}}.
session.logon signs the request payload of auth.md with
METHOD = WS, path = /v1/ws and empty query,
account and body; userDataStream.subscribe needs
READ over the account (decided by the core).
Market streams arrive as
{"stream": "btc-usd@trade", "data": {...}}. Symbols are
lowercase in stream names.
| stream | payload | when |
|---|---|---|
<symbol>@trade |
{e: "trade", E, s, t, p, q, T, m, M} |
every fill |
<symbol>@depth |
{e: "depthUpdate", E, s, U, u, pu, b, a} |
every batch that changed the book |
<symbol>@depth20 |
{lastUpdateId, bids, asks} |
every second |
<symbol>@bookTicker |
{u, s, b, B, a, A} |
when the best bid or ask changes |
<symbol>@kline_<interval> |
{e: "kline", E, s, k: {t, T, s, i, o, c, h, l, v, n, x, q, V, Q}} |
every second while the market trades |
<symbol>@ticker |
{e: "24hrTicker", E, s, p, P, w, c, o, h, l, v, q, O, C, F, L, n} |
every second while the market trades |
Depth sync. Update ids are journal sequence numbers,
so they are not contiguous per market: U/u are
the first/last seq that changed this book in the event and
pu is the u of the previous event for the same
market (as on Binance futures). To keep a local book: open the stream,
fetch GET /v1/depth (its lastUpdateId = L),
drop events with u <= L; the first applied event must
have pu <= L and each later one pu = the
previous u; otherwise refetch.
User stream events arrive as
{"subscriptionId": 0, "event": {...}}, in Binance shapes
plus A (the account id): executionReport
(every order change; x = NEW,
TRADE, CANCELED, EXPIRED,
REJECTED), outboundAccountPosition (balances
touched by a command), balanceUpdate (mint, burn, transfer,
import; signed d) and transfer (ZAAR: the
transfer record for those kinds).
Each connection has a bounded outgoing queue; a client that cannot keep up is disconnected and must reconnect and resync. The server pings every 20 s and closes connections silent for 60 s.
Reserved for v1.1: order placement over WebSocket
(order.place etc.), amend keep-priority, order lists, SBE
binary encoding.