Polyester runs separate environments, each with its own hosts, accounts, API keys, and contracts. Nothing carries over between them: create an API key in the environment you connect to, and point your client at that environment's hosts. Testnet is the public environment today; Mainnet is coming soon.
Environments
| Environment | Use it for |
|---|---|
| Testnet | Building and testing an integration before production |
| Mainnet | Production trading. Coming soon |
Each environment runs its own release, so a contract can change when that environment is upgraded. Build against the contracts published for the environment you target, described below, and regenerate your clients when they change.
Hosts
Each environment has two kinds of host: API hosts for REST, ConnectRPC, and the realtime streams, and one trade host for the low-latency trade WebSockets. The global API host is shown here; Testnet also has regional API hosts.
| Host | Testnet |
|---|---|
| API host (global) | api.testnet.polyester.com |
| Trade host | trade.api.testnet.polyester.com |
Every interface uses TLS: https:// for HTTP requests and wss:// for WebSockets.
| Interface | Host | Path |
|---|---|---|
| REST | API host | /v1/... |
| ConnectRPC | API host | /<package>.<Service>/<Method> |
| Realtime WebSocket | API host | /connection/websocket |
| Private WebSocket (your orders) | API host | /v1/ws/private |
| SBE trade WebSocket | Trade host | /ws/trade.sbe |
| Protobuf trade WebSocket | Trade host | /ws/trade.proto |
For example, the spot configuration is GET https://api.testnet.polyester.com/v1/spot/config on
REST and POST https://api.testnet.polyester.com/marketdata.v1.MarketDataService/GetSpotConfig on ConnectRPC. Open the realtime WebSocket at /connection/websocket; Cloudflare can refuse an upgrade at the
host root. Tokens for the
realtime and private WebSockets come from GET /v1/rt/token and GET /v1/rt/subscribe on the API
host; see WebSocket session model.
On Testnet, API clients may be refused with HTTP 403 when they open the private WebSocket while access is being enabled. See Private WebSocket.
Regional API hosts
Besides the global API host, Testnet has regional API hosts that serve the same REST, ConnectRPC, and realtime routes. Use one when you want a fixed region instead of the global entry point.
| Region | Testnet host |
|---|---|
| Tokyo | https://tyo.api.testnet.polyester.com |
| EU West | https://bru.api.testnet.polyester.com |
| US East | https://iad.api.testnet.polyester.com |
| US West | https://pdx.api.testnet.polyester.com |
The trade WebSockets have no regional hosts. Always connect them to the environment's trade host. To choose between the global and a regional host, and to keep connections reliable, see Regions and connectivity.
Contracts per environment
The public contracts for each environment are published in the polyester-proto repository, one branch per
environment. Use the testnet branch for Testnet; Mainnet gets its own branch at launch.
Each branch has a manifest.json at its root. Its paths object names where everything is, and publicDescriptorSha256 fingerprints the compiled descriptor, so a changed value tells you the
contracts changed:
| Path | Contents |
|---|---|
proto | The public .proto files, for ConnectRPC and the Protobuf WebSockets |
descriptor | A compiled descriptor set of those files |
openapi | The OpenAPI documents for REST |
sbe | The SBE schema for the SBE trade WebSocket. Its file name carries the schema version |
docs | Generated API reference data, including the error catalog |
The SDKs are generated from the same contracts. The API reference is built from them too. How changes are announced, and how to update safely, is in API changes and versioning.
Shared conventions
These conventions hold across the REST and ConnectRPC APIs unless an endpoint's reference says otherwise.
Timestamps
A timestamp's field name tells you its form and unit:
| Field form | Value |
|---|---|
createdAt, executedAt, and other *At fields | RFC 3339 date-time strings in UTC on REST, google.protobuf.Timestamp on ConnectRPC |
tsNs, acceptedTsNs, and other *Ns fields | Nanoseconds since the Unix epoch, as a decimal string in JSON |
*Sec fields | Seconds, either since the Unix epoch or as a duration, as the field describes |
*Ms fields | Milliseconds, usually a duration such as retryAfterMs |
Time-range filters on REST, such as startTime and endTime on order history, trades, and candles,
take RFC 3339 timestamps. Transfer history is the exception: its timestampMin and timestampMax filters take microseconds since the Unix epoch, as the GET /v1/transfers reference describes.
Large integers
ConnectRPC's JSON encoding carries every 64-bit integer as a string, and REST does for most fields,
such as IDs, bookSeq, and *Ns timestamps. A few REST and WebSocket JSON fields are plain numbers
instead: the REST order book's ts (Unix milliseconds), the order book WebSocket deltas' bookSeqStart, bookSeqEnd, and ts, and request integers such as newQtyScaled and maxSlippageTicks. The API reference gives each field's type. Parse 64-bit values as 64-bit
integers or exact decimals, never as floating-point numbers.
Pagination
List endpoints page with an opaque cursor. Pass the cursor from the previous response back
unchanged, and stop when it comes back empty. Both REST and ConnectRPC JSON name it pageToken in
the request and nextPageToken in the response; the .proto fields are page_token and next_page_token. A page can hold fewer rows than the limit,
or none, before the end. Time-range and trade-ID cursors are covered in REST getting started.
Identifiers
Orders, accounts, Subaccounts, and other resources have public IDs. REST writes them as short
base58 strings; ConnectRPC carries them as fixed64 numbers. Both forms name the same resource.
See Public IDs.
Prices, quantities, and amounts
REST carries prices, quantities, and amounts as decimal strings, such as "64250.5". ConnectRPC
carries them as scaled integers: price ticks, quantities at the Asset's scale, and 18-decimal *_e18 amounts. Read each field's scale before converting. See Scaled integers.
Errors
Every interface reports a stable error code. See Error responses and Error codes.