Skip to content
Skip to main content

Order Rejections

When the order engine declines an order, the outcome is HTTP 200 with orderStatus: "Rejected" — never a dedicated rejection HTTP status. The human-readable reason lives in text.

Full integration guide

This page is a quick reference. For polling cadence, WebSocket pushes, code samples, and troubleshooting, see Order rejections in the Equity Trading guide.

Golden rules

  1. Never trust POST /order alone — live routed orders may return PendingNew + text: null before rejecting ~50 ms later.
  2. Always read clientOrderId from the POST response — R118 with route may rewrite the ID with an INVALID suffix.
  3. Poll GET /order/{clientOrderId} and fall back to GET /orders when single-order lookup returns 404.
  4. Never cancel a Rejected order — cancel returns HTTP 200 but overwrites text with R130, masking the real reason.

Where rejection reasons appear

SurfaceUse when
POST /orderImmediate ack; may be PendingNew without text
GET /order/{clientOrderId}Authoritative single-order lookup — poll every 50 ms
GET /ordersFull book; only surface for some R118 + route cases
Portfolio WebSocket OrderReal-time; subscribe before placing orders

Rejection code reference

Common codes on live accounts:

CodeExample textTypical triggerPOST timing
R24R24: Your order cannot have a STOP price of ZeroStop/StopLimit without valid stopPriceAsync
R54R54: Unable to reach the destination RouteInvalid or missing routeAsync
R78R78: Market orders are not allowed at this timeMarket order outside RTH (9:30 AM–4:00 PM ET)Sync outside RTH
R95R95: Cannot have opening buy and sell orders at the same timeOpening long and short on same symbolAsync (~4 ms)
R06R06: This symbol is restricted from trading at this priceLimit far from allowed bandAsync
R114R114: Invalid duplicate UserOrderIdReused clientOrderId in sessionSync
R118R118: Stop price is on wrong side of quoteStop on wrong side of quoteAsync without route; sync + text: null with route
R130R130: Cancel Request Rejected: …Cancel on terminal order (from DELETE, not placement)
R145R145: Negative Price Is Not AllowedNegative limitPrice or stopPriceSync
(none)Rejected: Broker Rejected …Venue declined (no R## prefix)Async
(none)nullRisk check with no surfaced codeSync on POST

Parse R-codes from text:

const code = order.text?.match(/^(R\d+)/)?.[1] ?? null;

Schema errors vs routing rejections

ClassHTTP statusBody
JSON Schema / parse failure400Plain text (Content-Type: text/plain)
Routing / risk rejection200Order JSON with orderStatus: "Rejected"

See Validation errors for the 400 table.

Troubleshooting cheatsheet

SymptomLikely causeFix
POST PendingNew, no error shownAsync rejectionPoll GET /order or use Portfolio WS
POST Rejected + text: null, GET → 404R118 with explicit routeScan GET /orders; do not cancel
Error only after cancelR130 overwrote original textRead rejection before cancel
GET /order 404 onceRegistration raceRetry 1–2 s