API Reference

Order Statuses & Best Practices

Order Statuses

An order may take on the following statuses during it's lifecycle:

  • PENDING: The order has been acknowledged by the POST /order endpoint (all 201 responses from POST /order will be status PENDING)
  • OPEN: The order is open on the orderbook as a maker order waiting to be matched
  • PARTIAL_FILLED: The order is partially open on the orderbook as a maker order waiting for the remaining quantity to be matched
  • STAND_BY_PENDING: The stop order has been acknowledged by the POST /order endpoint (all 201 responses from POST /order for stop orders will be status STAND_BY_PENDING\)
  • STAND_BY: The stop order is successfully added, waiting to be triggered
  • FILLED: The order is entirely filled
  • CANCELLING: The order cancellation request has been acknowledged by the DELETE /order endpoint
  • CANCELLED: The order has been cancelled. An order of this status will also be accompanied with a cancelReason field.

The above statuses can be grouped into 3 categories: Transient, Intermediate, Terminal

  • Transient: STANDBY_PENDING, PENDING and CANCELLING are transient statuses that last typically only for a few ms.
    • The STAND_BY_PENDING status signifies that the stop order has been accepted by the POST /order endpoint and passes all initial order validations such as valid signature, valid inputs, unique, etc
    • The PENDING status signifies that the order has been accepted by the POST /order endpoint and passes all initial order validations such as valid signature, valid inputs, unique, etc. The order, however, may be cancelled by the orderbook due to a failing condition during matching such as Post Only Failed, TIF Condition Failed, Self Trade, etc. In such a case the order will transition from PENDING directly to CANCELLED with the appropriate cancelReason
    • The CANCELLING status signifies the order has been accepted by the DELETE /order endpoint and passed all initial request validations such as Order Does Not Exist, Order Already Cancelled, etc. Though the request is accepted at this stage, the order cancellation may fail if the order is not found in the orderbook during execution. This is possible if the order has already been sent on-chain for settlement, which due to the nature of interacting with a blockchain is not instantaneous, and thus cannot be found in the orderbook to be cancelled. The order will be moved back to its previous status and a Trade/Fill event can be expected soon which will update the status to PARTIAL_FILLED or FILLED. Note that if part of the order is found in the orderbook (only a part of it has been sent on-chain for settlement), the open quantity will be cancelled. If the order is found in the orderbook it will transition from CANCELLING to CANCELLED with cancelReason=USER_CANCELLED. You can find more details on these edge cases in the section below.
  • Intermediate: STAND_BY,OPEN and PARTIAL_FILLED are intermediate statuses that may transition to a terminal state at any time.
    • The STAND_BY status signifies that the stop order is added on the standby order service waiting to be triggered.
    • The OPEN status signifies that the order is open as a maker order on the orderbook waiting to be matched.
    • The PARTIAL_FILLED status signifies that part of the order is open as a maker order on the orderbook waiting to be matched, the other part has already been filled.
  • Terminal: FILLED and CANCELLED are terminal statuses and may never transition to another status after they reach this point.

