API

Trading

Place, cancel and close, as signed requests through the relay.

There is no REST endpoint called place-order. Every write is a request you sign yourself and POST /api/prep/relay forwards unchanged, which is what keeps a trading key out of this server entirely. Read Authentication first; this page is only what to put in the envelope.

These act on real funds at real leverage. There is no dry run, no simulation mode and no undo. A filled market order can only be reversed by trading back out at whatever the market is then.

Place an order

Sign POST /v1/order with the body below, then relay it. The body you sign is the exact string you send.

ParameterTypeRequiredNotes
symbolstringyesPERP_<BASE>_USDC.
sidestringyesBUY opens or increases a long, SELL a short.
order_typestringyesLIMIT, MARKET, IOC, FOK, POST_ONLY, ASK or BID.
order_quantitynumbernoSize in the base asset. A multiple of base_tick, worth at least min_notional.
order_pricenumbernoRequired unless order_type is MARKET, ASK or BID — so LIMIT, IOC, FOK and POST_ONLY all need one. A multiple of quote_tick.
order_amountnumbernoQuote-asset notional, as an alternative to order_quantity.
reduce_onlybooleannoWhen true the order can only shrink an existing position.
client_order_idstringnoYour own id, echoed back on the result.
visible_quantitynumbernoHow much of the size rests visibly on the book.
slippagenumbernoTolerance for a market order.
order_tagstringnoFree-form tag carried on the order.
margin_modestringnoCROSS or ISOLATED.
order_quantity is in the base asset, not dollars. On PERP_ETH_USDC a quantity of 0.5 is half an ETH, not fifty cents. Convert a dollar figure with mark_price from /api/prep/markets, round down to base_tick, and check it still clears min_notional. Getting this wrong places an order orders of magnitude too large.
A market buy
POST /api/prep/relay
{
  "method": "POST",
  "path": "/v1/order",
  "body": "{\"symbol\":\"PERP_ETH_USDC\",\"order_type\":\"MARKET\",\"side\":\"BUY\",\"order_quantity\":0.5,\"reduce_only\":false}",
  "auth": {
    "accountId": "0x<64 hex characters>",
    "key": "ed25519:<base58 public key>",
    "signature": "<base64url signature>",
    "timestamp": "1717171717171"
  }
}
Response
{
  "order_id": 883712441,
  "client_order_id": null,
  "order_type": "MARKET",
  "order_price": null,
  "order_quantity": 0.5
}

An error_message field may accompany the result when the request was accepted and the order rejected. Any priced order without order_price is refused, and that is every order_type except MARKET, ASK and BID: IOC, FOK and POST_ONLY need a price exactly as LIMIT does, since they replace LIMIT's resting behaviour rather than modify it.

Never blindly retry a place that failed. Read /v1/positions first: a retry after a partial fill doubles the position.

Close a position

There is no close endpoint. A close is a reduce-only market order on the opposite side, which is exactly what the app and the agent tools do.

  1. 1Sign GET /v1/positions and relay it. Find the row whose symbol matches and whose position_qty is not zero.
  2. 2The side is the opposite of the sign of position_qty: a positive quantity is long, so it closes with SELL.
  3. 3The size is the absolute value of position_qty, or less for a partial close. Never more.
  4. 4Sign POST /v1/order with order_type MARKET and reduce_only true, and relay it.
The body for a full close of a long
{
  "symbol": "PERP_ETH_USDC",
  "order_type": "MARKET",
  "side": "SELL",
  "order_quantity": 0.5,
  "reduce_only": true
}
Closing does not cancel resting orders on that market, and a limit that fills afterwards re-opens exposure. Cancel them separately.

Cancel an order

Sign DELETE /v1/order with order_id and symbol in the query string, and no body. The path you sign includes the query string exactly as you send it.

The relay envelope
{
  "method": "DELETE",
  "path": "/v1/order?order_id=883712441&symbol=PERP_ETH_USDC",
  "auth": { "...": "as above" }
}

The response is the upstream payload for the cancel, scrubbed. This app does not reshape it, so its fields are the upstream's own and are not restated here.

Cancelling removes an instruction, not exposure. An order that already filled cannot be cancelled.

Reading your own account

Signed GETs through the same relay. These are forwarded pass-throughs: the field names are the upstream's, and the ones worth naming are called out below.

PathWhat it answers
/v1/client/infoEquity, free collateral, unsettled profit and the margin ratios.
/v1/client/holdingCollateral held, per asset.
/v1/positionsEvery open position.
/v1/position/{symbol}One position.
/v1/position_historyPositions that have been closed.
/v1/orders?status=INCOMPLETEResting orders. COMPLETED for filled and cancelled.
/v1/order/{id}One order.
/v1/tradesYour own fills. /v1/trade/{id} for one.
/v1/funding_fee/historyFunding paid and received.
/v1/asset/historyDeposits and withdrawals.
/v1/client/statisticsAggregate account statistics.
/v1/liquidationsYour own liquidations.
/v1/volume/user/dailyYour traded volume by day. /v1/volume/user/stats for totals.
  • On /v1/client/info the fields the app reads are total_collateral_value, free_collateral, total_unsettled_pnl, margin_ratio and maintenance_margin_ratio. The gap between the last two is the account's whole cushion.
  • On /v1/positions each row carries position_qty, average_open_price, mark_price, unsettled_pnl and est_liq_price. A positive position_qty is long, a negative one short.
  • est_liq_price is an estimate and moves on its own as funding and fees drain collateral, and under cross margin as other positions lose.

What this API will not do

Not possibleWhy
Withdraw with a trading key aloneA withdrawal carries a second, wallet signature upstream. The path relays; the key does not authorise it.
Set leverage on an orderThere is no leverage field. Size the order against the collateral you mean to commit.
Dry-run an orderThere is no simulation mode and no undo.
Reach an arbitrary upstream pathThe relay allowlist is anchored and closed. Anything outside it is forbidden.
Trade on someone else's behalfThis server holds no key and cannot produce a signature. It can only carry one you made.