10 KiB
Place Order
Rate limits
- With spot leverage: 600 orders/minute or 10 orders/sec per wallet. (weight=1)
- Without spot leverage: 30 orders/min or 5 orders every 10 seconds per wallet. (weight = 20)
{% hint style="info" %} See more details in API Rate limits. {% endhint %}
Request
{% tabs %} {% tab title="Websocket" %} Connect
WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]
Message
{
"place_order": {
"product_id": 1,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "1000000000000000000",
"amount": "1000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666688",
"appendix": "1"
},
"signature": "0x",
"id": 100
}
}
{% endtab %}
{% tab title="REST" %} POST [GATEWAY_REST_ENDPOINT]/execute
Body
{
"place_order": {
"product_id": 1,
"order": {
"sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
"priceX18": "1000000000000000000",
"amount": "1000000000000000000",
"expiration": "4294967295",
"nonce": "1757062078359666688"
},
"signature": "0x",
"id": 100
}
}
{% endtab %} {% endtabs %}
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| product_id | number | Yes | Id of spot / perp product for which to place order. Use All products query to retrieve all valid product ids. |
| order | object | Yes | Order object, see Signing section for details on each order field. |
| order.sender | string | Yes | Hex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender. |
| order.priceX18 | string | Yes | Price of the order multiplied by 1e18. |
| order.amount | string | Yes | Quantity of the order multiplied by 1e18. |
| order.expiration | string | Yes | A time after which the order should automatically be cancelled, as a timestamp in seconds after the unix epoch. |
| order.nonce | string | Yes | Used to differentiate between the same order multiple times. See Signing section for more details. |
| order.appendix | string | Yes | Encodes various order properties including execution types, isolated positions, TWAP parameters, and trigger types. See order appendix section for more details. |
| signature | string | Yes | Hex string representing hash of the signed order. See Signing section for more details. |
| digest | string | No | Hex string representing a hash of the order. |
| spot_leverage | boolean | No | Indicates whether leverage should be used; when set to false , placing the order fails if the transaction causes a borrow on the subaccount. Defaults to true. |
| id | number | No | An optional id that when provided is returned as part of Fill and OrderUpdate stream events. See subscriptions for more details.NOTE: The client id should not be used to differentiate orders, as it is not included in the order hash (i.e., the order digest). Instead, use the last 20 bits of the order nonce to distinguish between similar orders. For more details, refer to Order Nonce. |
Signing
{% hint style="info" %} See more details and examples in our signing page. {% endhint %}
The solidity typed data struct that needs to be signed is:
struct Order {
bytes32 sender;
int128 priceX18;
int128 amount;
uint64 expiration;
uint64 nonce;
uint128 appendix;
}
sender: a bytes32 sent as a hex string; includes the address and the subaccount identifier
priceX18: an int128 representing the price of the order multiplied by 1e18, sent as a string. For example, a price of 1 USDT0 would be sent as "1000000000000000000"
amount: an int128 representing the quantity of the order multiplied by 1e18, sent as a string. A positive amount means that this is a buy order, and a negative amount means this is a sell order.
expiration: a time after which the order should automatically be cancelled, as a timestamp in seconds after the unix epoch, sent as a string.
Order Nonce
nonce: used to differentiate between the same order multiple times, and a user trying to place an order with the same parameters twice. Sent as a string. Encodes two bit of information:
-
Most significant
44bits encoding the time in milliseconds (arecv_time) after which the order should be ignored by the matching engine -
Least significant
20bits are a random integer used to avoid hash collisionsFor example, to place an order with a random integer of
1000, and a discard time 50 ms from now, we would send a nonce of((timestamp_ms() + 50) << 20) + 1000)
import time
unix_epoch_ms = int(time.time()) * 1000
nonce = ((unix_epoch_ms + 50) << 20) + 1000
{% hint style="warning" %}
Note: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: nonce should be an uint64 for Signing but should be sent as a string in the final payload.
{% endhint %}
Order Appendix
{% hint style="info" %} See more details and examples in our Order Appendix page. {% endhint %}
appendix: is a 128-bit integer that encodes extra order parameters like execution type, isolated margin, and trigger type.
Bit Layout
| value | reserved | trigger | reduce only | order type | isolated | version |
| 64 bits | 50 bits | 2 bits | 1 bit | 2 bits | 1 bit | 8 bits |
| 127..64 | 63..14 | 13..12 | 11 | 10..9 | 8 | 7..0 |
Fields (from LSB to MSB):
- Version (8 bits, 0–7) – protocol version (currently
1) - Isolated (1 bit, 8) – whether the order uses isolated margin
- Order Type (2 bits, 9–10) – 0 = DEFAULT, 1 = IOC, 2 = FOK, 3 = POST_ONLY
0-DEFAULT: Standard limit order behavior1-IOC (Immediate or Cancel): Execute immediately, cancel unfilled portion2-FOK (Fill or Kill): Execute completely or cancel entire order3-POST_ONLY: Only add liquidity, reject if would take liquidity
- Reduce Only (1 bit, 11) – only decreases an existing position.
- Trigger Type (2 bits, 12–13) – 0 = NONE, 1 = PRICE, 2 = TWAP, 3 = TWAP_CUSTOM_AMOUNTS
- Reserved (50 bits, 14–63) – future use
- Value (64 bits, 64–127) – extra data (isolated margin or TWAP parameters)
-
if
triggeris2or3⇒valuerepresents how many times the TWAP order will execute and the maximum acceptable slippage. Encoded as:| times | slippage_x6 | | 32 bits| 32 bits |times: Number of TWAP executions.slippage_x6: Maximum slippage × 1,000,000 (6 decimal precision).
-
if
isolatedis1⇒valuerepresentsmargin_x6(in x6 precision, 6 decimals) to be transferred to the isolated subaccount when the order gets its first match. -
otherwise,
valueis0.
-
Response
Success
{
"status": "success",
"signature": {signature},
"data": {
"digest": {order digest}
},
"request_type": "execute_place_order"
"id": 100
}
Failure
{
"status": "failure",
"signature": {signature},
"error": "{error_msg}",
"error_code": {error_code},
"request_type": "execute_place_order"
}