On-Chain Trade Settlement Edge Cases

  • It is possible that your marker or taker order gets matched against an order that is rejected on-chain for one of the cancel reasons, in such a case the order is re-queued to be executed by the orderbook again. Though this is very rare, if you wish for your order to never be re-queued please pass in cancelOnRevert=true flag in the POST /order endpoint. Passing in this flag will result in a force cancellation of your order if it is ever matched against an invalid order before it is put into the re-queue pipeline. Note that if your order was invalid, it will be force cancelled with the appropriate reason regardless of flag.
  • Due to the hybrid nature off an off-chain orderbook with on-chain order settlement, there can sometimes be a small delay in a trade/fill event. As such the following cases are possible:
    1. Your OPEN order just got sent on-chain for settlement, but before we received a Trade/FIll event that would transition it to status FILLED, you submit an order cancellation request. In such a case the order will be accepted by the API as status=CANCELLING, the API will then forward the request to the Orderbook which will transition the order back to status=OPEN since it would not find the order in the orderbook (remember it's already been sent on-chain for settlement) with the reason ORDER_NOT_FOUND. Soon after you can expect a Trade/Fill event that will transition the status to FILLED.
    2. Your OPEN order just got partially sent on-chain for settlement, but before we received a Trade/FIll event that would transition it to status PARTIAL_FILLED, you submit an order cancellation request. In such a case the order will be accepted by the API as status=CANCELLING, the API will then forward the request to the Orderbook which will cancel the remaining quantity and transition status to CANCELLED since it was able to cancel the open quantity. Though you've reached a terminal status, CANCELLED, and the order will always remain in this status, you will receive a Trade/Fill event that will partially fill this order.

Note that the above two cases are rare, since all the above typically happens in <1s on an L2 blockchain like Arbitrum, but none the less high frequency traders (HFTs) may experience this on occasion.

Other Transient States of an Order

In the above section, we discussed some settlement edge cases where cancellations fail when an order has departed the orderbook and waiting to be settled on-chain or where you successfully cancel an order but a fill comes since the order had partially left for settlement.

To aid transparency in these scenarios, settlement and re-queue order events inform you on when an order (partially or fully) leaves the orderbook and is awaiting to be filled on-chain or when a settlement reverts and the order is being re-queued.

It's important to note that these are not official order status updates, they are purely an informational stream of events for HFTs that find themselves running into the aforementioned edge cases. A regular user trading via API or UI is unlikely to ever run into these scenarios and as such these socket events do not constitute any official order status update or showcase on the GUI.

If you are listening to these events, here are possible cases you'll encounter:

  1. Your OPEN order got fully matched and sent on-chain for settlement, you'll receive socket emit onUserOrderSentForSettlementUpdate mentioning the quantity of the order sent for settlement. Your order is still in OPEN state until the settlement successfully executes on-chain and the order is transitioned to FILLED. If during this process you submit a cancellation request for this order, it'll be accepted by the API as status=CANCELLING, the API will then forward the request to the orderbook, but the orderbook will not find the order in the orderbook and you'll receive an ORDER_NOT_FOUND error. You should be expecting a Trade/Fill event that will transition the status of the order to FILLED shortly.
  2. Your OPEN order got partially matched and sent on-chain for settlement, you'll receive socket emit onUserOrderSentForSettlementUpdate mentioning the quantity of the order sent for settlement. Your order is still in OPEN state until the settlement successfully executes on-chain and the order is transitioned to PARTIALLY_FILLED. If during this process you submit a cancellation request for this order, it'll be accepted by the API as status=CANCELLING, the API will then forward the request to the orderbook, the orderbook will cancel the remaining quantity and transition status to CANCELLED (since it was able to cancel the open quantity). Though you've reached a terminal status, CANCELLED, and the order will always remain in this status, you should expect to receive a Trade/Fill event that will partially fill this order.
  3. Your OPEN order got matched and sent on-chain for settlement, you'll receive socket emit onUserOrderSentForSettlementUpdate mentioning the quantity of the order sent for settlement. However, there are instances where settlement fails due to various reasons, such as issues with other maker/taker orders in the trade or blockchain unavailability. In such cases, the valid orders are sent back to the orderbook for re-queuing (unless the order has the cancelOnRevert flag set to True). If your order is valid and goes through this process, you will receive a socket emit onUserOrderRequeueUpdate. This emit indicates that your order, which was initially sent for settlement but failed, is now being re-queued to the orderbook. Your order status will remain OPEN through out this process.
  4. Finally, a combination of any of the above can happen as well. Your cancellation attempt in Case 1 can fail but due to reasons in Case 3, your order then may be re-queued implying the order will not transition to status=FILLED and remain as status=OPEN. If you re-attempt cancellation during this time it will succeed or potentially fail if one of Case 1 & 2 happens again. These cases happen rarely given this process is happening in milliseconds and therefore can only impact HFTs, but to avoid these cases all together, please use the cancelOnRevert flag by setting it to True.

It's important to note that during the re-queuing process, there is a possibility of your order getting cancelled. For example, if your order expires during the re-queuing stage, you will receive a cancellation notification via the order updates with the appropriate reason for the cancellation.