id is
the market_id you order against.
Rate limits
Requests are limited to 10 per second per IP address; see Rate limits for what a429
looks like, how to retry it and how to stay under the limit.
Base URL
Placing an order and following it
Orders are asynchronous. Before a buy, check that you have the cash for it. Splash adds a fee to the contracts cost and debits both when the order is submitted; a buy without enough cash is accepted and then cancelled without filling. Read your fee settings andmax_trade from GET /account and your cash_available from GET /balance, compute the order’s cost, and send the raw
order only when it fits. The order never carries a fee: Splash computes it. The formulas and a calculator are in
Fees and order cost.
POST /trading/ordersreturns200withorder_status: "pending". That means the order was accepted, not filled: it is queued.- Poll
GET /orders?request_id=<your request_id>until the order’sstatusisexecutedorcancelled. Poll every 500 ms to 1 second for the first few seconds, then every few seconds; keep polling while it readspending. See Rate limits. - While the order is queued, or after it was refused, the poll returns a minimal
{ id, request_id, status, error? }(see PendingOrder). Once the order is recorded it returns the full OrderWithMarket.
time_in_force to "FOK", and the order fills completely at your
price or better, or is cancelled. IOC is coming; until then it is a 400 with
IOC orders are not yet supported.
Order outcomes and retries
Not getting a200 does not mean the order failed. What each answer to POST /trading/orders tells you, and what to do
next:
A spent
request_id stays spent for 24 hours. Polling it reads cancelled with the refusal’s message in error, and
sending it again returns 200 with order_status: "cancelled" and places nothing. Two exceptions to the poll: after a
409 it returns nothing, because the request_id is another account’s; and after a 500, poll before trying again and
follow the order if the poll returns one.
A body that is not valid JSON, or over 3 MB, is refused by the web framework before anything is read, with a 400 or
413 that may not be JSON. Nothing was recorded, so the same request_id is fine once the body is fixed.
A poll of a spent request_id, here after 400 Market is not active:
Idempotency
request_id is required on every order: 1 to 64 characters from A-Z a-z 0-9 _ -. A UUID is ideal.
- One
request_idnever places more than one order. Sending your ownrequest_idagain returns the order it already names (sameorder_id) with its current status, andcancelledif the first request was refused. When to reuse it and when to send a new one: Order outcomes and retries. - Another account’s
request_idis409 DUPLICATE_REQUEST_ID. Use a fresh random value.
Conventions
- No
nullin a response. A value that is unset is omitted. Test for presence. - Timestamps are epoch milliseconds on orders and positions.
- Money is a number in dollars. A price is per contract, between 0 and 1. A price you send is between 0.01 and 0.99.
- Dollar fields are the source of truth. Fills land on half-cents, so do not recompute a cost as price
times quantity; read
fill_cost,costand the other dollar fields. - Pagination. Lists take
limit(1 to 50, default 50) andoffset. - Rate limit. At most 10 requests per second per IP address, whichever key they use. See Rate limits.
- Your data only. Every route acts as the key’s own account.
GET /orders,GET /orders/{id},GET /positions,GET /positions/{id}andGET /transactionsrefuse auser_idquery parameter with a401; the other routes ignore it.
Errors
An error is{ "status": "error", "error": "<CODE>", "message": "<text>" }. error is a string; the codes below
are the ones these routes return today, and a code not listed here should be handled by its HTTP status. Every code
is also on Enumerations. For POST /trading/orders, whether a request_id
can be reused after each error is in Order outcomes and retries.
A
429 Too Many Requests is the rate limit, not one of these codes. It records
nothing: wait and retry the same request, as in Rate limits.
