Raw Signed Actions
The low-level wallet flow is a two-step hash-and-submit round trip:
POST /api/v1/trading/actions/hashwith an unsigned payload.- Sign the returned
hashwith the wallet. POST /api/v1/trading/actionswith the returned canonicalpayloadand the walletsignature.
Always sign the canonical payload returned by /actions/hash, not a locally reserialized copy.
Envelope
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 0,
"nonceReservationId": null,
"ts": 1781190000000,
"action": {
"SpotPlaceOrder": {
"marketId": 1,
"side": "Bid",
"price": 1000000,
"qty": 100000,
"timeInForce": "post_only",
"isMarket": false,
"reduceOnly": false
}
}
}
nonce: 0 asks the server to use the current account nonce in the canonical response. If you reserved a nonce range, send the explicit nonce and nonceReservationId.
Submit the signed response payload:
{
"payload": {
"account": "0x1111111111111111111111111111111111111111",
"nonce": 42,
"nonceReservationId": null,
"ts": 1781190000000,
"action": {
"SpotPlaceOrder": {
"marketId": 1,
"side": "Bid",
"price": 1000000,
"qty": 100000,
"timeInForce": "post_only",
"isMarket": false,
"reduceOnly": false,
"expiresAt": null
}
}
},
"signature": {
"scheme": "EcdsaSecp256k1",
"bytes": [1, 2, 3]
}
}
Use Idempotency-Key on submit requests that may be retried.
Field casing
0.1.2 has two canonical action families:
| Family | Canonical fields |
|---|---|
Public place-order envelopes: SpotPlaceOrder, OutcomePlaceOrder | marketId, timeInForce, isMarket, reduceOnly, expiresAt |
Raw advanced envelopes: Cancel, AmendOrder, QuoteReplace, SpotQuoteReplace, PlaceAlgoOrder, PlaceConditionalOrder | market, order_id, new_qty, time_in_force, is_market, reduce_only, expires_at |
The server accepts documented camelCase aliases for advanced fields in 0.1.2 and canonicalizes them back to snake_case. For deterministic client code, prefer the canonical fields shown below.
Spot Place Order
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 0,
"ts": 1781190000000,
"action": {
"SpotPlaceOrder": {
"marketId": 1,
"side": "Bid",
"price": 1000000,
"qty": 100000,
"stpMode": "cancel_maker",
"timeInForce": "post_only",
"isMarket": false,
"reduceOnly": false,
"expiresAt": null
}
}
}
Spot orders do not carry book or outcome.
Prediction Place Order
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 0,
"ts": 1781190000000,
"action": {
"OutcomePlaceOrder": {
"marketId": 10,
"outcome": "YES",
"side": "Bid",
"price": 520000,
"qty": 100000,
"timeInForce": "gtc"
}
}
}
book is still accepted as a deprecated alias for outcome on prediction place orders.
Cancel
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 0,
"ts": 1781190000000,
"action": {
"Cancel": {
"order_id": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
}
}
orderId is accepted as an alias.
Amend Quantity
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 0,
"ts": 1781190000000,
"action": {
"AmendOrder": {
"order_id": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"new_qty": 50000
}
}
}
Current amend semantics only allow quantity reduction while keeping priority. Do not send new_price; use quote replace for repricing.
Spot Quote Replace
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 0,
"ts": 1781190000000,
"action": {
"SpotQuoteReplace": {
"market": 1,
"legs": [
{
"cancel_order_id": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"side": "Bid",
"price": 999900,
"qty": 100000,
"time_in_force": "post_only",
"is_market": false,
"reduce_only": false
},
{
"side": "Ask",
"price": 1000100,
"qty": 100000,
"time_in_force": "post_only"
}
]
}
}
}
Spot quote legs do not carry book. A leg with cancel_order_id and qty: 0 is cancel-only. A leg without cancel_order_id is place-only.
Prediction Quote Replace
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 0,
"ts": 1781190000000,
"action": {
"QuoteReplace": {
"market": 10,
"legs": [
{
"cancel_order_id": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"book": "YES",
"side": "Bid",
"price": 510000,
"qty": 100000,
"time_in_force": "post_only"
},
{
"book": "NO",
"side": "Ask",
"price": 480000,
"qty": 100000,
"time_in_force": "post_only"
}
]
}
}
}
Quote replace is atomic at engine level. If any leg is rejected, the engine rolls back the full group. New child orders are derived from the parent action and leg index; replacing an order creates a new child order and does not preserve the canceled order's queue priority.
Algo Order
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 0,
"ts": 1781190000000,
"action": {
"PlaceAlgoOrder": {
"market": 10,
"book": "YES",
"side": "Bid",
"total_qty": 1000000,
"limit_price": 510000,
"time_in_force": "gtc",
"strategy": {
"kind": "twap",
"slice_qty": 100000,
"interval_ms": 5000
}
}
}
}
Supported strategies are iceberg, twap, and vwap.
Conditional Order
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 0,
"ts": 1781190000000,
"action": {
"PlaceConditionalOrder": {
"market": 10,
"book": "YES",
"side": "Ask",
"qty": 100000,
"limit_price": 700000,
"trigger_price": 690000,
"trigger_direction": "at_or_above",
"conditional_kind": "take_profit",
"reduce_only": true,
"signed_trigger_order": {
"payload": {
"account": "0x1111111111111111111111111111111111111111",
"nonce": 43,
"ts": 1781190000000,
"action": {
"OutcomePlaceOrder": {
"marketId": 10,
"outcome": "YES",
"side": "Ask",
"price": 700000,
"qty": 100000,
"reduceOnly": true
}
}
},
"signature": {
"scheme": "EcdsaSecp256k1",
"bytes": [1, 2, 3]
}
}
}
}
}
The nested signed_trigger_order must already be signed. The outer conditional action controls storage and trigger conditions.