Skip to main content

Orders

Place, cancel, query, and list orders. Inspect your own fills.

Authentication

All endpoints in this page require JWT or API Key:

Authorization: Bearer <JWT>

or

X-API-Key: <key>

Place Order

POST /spot/orders

Request Body

{
"symbol": "DFUSDT",
"side": "buy",
"type": "limit",
"tif": "gtc",
"price": "0.5000",
"quantity": "100",
"quote_quantity": null
}
FieldTypeRequiredNotes
symbolstringYesMarket id from GET /spot/markets.
sidestringYesbuy or sell.
typestringYeslimit or market.
tifstringNogtc (default for limit) / ioc / post_only. Market orders are always IOC.
pricestring / numberlimit onlyMust be a multiple of tick_size.
quantitystring / numberlimit + market sellBase amount. Must be a multiple of lot_size.
quote_quantitystring / numbermarket buy onlyAmount of quote (USDT) to spend. Use this instead of quantity for market buys.

TIF semantics

tifBehavior
gtcGood-Til-Canceled. Resting remainder stays on the book until canceled or fully filled.
iocImmediate-Or-Cancel. Match what you can right now; cancel the rest. Status becomes canceled if any qty remains (filled_qty > 0 indicates partial).
post_onlyLimit-only. If the order would cross the book at placement time, it's rejected with POST_ONLY_REJECT and no fill occurs. Otherwise it rests like a GTC.

Market BUY contract (quote_quantity)

Market buys lock the quote token (USDT) up front. You specify how much you're willing to spend (quote_quantity); the engine walks asks ascending, filling base in lot_size increments until the lock is exhausted. Any unspent quote is refunded after matching.

Market sells use quantity (base / DF) — same as limit sell.

Self-trade prevention

If your incoming order would cross your own resting order, the new order is rejected with SELF_TRADE (DECLINE_TAKER policy). Existing resting orders are untouched.

Response — 200 OK

Inline fills array reports any matches that happened during this request (Binance-style):

{
"id": "9f2a-...-uuid",
"symbol": "DFUSDT",
"side": "buy",
"type": "limit",
"tif": "gtc",
"price": "0.5",
"quantity": "100",
"quote_quantity": null,
"filled_qty": "30",
"avg_fill_price": "0.499",
"status": "partially_filled",
"reject_reason": null,
"created_at": 1778400000,
"updated_at": 1778400000,
"fills": [
{ "trade_id": "...", "price": "0.499", "quantity": "30", "fee": "0", "fee_token": "DF" }
]
}

fee_token is the token the caller received (BUY → base, SELL → quote). MVP fees are 0; the field is populated for forward compatibility.

Status

statusMeaning
openResting on the book (no fills yet).
partially_filledResting on the book with filled_qty > 0.
filledFully filled — terminal.
canceledCanceled by user, IOC remainder, market remainder, or status delist — terminal.
rejectedValidation failed before the engine accepted it (e.g., self-trade) — terminal.
expired(Reserved; not used for spot in MVP.)

Error responses

HTTPerrorWhen
400MARKET_NOT_FOUND, INVALID_TICK, INVALID_LOT, BELOW_MIN_NOTIONAL, INSUFFICIENT_BALANCE, POST_ONLY_REJECT, SELF_TRADE, invalid side/type/tif, quote_quantity required for market buy, quantity required for limit/market sellrequest validation / engine pre-checks
404MARKET_NOT_FOUNDsymbol not in spot_markets
409MARKET_HALTEDmarket in halted state
410MARKET_DELISTEDmarket terminal
503spot trading disabled (engine not started) / ENGINE_BUSY (mpsc full) / ENGINE_RESTARTING (recovery in progress)transient
500DB_ERRORserver fault

Cancel One

DELETE /spot/orders/:id

:id is the order UUID. Cancels iff the order is open or partially_filled and belongs to the caller. Returns the canceled order.

Response — 200 OK

Same shape as a single order returned by GET /spot/orders/:id, with status = "canceled".

Errors

HTTPerror
400invalid id (not a UUID)
403FORBIDDEN (order belongs to another user)
404ORDER_NOT_FOUND (already terminal or doesn't exist)

Cancel All

DELETE /spot/orders?symbol=DFUSDT

Cancels every open / partially_filled order belonging to the caller, optionally scoped to one market. Orders that were already terminal are silently skipped.

Response — 200 OK

{ "canceled": [ { ...order... }, { ...order... } ] }

Get One

GET /spot/orders/:id

Returns one order owned by the caller. 404 ORDER_NOT_FOUND if it doesn't exist or belongs to another user.

{
"id": "9f2a-...", "symbol": "DFUSDT", "side": "buy", "type": "limit", "tif": "gtc",
"price": "0.5", "quantity": "100", "quote_quantity": null,
"filled_qty": "100", "avg_fill_price": "0.499",
"status": "filled", "reject_reason": null,
"created_at": 1778400000, "updated_at": 1778400090
}

List Orders

GET /spot/orders

Query Parameters

ParamTypeDefaultNotes
symbolstring(any)Filter to one market.
statusstring(any)open / partially_filled / filled / canceled / rejected / expired.
startnumber (unix seconds)(any)created_at >= start.
endnumber (unix seconds)(any)created_at <= end.
limitnumber501–200; clamped server-side.

Response — 200 OK: array of order objects, newest first.

Tip: to get only currently-open orders, use GET /spot/orders?status=open (or status=partially_filled); both are non-terminal.


My Trades (Fills)

Every fill the caller participated in — as either maker or taker.

GET /spot/trades/me

Query Parameters

ParamTypeDefaultNotes
symbolstring(any)
start / endnumber (unix seconds)(any)
limitnumber501–200.

Response — 200 OK

[
{
"trade_id": "...",
"symbol": "DFUSDT",
"side": "buy",
"price": "0.499",
"quantity": "30",
"fee": "0",
"fee_token": "DF",
"role": "taker",
"order_id": "9f2a-...",
"ts": 1778400090
}
]
FieldNotes
sideThe caller's side at this fill (BUY/SELL), not the global taker side.
fee / fee_tokenFee paid by the caller, in the token they received.
rolemaker or taker.
order_idThe caller's order id involved in this fill.
tsUnix seconds.

Code Example

End-to-end: place a buy, watch it fill, list resulting trades.

import requests, time

BASE = "https://api-sepolia.p99.world/api/v1"
JWT = "your_jwt_token"
H = {"Authorization": f"Bearer {JWT}", "Content-Type": "application/json"}

# Place a GTC limit buy
order = requests.post(f"{BASE}/spot/orders", headers=H, json={
"symbol": "DFUSDT", "side": "buy", "type": "limit", "tif": "gtc",
"price": "0.5", "quantity": "100"
}).json()
print(order["status"], order["filled_qty"], "/", order["quantity"])

# Poll until terminal
oid = order["id"]
while True:
o = requests.get(f"{BASE}/spot/orders/{oid}", headers=H).json()
if o["status"] in ("filled", "canceled", "rejected"):
break
time.sleep(1)

# Inspect fills
fills = requests.get(f"{BASE}/spot/trades/me?symbol=DFUSDT&limit=10", headers=H).json()
for f in fills:
print(f" {f['role']:5} {f['side']:4} {f['quantity']:>8} @ {f['price']}")