https://staging.zerolatencylabs.com); Environments has the base URLs.
There is no testnet faucet. No self-serve route mints test collateral, and spot deposit
and withdraw are not yet available. On staging, test collateral is provisioned out of
band, so arrange it before Step 3.
Two credential types
Every step uses one of two credentials. Do not confuse them.- Header credential — a header (
X-API-KEY) on a plain JSON request. Used for reads and a few writes. Runs directly in the playground. - Signed body — a
Base64SignedPayloadenvelope ({payload, signature, public_key}) carrying a packed binary body signed with a session key. The playground cannot sign, so these are documentation-only: read the shape, then sign and send from your own client.
| Step | Endpoint | Credential | Playground |
|---|---|---|---|
| 1 | POST /api/v1/auth/accounts | master-key signed body | doc-only |
| 2 | POST /api/v1/api-keys | SessionSig header triple (signed) | doc-only |
| 3 | POST /api/v1/trading/deposit | session-key signed body | doc-only |
| 4 | PUT /api/v1/leverage | X-API-KEY header | usable |
| 5 | POST /api/v1/trading/order/place/limit | session-key signed body | doc-only |
| 6 | GET /api/v1/fills | X-API-KEY header | usable |
Walkthrough
Create an account
POST /api/v1/auth/accounts. The body is a signed payload over a
CreateSecp256k1Account or CreatePasskeyAccount request, signed by your
master key. This one call creates the account and registers an initial session
key, so no separate session call is needed for the first trade.Read success, session_created, and account_id from the CreateAccountResponse
body, not the status code — a 200 can still be a failure.Accounts, subaccounts, and
portfolios covers the account_id,
subaccount_index, and portfolio_index you reference below, and the key
hierarchy behind the master key. Subaccount index 0 and portfolio index 0 are
the defaults created with the account.Mint an API key for reads
POST /api/v1/api-keys. Authenticate with the SessionSig header triple
(X-PUBLIC-KEY, X-SIGNATURE, X-REQUEST-ID) — see
session signatures. The request (CreateApiKeyRequest)
takes account_id, key_name, and an optional subaccount_index (null scopes
the key to the whole account).The response (CreateApiKeyResponse) returns the raw api_key once. Store
it. You will pass it as the X-API-KEY header for the read steps below. For the
full set of read credentials, see read
credentials.Deposit collateral
POST /api/v1/trading/deposit. The body is a signed payload over a DepositCash
request. DepositCash carries the portfolio_id triple and a size.Collateral is USDC. The size field is an integer in centi-cents
(1e-4 USDC), so 1,000 USDC is 10000000. Collateral and
cash covers the cash unit and the deposit,
withdraw, and transfer paths.The response is a RequestAck with a status field. Read it — the request can be
acknowledged or rejected here.There is no deposit faucet on staging, and DepositSpot returns 400 because spot
is not yet available. Test collateral is provisioned out of band.Set leverage (optional)
PUT /api/v1/leverage. This is a plain JSON write authenticated with the
X-API-KEY header, so it runs in the playground.The request (SetLeverageRequest) takes subaccount_index, portfolio_index,
market (for example BTC-PERP), and leverage (an integer multiplier per
market). Leverage is set per portfolio per market. See positions, leverage, and
funding for how leverage relates to margin
requirements.Place a limit order
POST /api/v1/trading/order/place/limit. The body is a signed payload over a
PlaceLimitOrder, signed by your session key.PlaceLimitOrder fields:portfolio_id— the{account_id, subaccount_index, portfolio_index}triple.price— a raw integerPriceOfAtom(the price of one atom, in1e-16 USDC).quantity— a raw signed integer in atoms. The sign is the side: positive is long/buy, negative is short/sell.flags—expiryencodes time-in-force (0= IOC,1= FOK, the maximumu64value = GTC, any other value = a GTT expiry in nanoseconds since the Unix epoch), pluspost_onlyandreduce_only. See orders and time-in-force.asset— the asset id (BTC is0, ETH is1).
100,000,000 atoms per
whole unit, so the price conversion factor is 1e12 / 1e8 = 10,000.price:50,000 USDCis500,000,000centi-cents; times10,000gives5000000000000.quantity:0.5 BTCtimes100,000,000atoms is50000000. Buy, so it stays positive.asset:0(BTC).
expiry: 0 is IOC. For a resting order use the maximum u64 value (GTC).The response is a RequestAck. A rejection — an invalid price or insufficient
margin — comes back as 200 with a rejecting status, so always read the body
(see the error model).Only LIMIT and MARKET orders are placeable. Market orders use
POST /api/v1/trading/order/place/market with PlaceMarketOrder (a signed
quantity, an asset, and a max_slippage_deci_bps; no price). Conditional
orders (stop, take-profit) have no endpoint yet. Self-trade-prevention is accepted
on the wire but not yet enforced.Read the fill
GET /api/v1/fills. A plain JSON read authenticated with the X-API-KEY header
from Step 2, so it runs in the playground. subaccount_index is required;
portfolio_index, limit (1–1000, default 100), and offset are optional.The response is an array of FillResponse. Each fill carries the portfolio_id,
market, side (LONG/SHORT), the request_id that links it to your order,
and quantity, price, and fee as decimal strings in human units.