Skip to main content

POST Place Order

Place an order

POST /v1/api/accounts/{account}/orders/place

Headers

NameValue
Content-Typeapplication/json
AuthorizationBearer <token>

Path Parameters

NameTypeRequiredDescription
accountstringRequiredName of account in NT8

Body

NameTypeRequiredDescription
instrumentstringRequiredName of underlying instrument (e.g., "ES 12-25")
actionstringRequiredBUY, SELL
quantityintRequiredContract quantity of new order
orderTypestringRequiredMARKET, LIMIT, STOPMARKET, STOPLIMIT
timeInForcestringRequiredDAY, GTC
limitPricefloatOptionalLimit price when submitting limit order type
stopPricefloatOptionalStop price when submitting stop order type
ocoIdstringOptionalCreate or append to OCO order by ID
strategystringOptionalATM strategy name if opening with ATM template
orderIdstringOptionalCustom order ID to assign at placement. If provided, this ID can be used to look up or cancel the order later.
requireMarketPositionstringOptionalComma-separated list of position states that must be true for the order to be accepted: "flat", "long", "short". Example: "flat" blocks the order if a position is already open. "flat,long" allows entry from flat or adding to a long. If the condition is not met, a 400 error is returned and no order is placed.
maxPositionsintOptionalMaximum allowed position size after the order is accepted. If the order would exceed this value, the request is rejected.

orderId behavior

The optional orderId body field is a caller-supplied reconciliation ID, not the same field as NinjaTrader's live Order.OrderId. If you provide orderId, CrossTrade stores it inside the NT8 order's UserData XML as AutomatedTradingOrderId so the order can still be found later by your original ID.

NT8, the connected broker, or a prop firm connection has ultimate control over the actual order ID. That ID can change over the lifetime of an order, so CrossTrade stores your custom ID separately from the current NT8 order ID instead of trying to overwrite NT8's own identifier.

The orderId returned by a successful place response is the current NT8-assigned order ID at placement time. It may be different from the custom orderId you sent. For later lookup, cancel, change, replace, or lifecycle calls, you can use either the returned NT8 ID or the custom orderId you supplied.

If you are retrying after a timeout, dropped connection, or ambiguous placement result, generate a unique custom orderId for the intended order, send it with the first request, then query by that same ID before sending another placement. Do not assume a separate duplicate-suppression window beyond this ID-based reconciliation path.

Code Examples

import requests

token = 'my-secret-token'

url = "https://app.crosstrade.io/v1/api/accounts/Sim101/orders/place"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
data = {
"instrument": "MES 12-25",
"action": "BUY",
"orderType": "MARKET",
"quantity": 1,
"timeInForce": "DAY",
"orderId": "my-strategy-entry-001",
# "limitPrice": 5500
# "stopPrice": 0,
# "ocoId": "abc123",
# "strategy": "MyAtmStrategy"
}

try:
response = requests.post(url, headers=headers, json=data)
print(f"Response Code: {response.status_code}, Response Text: {response.text}")
except Exception as e:
print(f"An error occurred: {e}")

Response

{
"orderId": "cb1fc8d4e1a84d29ae38fea964aaac8c",
"success": true
}

In this example, cb1fc8d4e1a84d29ae38fea964aaac8c is the NT8-assigned order ID returned by the add-on. The custom ID my-strategy-entry-001 remains stored in NT8 UserData under AutomatedTradingOrderId and can also be used for subsequent order lookups.

WebSocket API

This request can also be made over the WebSocket API. The account path parameter and request body fields are all passed inside args.

{
"action": "rpc",
"id": "my-request",
"api": "PlaceOrder",
"args": {
"account": "Sim101",
"instrument": "ES 09-26",
"action": "Buy",
"orderType": "Market",
"quantity": 1,
"timeInForce": "Gtc",
"orderId": "my-strategy-entry-001"
}
}