The OMS API exposes a thin HTTP layer over the NTS OMS command stream.
oms:commands).ibgatekeeper) consumes the stream and interacts with IBKR Gateway.Base path (examples):
http://localhost:8081https://api.ntsresearch.net/oms (example only)All requests require:
x-api-token: <token>
Tokens are configured via the API_TOKENS environment variable on the server. If no tokens are configured, the service may run in an open “dev” mode, but that is not recommended for production.
{
"secType": "FUT",
"symbol": "ES",
"lastTradeDateOrContractMonth": "202503",
"exchange": "SMART",
"currency": "USD"
}
Fields:
secType (string, default "FUT") – Security type.symbol (string, required) – Root symbol, e.g. "ES", "ZN".lastTradeDateOrContractMonth (string, required) – Contract month (YYYYMM or IB date string).exchange (string, default "SMART") – Execution venue.currency (string, default "USD") – Trade currency.{
"action": "BUY",
"totalQuantity": 1,
"orderType": "MKT",
"lmtPrice": null,
"tif": "DAY",
"outsideRth": true,
"goodAfterTime": null,
"goodTillDate": null
}
Fields:
action – "BUY" or "SELL".totalQuantity – Positive integer quantity.orderType – "MKT" or "LMT".lmtPrice – Required for limit orders.tif – "DAY" or "GTC".outsideRth (bool) – Allow trading outside regular hours.goodAfterTime, goodTillDate – Optional time‑in‑force constraints.Optional wrappers that specify:
These are serialized and carried in the envelope for downstream logic in ibgatekeeper and related runners.
{
"asof": null,
"orders": [ /* list of OrderEnvelope */ ],
"tenant": "nts",
"idem_hint": null,
"dry_run": false
}
Key fields:
orders (list of OrderEnvelope, required) – One or more complete contract + order + optional bracket/runner definitions.tenant (string, default "nts") – Logical tenant for multi‑tenant deployments.idem_hint (string, optional) – Optional idempotency hint.dry_run (bool, default false) – If true, envelope is created but may not be routed further.Returned by most OMS submission endpoints:
{
"status": "enqueued",
"message_id": "1764...",
"idem_key": "oms:..."
}
Fields:
status – "enqueued" or "duplicate".message_id – Redis Stream ID for the command.idem_key – Idempotency key used for this command./healthzSimple health check.
Response:
{"status": "ok", "version": "0.1.0"}
/oms/pingSimple envelope test, useful for connectivity and plumbing checks.
Request:
curl -X POST "$OMS_BASE/oms/ping" -H "Content-Type: application/json" -H "x-api-token: $API_TOKEN" -d '{"echo": "hello-nts"}'
Payload:
{
"echo": "hello-nts"
}
Behavior:
"oms.ping" envelope with the given payload.oms:commands.ibgatekeeper can log and acknowledge the message.Response:
{
"status": "enqueued",
"message_id": "1764...",
"idem_key": "oms:..."
}
/oms/ordersSubmit one or more orders into the OMS command stream.
Request:
curl -X POST "$OMS_BASE/oms/orders" -H "Content-Type: application/json" -H "x-api-token: $API_TOKEN" -d '{
"asof": null,
"orders": [
{
"contract": {
"secType": "FUT",
"symbol": "ES",
"lastTradeDateOrContractMonth": "202503",
"exchange": "SMART",
"currency": "USD"
},
"order": {
"action": "BUY",
"totalQuantity": 1,
"orderType": "MKT",
"tif": "DAY",
"outsideRth": true
},
"bracket": null,
"runner": null,
"refs": { "case": "demo", "strategy": "nts-demo" },
"exit_policy": "bracket"
}
],
"tenant": "nts",
"idem_hint": null,
"dry_run": false
}'
Behavior:
"oms.submit" envelope.oms:commands (via Redis Streams).ibgatekeeper consumes the envelope and translates it into IBKR API calls.Response:
{
"status": "enqueued",
"message_id": "1764...",
"idem_key": "oms:..."
}
Errors:
400 Bad Request – invalid order payload.401 Unauthorized – bad or missing token.503 Service Unavailable – Redis not reachable./oms/flattenSubmit a “flatten positions” command.
Request example:
curl -X POST "$OMS_BASE/oms/flatten" -H "Content-Type: application/json" -H "x-api-token: $API_TOKEN" -d '{
"account": null,
"sec_types": ["FUT"],
"exclude": [],
"cancel_open_first": true,
"wait_seconds": 30
}'
Fields:
account (string, optional) – Target account; null means “default”.sec_types (list of strings) – Security types to flatten, default ["FUT"].exclude (list of strings) – Symbols to skip.cancel_open_first (bool) – Whether to cancel open orders before flattening.wait_seconds (int) – Downstream grace window for cancellations.Behavior:
"oms.flatten" envelope.oms:commands.ibgatekeeper translates this into the appropriate IBKR actions (cancel + close).Response:
{
"status": "enqueued",
"message_id": "1764...",
"idem_key": "oms:..."
}
/ib/events/tailRead a recent tail of parsed IBKR events from ib:events.
Request:
curl -s "$OMS_BASE/ib/events/tail?count=50" -H "x-api-token: $API_TOKEN"
Response:
[
{
"id": "1764...",
"json": {
"event_type": "orderStatus",
"orderId": 1234,
"status": "Filled",
"filled": 1,
"remaining": 0,
"avgFillPrice": 4800.25,
"symbol": "ES"
}
},
{
"id": "...",
"json": { "...": "..." }
}
]
This endpoint is useful for building blotter UIs and for debugging ibgatekeeper behavior.
The OMS API never writes raw order JSON directly to Redis. Every command is:
Wrapped in an envelope:
kind (e.g., "oms.submit", "oms.flatten", "oms.ping")
tenantpayloadts (timestamp)nonceOptional idem_key
Signed using a shared secret (ENVELOPE_SECRET), and the signature is embedded in the envelope.
Written to a Redis Stream (e.g., oms:commands) as a single json field containing the envelope JSON.
Downstream workers (ibgatekeeper, runners, etc.):
json.kind and tenant.This separation lets you add more consumers in the future (e.g., paper trading, audit logging) without changing the OMS API surface.