Understanding Orders Guide

This guide is meant to help users understand how to use Moment's Orders API.

Using the Moment Orders API, a Client can monitor, place, and cancel their orders with Moment. Each order has a unique identifier that will be returned as part of the order object, along with the rest of the fields described below. Once an order is placed, it can be queried using the system-assigned unique ID to check the status. Updates on open orders at Moment will also be sent over the Real-time Orders API, which is the recommended method of maintaining order state.

Glossary

  • Order — The order created via POST /v1/trading/order/.
  • Execution Order (EO) — A discrete set of execution instructions created against an Order (e.g., LOB SOR, Manual RFQ, AutoEx RFQ, External).
  • Allocation — Pre-trade account splits attached to an Order that determine how fills are booked.

Creating Orders

Clients can submit requests to purchase or sell fixed income securities through the POST /v1/trading/order/ endpoint:

POST /v1/trading/order/
{
  "account_id": "eb9e2aaa-f71a-4f51-b5b4-52a6c565dad4",
  "instrument_id": "037833DP2",
  "amount": { "par": 3000.0 },
  "type": "limit",
  "side": "buy",
  "limit_price": 99.5,
  "extended_hours": false
}

After submitting an order request like the one above, the Client receives a unique ID for the order. This ID can then be supplied to the GET /v1/trading/order/{id}/ endpoint to retrieve the corresponding order object. The order object includes both information about the Client’s request (e.g., account ID, limit price, quantity, direction), as well as information about the current state of the request (e.g., filled quantity, filled average price).

Some order fields are immutable and will never change throughout the life of an order: id, isin, cusip, amount, type, side, limit_price, extended_hours.
Other order fields are mutable and will change in response to order events: filled_amount, filled_avg_price, status.

GET /v1/trading/order/mo_V1StGXR8_Z5jdHi6B-myT/
{
  "id": "mo_V1StGXR8_Z5jdHi6B-myT",
  "account_id": "eb9e2aaa-f71a-4f51-b5b4-52a6c565dad4",
  "created_at": "2021-03-16T18:38:01.942282Z",
  "approved_at": "2021-03-16T18:38:01.937734Z",
  "filled_at": null,
  "canceled_at": null,
  "isin": "US037833DP29",
  "cusip": "037833DP2",
  "amount": { "par": 3000.0 },
  "filled_amount": { "par": 1 },
  "filled_avg_price": { "pop": 90, "ytm": 4.6 },
  "type": "limit",
  "side": "buy",
  "limit_price": 99.5,
  "status": "partially_filled",
  "extended_hours": false
}

Executing an Order

When you create an Order, there are three ways it can move into execution:

1) Automated Execution (rules-based)

If your organization has configured an Execution Instruction Ruleset, orders will automatically be routed according to those rules. For example, your rules might direct corporate bonds over 1MM par to RFQ AutoEx, while smaller orders route via Smart Order Routing (SOR).

  • OMS accepts and approves the order.
  • Ruleset proposes protocol + strategy.
  • OMS issues an Execution Order to EMS.
  • You’ll see execution-order events like execution_order_create, followed by trade execution events (fills).

Tip: To stage instead of auto-executing, set "bypass_auto_execution": true on the order request.


2) Manual Execution at Order Creation

Provide execution instructions directly on the order request without relying on rules (e.g., Manual RFQ against a specific quote, or Manual LOB to a venue).

  • OMS accepts the order (pending_execution).
  • OMS issues an Execution Order to EMS based on the instructions you supplied.
  • Execution-order events (execution_order_create/cancel) stream back, and fills update the Order.

3) Manual Execution via Staged Orders

If no rules apply, or if you use "bypass_auto_execution": true, the order stages in pending_execution. From there, create Execution Orders separately using the Execution Order APIs. This lets you split an Order across multiple execution orders or try different protocols sequentially.

  • OMS accepts the order and stages it.

  • No execution occurs until you submit an Execution Order.

  • Post to endpoints such as:

    • POST /v1/trading/order/{id}/execution-order/lob/sor/
    • POST /v1/trading/order/{id}/execution-order/lob/manual/
    • POST /v1/trading/order/{id}/execution-order/rfq/manual/
    • POST /v1/trading/order/{id}/execution-order/rfq/autoex/
    • POST /v1/trading/order/{id}/execution-order/external/

