MarketDataService.GetSpotConfig (REST GET /v1/spot/config) returns every spot Asset and
Pair with the rules an order must
meet: price and quantity increments, minimum and maximum sizes, scales for decoding market data,
and the Pair's current trading status. It takes no parameters and needs no authentication.
Read it before you place orders or decode market data, and keep a cached copy current as described in Cache and refresh.
Request
GET https://api.testnet.polyester.com/v1/spot/configPOST https://api.testnet.polyester.com/marketdata.v1.MarketDataService/GetSpotConfig
Content-Type: application/json
{}See Environments and hosts for the host of each environment.
Response
The response holds assets, ordered by Asset code, pairs, ordered by symbol, the snapshot time tsSec, and maxOpenOrdersTotal. This is a BTC-USDT entry captured from REST on 5 November
2026:
{
"symbolId": 1,
"symbol": "BTC-USDT",
"baseAsset": "BTC",
"quoteAsset": "USDT",
"status": "ENABLED",
"tickSize": "0.01",
"stepSize": "0.00000001",
"minQtyBase": "0.00001",
"minNotionalQuote": "5",
"maxOrderNotionalQuote": "5000000",
"maxMarketNotionalQuote": "1000000",
"maxOpenOrdersPerPair": 200,
"baseQuantityScale": 8,
"quoteQuantityScale": 6,
"referencePriceScale": 9,
"allowBuyFeeFromBase": true,
"defaultMarketSlippageBpsBuy": 200,
"defaultMarketSlippageBpsSell": 200,
"maxClientRefDriftBps": 100,
"listingAt": "2026-11-05T12:13:33.827104Z",
"marketdata": { "orderbookPriceBuckets": [0.01, 0.1, 1, 10, 100] }
}The values are environment configuration, not fixed limits. Read them from the response of the environment you trade on. Every field is described in the API reference; the sections below cover how to use them.
REST and ConnectRPC return the same fields. They differ in two places: REST writes the status
without its prefix (ENABLED), while ConnectRPC uses the enum name (PAIR_STATUS_ENABLED); and
ConnectRPC JSON omits fields at their default value, such as a false boolean.
Identify a Pair
| Field | Meaning |
|---|---|
symbol | The Pair's symbol, such as BTC-USDT. REST paths and REST request bodies use it |
symbolId | Stable numeric Pair ID. ConnectRPC requests and every realtime channel name use it |
baseAsset, quoteAsset | Asset codes of the Pair. Look up each Asset's scales in assets by its asset code |
Keep a map from symbolId to symbol and back. Realtime channel names such as public:spot:market:trades:1 and ConnectRPC payloads carry only the symbolId. Symbols are
case-sensitive: btc-usdt is an unknown symbol.
Order rules
All decimal rules are strings, so parse them as exact decimals, never as floating-point numbers.
| Field | Rule |
|---|---|
tickSize | Price increment in quote units. A limit price that is not a multiple is rejected with PRICE_TICK_SIZE |
stepSize | Quantity increment in base units. Other quantities are rejected with QTY_STEP_SIZE |
minQtyBase | Smallest order quantity in base units, otherwise MIN_QTY |
minNotionalQuote | Smallest order value in quote units, otherwise MIN_NOTIONAL |
maxLimitQtyBase | Largest quantity of one limit order. A replace is checked on its new total less the quantity already filled. Above it: MAX_QTY |
maxMarketQtyBase | Largest quantity of one market order. A market order sized by quote amount is checked once converted to base. Above it: MAX_QTY |
maxOrderNotionalQuote | Largest value of one order: quantity times the limit price, or times the protection price for a market order. A buy sized by a quote amount must fit its whole amount. Above it: MAX_NOTIONAL |
maxMarketNotionalQuote | Largest value of one market order: a buy at its protection price, a sell at its reference price before slippage. A market buy sized by a quote amount must fit its whole amount. Above it: MAX_NOTIONAL |
maxOpenOrdersPerPair | Default limit on resting orders one account may hold on the Pair. Past it: MAX_OPEN_ORDERS_PER_PAIR |
maxOpenOrdersTotal | Top-level field. Default limit on resting orders one account may hold across all Pairs. Past it: MAX_OPEN_ORDERS_TOTAL |
The four maximum size fields are absent when the Pair has no such maximum. In the example above,
for instance, BTC-USDT has no maxLimitQtyBase or maxMarketQtyBase. Maximums are compared exactly, with no
rounding.
Only good-till-cancelled and good-till-date orders that have not ended count toward the open-order
limits. Immediate-or-cancel, fill-or-kill, and market orders never count, and a replaced order keeps
its place. An account can have a lower limit of its own; GetSpotConfig returns only the venue
default.
For how quantities, quote budgets, and minimums interact at order entry, see Order sizing. The market order fields defaultMarketSlippageBpsBuy, defaultMarketSlippageBpsSell, and maxClientRefDriftBps are
described in Market order price protection,
and allowBuyFeeFromBase in Fee Assets.
Scales
ConnectRPC and Protobuf payloads carry prices and quantities as scaled integers. REST and WebSocket JSON carry decimal strings and need no scales.
| Field | Where | Decodes |
|---|---|---|
baseQuantityScale | Pair | Base quantities: order book levels, trade quantities, order quantities |
quoteQuantityScale | Pair | Quote amounts, such as 24h quote volume |
referencePriceScale | Pair | Prices of reference candles |
quantityScale | Asset | Asset fields that name this scale, such as supply. Account balances always use a fixed 18 decimals |
marketDataVolumeScale | Asset | Base volume of candles and the market overview |
Prices of trades, order books, and primary candles always use a fixed scale of 9, whatever the quote Asset. quantityDisplayDecimals on an Asset is display guidance only; never use it to decode.
See Scaled integers for the conversion rules.
marketdata.orderbookPriceBuckets suggests price steps for grouping order book levels in a display.
They are display hints in quote units, not trading rules, and order book responses always carry
unaggregated levels.
Trading status
status says which order requests the Pair accepts right now.
| Status | New orders |
|---|---|
ENABLED | Accepted, subject to the listing times below |
DISABLED | Temporarily rejected with PAIR_DISABLED |
CANCEL_ONLY | Rejected with PAIR_CANCEL_ONLY. Cancellations are accepted |
POST_ONLY | Accepted only as post-only limit orders. Others are rejected with PAIR_POST_ONLY |
REDUCE_ONLY | Rejected with PAIR_REDUCE_ONLY |
HALTED | Rejected with MARKET_HALTED. Cancellations are accepted |
When a Pair is halted, Polyester cancels its open orders with the cancel reason MARKET_HALTED.
Fills before the cancel stand. Cancel-all accepts every status, so you can clear your orders on any
Pair; see Cancel all orders.
Listing and delisting times
listingAt and delistingAt are optional RFC 3339 times. They are independent of status: a Pair
can be ENABLED with a listingAt in the future. Before listingAt, new orders are rejected with PAIR_NOT_LISTED_YET. From delistingAt on, new orders are rejected with PAIR_DELISTED. A Pair
without these fields has no scheduled listing or delisting.
To decide whether you can trade a Pair now, check both: status is ENABLED (or POST_ONLY for
post-only orders), listingAt is absent or in the past, and delistingAt is absent or in the
future.
Cache and refresh
Polyester pushes no realtime updates for Pair configuration, so poll it.
Load at startup
Call GetSpotConfig before placing orders or decoding market data. Index pairs by symbolId and
by symbol, and assets by asset.
Refresh on a bounded interval
Re-read the configuration periodically and replace your cached copy as a whole. A response can be
served from a cache for up to 10 seconds, so polling more often than that can return the same
snapshot. A tsSec newer than your copy's means a newer snapshot.
Refresh on a rule rejection
Re-read the configuration when an order is rejected with a Pair rule or status code, such as PRICE_TICK_SIZE, MIN_NOTIONAL, MAX_QTY, PAIR_CANCEL_ONLY, or MARKET_HALTED, and when a symbolId you do not know appears in a stream.
ENABLED.Errors
GetSpotConfig takes no input, so it fails only when the service is unavailable. Retry with
backoff. Read quotas are not published yet; poll on a bounded interval as described in Cache and refresh.