Key Things to Know

  • bypass_auto_execution
    Forces staging even if rules are configured. Use this to prevent rules-driven auto-execution.

  • Manual vs. External trade reporting
    For off-platform trades, use protocol external (via Execution Order APIs) and submit an external trade report so OMS can track, book, and allocate consistently. If you have already booked the trade outside the system and only need to report it for record-keeping, set bypass_trade_booking: true on the external trade report you submit.

  • Fees on orders
    You can pass fees on the order which would override the default fees configured in the system for the risk_group_id

  • Events
    Orders emit top-level lifecycle events (request, approve, reject, cancel, execution).
    Execution Orders emit their own sub-events (execution_order_create, execution_order_cancel).

  • Events coverage window
    The Events API returns events from the last 2 days. For durable state, consume the Real-time Orders API and persist events in your system.


Execution Orders

In addition to submitting Orders, Clients can create Execution Orders on top of staged orders. Execution Orders represent specific execution instructions for how an Order should be worked by Moment’s Execution Management System (EMS).

Execution Orders allow Clients to:

  • Break down an Order into one or more distinct execution strategies.
  • Route via different protocols such as SOR, Manual RFQ, Auto RFQ, or External trade reporting.
  • Cancel and issue new execution requests independently of the Order.

Execution Order prerequisites & limits

  • order status must be pending_execution or partially_filled.

  • You may create multiple execution orders; the sum of their open quantities must not exceed the order’s open quantity.

  • Each request must include a client_execution_order_id (idempotency).

  • Protocol-specific requirements:

    • LOB Manual: include venue_mpid.
    • AutoEx RFQ: include rfq_protocol_parameters, execution_criteria, and exit_criteria (and optionally skip_lob_quotes).
    • External: you may attach an external_trade_report inline or report it later to the EO.

Execution Order Lifecycle

Execution Orders have their own lifecycle and event updates, distinct from the Order. Clients receive real-time updates over the Real-time Orders API.

System events

  • execution_order_request — Acknowledges Moment received the request.
  • execution_order_reject — Request rejected due to validation/state errors.
  • execution_order_cancel_request — Acknowledges a cancel was requested on the execution order.
  • execution_order_cancel_reject — Cancel request rejected.

Order events

  • execution_order_create — Execution order accepted and staged/sent to EMS routing.
  • execution_order_cancel — Execution order canceled successfully.

Block Trading & Pre-Trade Allocations

To submit a block trade, include allocations on the order request. This creates an Allocation object for the order at creation time.

Current behavior: Moment only supports pre-trade allocations. Allocations must be supplied on the initial order request (post-trade allocation entry is not supported).

RIA accounts must use fifo_without_averaging. The averaging
strategies (fifo_with_averaging, pro_rata_with_averaging) require a
principal/averaging trading account to average executions before they are
booked to client accounts. RIAs trade in an agency capacity and must report
the actual street-execution prices and quantities to their custodian (e.g.
Schwab), so each allocation has to match a real executed trade. Because there
is no averaging account to absorb the difference, averaged allocation is not
available to RIAs — only the non-averaging FIFO strategy, which preserves the
true per-trade execution prices, is supported.

How it works

  1. You submit an order with an allocations object (pre-trade).
  2. The system creates an Allocation linked to the Order.
  3. As fills come in, the Allocation is calculated and then submitted to the custodian for booking based on your strategy.
  4. You receive real-time allocation events over the Events/Real-time Orders API.

Example — order with pre-trade allocations

{
  "client_order_id": "01JZ5Q165940HX2Q3SB2EK0CA4",
  "instrument_id": "00033GAB1",
  "limit_price": null,
  "type": "market",
  "extended_hours": true,
  "side": "buy",
  "amount": {
    "type": "par",
    "value": 10000
  },
  "account_id": "",
  "ib_id": "01K4BRMF8MCV09YXYE1TT4S2TB",
  "risk_group_id": "01K4BRMRH4ERKRYFCJKCQYKR26",
  "execution_instructions": [
    {
      "protocol": "limit_order_book",
      "strategy": "smart_order_routing",
      "quantity": {
        "type": "par",
        "value": 10000
      },
      "limit_price": 84.35,
      "suppress_pmp_check": false,
      "all_or_none": true,
      "client_execution_order_id": "01K4BRMZZPD8BD896GB4PC3VF4"
    }
  ],
  "explicit_cancelation_required": true,
  "trader_profile": {
    "user_id": "01K4BRN66KX4977GWNTBKMSKWW",
    "bloomberg_id": "BBG000BLNQ16"
  },
  "custodian_id": "cust_lpl",
  "allocations": {
    "strategy": "fifo_without_averaging",
    "client_allocation_id": "allocation-01K4BRNB4YV87WZV9G5DA2QTT4",
    "account_allocations": [
      {
        "client_account_allocation_id": "allocation-01K4BRNJ2VJJKQ0C6VZWWT734J",
        "account_id": "myaccount",
        "requested_amount": {
          "type": "par",
          "value": 10000
        }
      }
    ]
  },
  "all_or_none": true
}

Real-time allocation events

System events

  • cancel_allocation_request — Request to cancel an allocation.
  • cancel_allocation_reject — Rejection on the cancel request.

Order events

  • allocation_create — Allocation object created for the order.
  • allocation_calculate — Allocation engine computed splits based on executions (returns account_allocations with actual_amount, fill_price, and any linked venue info).
  • allocation_submit — Allocation submitted to the custodian for booking (includes custodian_id).
  • allocation_approve — Allocation approved.
  • allocation_reject — Allocation rejected (code, reason).
  • allocation_fail — Booking/processing failure (code, reason).
  • allocation_cancel — Allocation canceled.

Canceling an allocation

DELETE /v1/trading/allocation/{allocation_id}/

EO Endpoint Cheat Sheet

ActionEndpoint
LOB SOR EOPOST /v1/trading/order/{id}/execution-order/lob/sor/
LOB Manual EOPOST /v1/trading/order/{id}/execution-order/lob/manual/
RFQ Manual EOPOST /v1/trading/order/{id}/execution-order/rfq/manual/
RFQ AutoEx EOPOST /v1/trading/order/{id}/execution-order/rfq/autoex/
External EOPOST /v1/trading/order/{id}/execution-order/external/
Report external tradePOST /v1/trading/order/{id}/execution-order/{execution_order_id}/external/trade-report/
Cancel EODELETE /v1/trading/order/{id}/execution-order/{execution_order_id}/

Order States and Statuses

An order’s status tells API users where the order currently is in its lifecycle. There are seven possible order statuses: pending_approval, pending_review, pending_execution, partially_filled, filled, rejected, and canceled.

Moment considers orders whose statuses are pending_approval, pending_review, pending_execution, or partially_filled to be in the open state, meaning they are actively being processed and their statuses may change. Orders whose statuses are filled, rejected, or canceled are in the closed state, meaning they are no longer being processed and their statuses will not change.

StatusStateDescriptionPossible Next States
pending_approvalopenThe order has been received and is waiting for approval.pending_review
rejected
canceled
pending_execution
pending_reviewopenThe order has been received and is waiting manual approval.rejected
canceled
pending_execution
pending_executionopenThe order has been approved and Moment is attempting to execute the order.partially_filled
filled
canceled
partially_filledopenThe order has been partially filled by one or more executions, and Moment is continuing to attempt to execute the remainder.partially_filled
filled
canceled
filledclosedThe order has been filled. No further updates will occur.None
canceledclosedThe order has been canceled by the client, Moment, or the venue. No further updates will occur.

Note that canceled orders may have been partially filled prior to cancellation.
None
rejectedclosedThe order has been rejected by Moment. No further updates will occur.None

Order Status Descriptions

  • pending_approval — The order has been received by Moment and is awaiting approval. While in this status, no execution activity will take place. The order will transition to pending_execution upon approval, rejected if a reviewer declines it, or canceled if a cancellation request is submitted.

  • pending_review — The order has been received by Moment and is awaiting manual approval. This status occurs when an order is flagged by one or more soft pre-trade controls and requires a human reviewer to explicitly approve or reject it. While in this status, no execution activity will take place. The order will transition to pending_execution upon approval, rejected if a reviewer declines it, or canceled if a cancellation request is submitted.

  • pending_execution — The order has been approved and is staged for execution. Moment is actively attempting to execute the order, or the order is waiting for the client to submit Execution Orders (in the case of staged orders with bypass_auto_execution: true). The order will transition to partially_filled or filled as executions occur, or to canceled if a cancellation is requested.

  • partially_filled — The order has received one or more fills but the full requested amount has not yet been executed. Moment continues to work the remaining quantity. The order will transition to filled once the entire amount is executed, remain partially_filled as additional fills come in, or move to canceled if a cancellation is requested. Note that a canceled order may have partial fills — check filled_amount to determine how much was executed before cancellation.

  • filled — The order has been completely filled. The entire requested amount has been executed and no further updates will occur. This is a terminal (closed) status. The filled_amount and filled_avg_price fields reflect the final execution results.

  • canceled — The order has been canceled by the client, by Moment, or by the trading venue. No further execution activity will occur. This is a terminal (closed) status. A canceled order may have been partially filled prior to cancellation — always check filled_amount to see if any quantity was executed before the order was canceled.

  • rejected — The order has been rejected by Moment. This can happen when a reviewer explicitly rejects a flagged order, when the order fails hard pre-trade controls, or when the order is submitted outside of eligible trading hours. No execution activity will occur. This is a terminal (closed) status.


Order Types

When a Client submits an order, they can choose one of the supported order types. Due to lower liquidity in the bond market as compared with the equity market, most fixed income trading venues do not support market orders.


Limit Order

A limit order is an order to buy or sell at a specified price or better. A buy limit order is executed at the specified limit price or lower (better). A sell limit order is executed at the specified limit price or higher (better). Clients must specify the limit_price when submitting an order.

While a limit order can prevent slippage, it may not be filled for some time—if at all. For a buy limit order, if the market price is within the specified limit price, Clients can expect the order to be filled. If the market price is equivalent to the limit price, the order may or may not be filled; if it cannot immediately execute against resting liquidity, it is deemed non-marketable and will only be filled once a marketable order interacts with it.


Market Order

A market order is an instruction to buy or sell at the best available price. Market orders do not include a limit_price and can be subject to slippage if liquidity is thin.

  • Availability of market orders varies by instrument/venue in fixed income. If a venue does not support market orders for the given instrument, the request may be rejected.
  • Market orders can partially fill; any unfilled remainder will continue to work or be rejected based on venue behavior and time-in-force.
  • Use with care during extended hours or in illiquid securities due to wider spreads.
  • Market orders will only execute within the price controls set up by the executing broker.

Example (if supported):

POST /v1/trading/order/
{
  "account_id": "eb9e2aaa-f71a-4f51-b5b4-52a6c565dad4",
  "instrument_id": "037833DP2",
  "amount": { "par": 3000.0 },
  "type": "market",
  "side": "buy",
  "extended_hours": false
}

All-or-None (AON)

All-or-None is an order constraint, not a separate order type. When AON is set, the instruction is to fill the entire requested amount or none—no partial fills.

You can set all_or_none to true on the order to restrict the order to only have 1 fill. You can also opt to let the order not be all or none & instead enforce the constraint only on the execution orders.

Example (AON on a Manual RFQ Execution Order):

POST /v1/trading/order/{id}/execution-order/rfq/manual/
{
  "client_execution_order_id": "exec-002",
  "amount": { "par": 500000 },
  "all_or_none": true,
  "rfq": {
    "id": "rfq-123",
    "contra_quote_id": "quote-456"
  }
}

Example (AON inside execution instructions on order creation):

POST /v1/trading/order/
{
  "account_id": "eb9e2aaa-f71a-4f51-b5b4-52a6c565dad4",
  "instrument_id": "037833DP2",
  "amount": { "par": 500000 },
  "type": "limit",
  "side": "buy",
  "limit_price": 99.5,
  "execution_instructions": [
    {
      "protocol": "request_for_quote",
      "strategy": "manual",
      "all_or_none": true,
      "rfq": { "id": "rfq-123", "contra_quote_id": "quote-456" }
    }
  ]
}

Review & Release (Flagged Orders)

On order submission, Moment runs your org’s pre-trade controls. If an order fails one or more controls that are marked as soft controls (i.e they have the control remediation set to flag), it is flagged for review and a human is required to explicitly approve or reject it. If all of your controls are set with remediation of reject, then you would not have the case where an order is ever flagged for review.

What you’ll see

  • Order in pending_review.
  • Auto-routing is paused (no Execution Orders are created).
  • You receive an order_updateflagged_for_review event with details.

Example — flagged_for_review event (excerpt):

{
  "msg_type": "order_update",
  "order": { "id": "mo_...", "...": "..." },
  "event": {
    "event_type": "flagged_for_review",
    "time": "2025-01-02T15:04:05Z",
    "order_id": "mo_...",
    "client_order_id": "co-123",
    "failed_controls": [
      { "control_message": "Price outside configured tolerance." },
      { "control_message": "Trader not entitled for this instrument." }
    ]
  },
  "event_id": "evt_..."
}

Approving or Rejecting a flagged order

A system administrator (per your org’s entitlements) must take action on the Order:

  1. Request the action
    When an approval (or rejection) request is submitted, you’ll receive a system_update acknowledging the request.
  • manual_approve_request (acknowledges an approval request)
  • manual_reject_request (acknowledges a rejection request)

Example — manual_approve_request (excerpt):

{
  "msg_type": "system_update",
  "event": {
    "event_type": "manual_approve_request",
    "time": "2025-01-02T15:05:10Z",
    "order_id": "mo_...",
    "manual_approve_id": "ma_01...",
    "client_manual_approve_id": "client-ma-123",
    "annotation": "Approved per desk head"
  },
  "event_id": "evt_..."
}

If the request cannot be accepted (e.g., invalid state or permissions), you’ll receive a failure:

  • manual_approve_fail (with reason)
  • manual_reject_fail (with reason)
  1. Decision & release
    Once an admin completes the review, you’ll receive an order_update:
  • approve — the Order transitions to pending_execution.
  • reject — the Order transitions to rejected and will close immediately.

Orders Submitted Outside of Eligible Trading Hours

Orders not eligible for extended hours submitted after 4:00pm ET will be rejected.


Extended Hours Trading

Clients can submit and fill orders during pre-market and after-hours.

Currently, we support full extended hours:

  • Pre-market: 7:30am – 9:30am ET (Mon–Fri)
  • After-hours: 4:00pm – 5:30pm ET (Mon–Fri)

Note: In live trading, extended hours run 7:30am–5:30pm ET.

Submitting an Extended Hours Eligible Order

To indicate an order is eligible for extended hours trading, supply a boolean parameter named extended_hours on the order request. When this parameter is true, the order is eligible for execution in the pre-market or after-hours. All bonds supported during regular market hours are also supported during extended hours.


Time in Force

All orders submitted via Moment are day orders. A day order is eligible for execution only on the day it is live. By default, the order is valid during Regular Trading Hours (9:30am – 4:00pm ET). If unfilled by 4:00pm ET, it automatically expires. If submitted after the close, it is rejected. However, if marked as eligible for extended hours, the order can also execute during supported extended hours.


Canceling Orders

Clients can request to cancel an open order through the DELETE /v1/trading/order/{id}/ endpoint:

DELETE /v1/trading/order/mo_V1StGXR8_Z5jdHi6B-myT/

When a Client submits a cancellation request for an order, Moment will attempt to cancel any outstanding order tickets on the trading venues. A cancel request will be rejected if the order is closed, nonexistent, or if a cancel request is already pending.

Coupling parent/child cancellations (explicit_cancelation_required)

You can control whether an Order is automatically canceled when its single Execution Order is canceled:

  • explicit_cancelation_required: false (default)
    If the Order has exactly one Execution Order and that Execution Order is canceled, the Order will also be canceled automatically.

  • explicit_cancelation_required: true
    The Order will not auto-cancel when its Execution Order is canceled. You must explicitly cancel the Order via DELETE /v1/trading/order/{id}/ if desired.