Skip to main content

Tradovate API

The /v1/api/tv surface exposes your linked Tradovate accounts through CrossTrade. It is separate from the NinjaTrader /v1/api surface:

PlatformRoute prefixRuntimeWebSocket
Tradovate/v1/api/tvServer-side against your linked Tradovate identity. NT8 can be closed.Not currently available.
NinjaTrader 8/v1/apiThrough the CrossTrade Add-On in a running NT8 desktop instance.Supported.
How the Tradovate docs are organized

Most Tradovate endpoints mirror an existing NinjaTrader endpoint. Those shared endpoints are documented on their existing reference pages, where a Tradovate tab sits beside the NT8 tab (for example POST Place Order, GET All Orders, and POST Close Position).

The pages in this Tradovate section are the endpoints unique to Tradovate, with no NT8 equivalent: link status, cash balances, margin snapshots, contract lookup and suggestions, recent fills, and the exchange list.

The two tables below index the whole surface, shared and Tradovate-only, in one place.

Tradovate reads return account state such as positions, orders, fills, and balances. Mutations such as place, cancel, change, close, flatten, and reverse run server-side through the same validation and controls as a Tradovate webhook signal: field validation, Account Manager kill or closing-only checks, position gates, and Trade Copier fan-out all apply. Because these are direct REST calls rather than inbound webhook alerts, the webhook-only layers do not apply: there is no webhook secret or channel to validate, no Alert History entry, no news lockout, no webhook rate bucket, and no per-account/instrument webhook lock.

GA routing; managed ATM beta

Tradovate-native REST routing, the API Playground, and MCP Tv_* tools are generally available. CrossTrade-exclusive ATM breakeven and profit-triggered trail activation remain beta.

Native Tradovate vs. CrossTrade-exclusive

CapabilityOwner
Market/limit/stop/MIT/trailing orders, OSO/OCO brackets, multibracket targets and stops, continuous ATM trailingTradovate native
Reusable named Tradovate ATM configurationsCrossTrade webhook configuration; REST and MCP use inline atm* fields
Profit-triggered trail activation and durable restart replayCrossTrade-exclusive until conversion, then handed to a native Tradovate trailing stop
Target-fill breakevenCrossTrade-exclusive; Tradovate AutoBracket has no breakeven field
Relative-price conversion, position marks, and managed trigger pricesCalculated by CrossTrade server-side from live market data

CrossTrade does not use Tradovate market-data entitlements for quote-dependent behavior. It also does not fall back to one user's Add-On cache or direct GetQuote. No fresh pricing means fail closed; for a pending managed trail, the native fixed stop remains active.

Prerequisites

  • Link a Tradovate account. Connect at least one Tradovate identity under My Account, Brokers tab. Requests for an unlinked user return 403 tradovate_not_linked.
  • API access on your plan. The same plan gate as /v1/api applies. Requests without it return 401 api_requires_pro.
  • A bearer token. Use the same token as the rest of the CrossTrade API. See Authentication.

Base URL and auth

All paths are under https://app.crosstrade.io. Every request carries a bearer token:

NameValue
Content-Typeapplication/json
AuthorizationBearer <token>

The {account} path segment is the Tradovate account name (for example DEMO12345678), matched case-insensitively.

Response envelope

Most reads return {"success": true, "data": ...}. The accounts snapshot is the exception: it returns its snapshot object directly, including success, accounts, asOf, and counts. Mutations return the dispatcher envelope:

{
"success": true,
"destination": "tradovate",
"api": "place_order",
"account": "DEMO12345678",
"instrument": "MES1!",
"response": { "orderId": 123456789 },
"durationMs": 214
}

Validation and account-lock failures use {"success": false, "error": "<message>"}. Failures after dispatch begins may also include dispatcher context such as destination, api, account, instrument, and durationMs. These failures use a 400 status unless an authentication or rate-limit status below applies.

Read endpoints

Shared endpoints link to their NinjaTrader twin page, which carries a Tradovate section. Tradovate-only endpoints link to their own pages.

MethodPathDescription
GET/v1/api/tv/statusToken and connection status for your Tradovate identities.
GET/v1/api/tv/accountsList your linked Tradovate accounts.
GET/v1/api/tv/accounts/snapshotLive per-account P&L, positions, and working orders in one call.
GET/v1/api/tv/accounts/{account}One account plus a cash-balance snapshot.
GET/v1/api/tv/positionsOpen positions across all linked accounts.
GET/v1/api/tv/accounts/{account}/positionsOpen positions on one account.
GET/v1/api/tv/accounts/{account}/position?instrument=Single net position for one account and instrument. netPos is signed; 0 means flat.
GET/v1/api/tv/ordersEvery order across all linked accounts.
GET/v1/api/tv/accounts/{account}/ordersWorking orders on one account.
GET/v1/api/tv/accounts/{account}/orders/{id}One order by Tradovate order id.
GET/v1/api/tv/accounts/{account}/orders/{id}/statusSlim order status: id, status, action, contract, timestamp.
GET/v1/api/tv/accounts/{account}/orders/{id}/lifecycleOrder audit trail: order, version, commands, and command reports (with reject reasons).
GET/v1/api/tv/fillsRecent fills across linked accounts.
GET/v1/api/tv/fills/order/{orderId}Fills for one Tradovate order id.
GET/v1/api/tv/accounts/{account}/fillsRecent fills for one account's identity.
GET/v1/api/tv/accounts/{account}/watermarksP&L high-water marks tracked by the Account Manager monitor engine.
GET/v1/api/tv/cashbalancesCash-balance snapshots.
GET/v1/api/tv/marginsnapshotsMargin snapshots.
GET/v1/api/tv/contracts/find?name=Resolve a contract by exact symbol.
GET/v1/api/tv/contracts/suggest?text=Contract search suggestions; resolves the active front month.
GET/v1/api/tv/exchangesExchange reference list.

Trading endpoints

MethodPathDescription
POST/v1/api/tv/accounts/{account}/orders/placePlace an order, including native OSO/OCO and multibracket orders plus CrossTrade-exclusive managed ATM enhancements.
POST/v1/api/tv/accounts/{account}/orders/{id}/cancelCancel one order.
PUT/v1/api/tv/accounts/{account}/orders/{id}/changeChange one order. Supports partial changes with required live fields restored before submission. POST is still accepted for backward compatibility.
POST/v1/api/tv/accounts/{account}/orders/{id}/replaceDurably cancel and replace one order on the same account and contract.
POST/v1/api/tv/accounts/{account}/orders/cancelCancel working orders on the account.
POST/v1/api/tv/orders/cancelallCancel all working orders.
POST/v1/api/tv/accounts/{account}/orders/cancel_and_bracketCancel working orders, then protect the current position with a bracket. action is the protected position side. The hyphen form cancel-and-bracket is also accepted.
POST/v1/api/tv/accounts/{account}/orders/flatplaceFlatten the position and clear same-contract working orders, confirm settlement, then place a new order.
POST/v1/api/tv/accounts/{account}/positions/closeClose a position, full or partial by qty or percent.
POST/v1/api/tv/accounts/{account}/positions/flattenFlatten one account.
POST/v1/api/tv/positions/flattenFlatten every linked account.
POST/v1/api/tv/accounts/{account}/positions/reverseReverse the position.
POST/v1/api/tv/accounts/{account}/positions/reversepositionReverse the position (position-scoped variant).

MCP tools

Elite subscribers can call this same surface through the hosted MCP server as Tv_* tools. Reads map to the endpoints above (for example Tv_ListAccounts, Tv_AccountSnapshot, Tv_GetPosition), and trades (for example Tv_PlaceOrder, Tv_ClosePosition, Tv_FlattenEverything) run through the same validation and controls, so Account Manager locks and Trade Copier fan-out apply there too. See Tradovate MCP tools.

Request fields

Mutation bodies use camelCase JSON keys, matching the NinjaTrader REST surface. The command and account come from the path, so a body only needs the trade fields. Common fields:

FieldExampleNotes
instrumentMES1!Symbol. Continuous (MES1!), NT8 expiry (MES 09-26), or Tradovate contract (MESU6) forms are accepted.
actionbuy / sellOrder side.
qty1Quantity. quantity is also accepted.
orderTypemarket / limit / stopRequired for entry endpoints. Stop-limit, MIT, and trailing variants are also supported.
limitPrice5000.25Required for limit orders.
stopPrice4995.00Required for stop orders.
takeProfit5020.00Optional absolute bracket target. REST does not run webhook relative-price preprocessing.
stopLoss4990.00Optional absolute bracket stop. REST does not run webhook relative-price preprocessing.
atmTargets20,40Tradovate native: per-tier target distances, in ticks by default or points with pt.
atmStops15Tradovate native: one stop distance for all tiers or one per tier.
atmQtys1,1Tradovate native: contracts per tier; must sum to qty.
atmTrailfalse,trueTradovate native without a trigger: continuously trail selected tiers from entry.
atmTrailTrigger,30CrossTrade-exclusive: profit distance, based on CrossTrade's own live pricing, that activates selected trailing tiers. Pair with atmTrailOffset. Day entries only.
atmTrailOffset,10CrossTrade-managed activation, native handoff: native trail distance after confirmed conversion.
atmBreakeven1CrossTrade-exclusive: target tier whose fill moves surviving stops to breakeven. Day entries only.
atmBreakevenOffset2CrossTrade-exclusive: ticks or points past entry for the managed breakeven stop.
percent0.5For positions/close, close half. Must be greater than 0 and at most 1.
outOfSyncwaitWith Strategy Sync, wait withholds this request's entry and returns. It never queues the order for later placement.

See Destinations for Tradovate-specific requirements and guarantees. Shared field names do not imply identical broker sequencing.

Mutation safety

  • CANCELREPLACE is owner-fenced and durable. Concurrent operations on the same order are serialized, and staged recovery state is persisted before each broker mutation. The original order must belong to the {account} in the path, and the replacement instrument must resolve to the same exact contract. CrossTrade confirms the leader cancellation and every mapped signal-copier follower cancellation before replacement fan-out. If a cancel or placement outcome is ambiguous, CrossTrade does not resend it and returns reconciliation_required; reconcile the broker orders before starting a different replacement.
  • Partial CHANGE requests restore broker-required fields. When omitted, CrossTrade reads and restores quantity, order type, the limit and/or stop price required by the final order type, and the trailing offset required by trailing orders. Copied followers restore those fields from each follower's own live order version before their modify request.
  • CANCELANDBRACKET protects an existing side. action=buy means the live position being protected is long; action=sell means it is short. It is not the side of the exit orders. A flat position or side mismatch is rejected before cancellation.
  • FLATPLACE fails closed on settlement. The entry is sent only after the same account and contract report a flat position and no nonterminal working orders. A timeout returns an error without placing the entry; mapped followers run their own settlement barrier.

Example: place a market order

POST /v1/api/tv/accounts/DEMO12345678/orders/place

TOKEN="my-secret-token"

curl -X POST "https://app.crosstrade.io/v1/api/tv/accounts/DEMO12345678/orders/place" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"instrument": "MES1!", "action": "buy", "qty": 1, "orderType": "market"}'

A limit order with a bracket looks like this:

curl -X POST "https://app.crosstrade.io/v1/api/tv/accounts/DEMO12345678/orders/place" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"instrument": "MES1!", "action": "buy", "qty": 2, "orderType": "limit", "limitPrice": 5000.25, "takeProfit": 5020.00, "stopLoss": 4990.00}'

A two-tier native multibracket with a CrossTrade-exclusive triggered runner:

curl -X POST "https://app.crosstrade.io/v1/api/tv/accounts/DEMO12345678/orders/place" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"instrument":"MES1!","action":"buy","qty":2,"orderType":"market","tif":"day","atmTargets":"20,40","atmStops":"15","atmQtys":"1,1","atmTrail":"false,true","atmTrailTrigger":",30","atmTrailOffset":",10"}'

Tradovate hosts the entry, targets, fixed stops, and OCO structure. CrossTrade records the highs and lows of its own live pricing and activates the runner only after the 30-tick trigger. The fixed stop remains active until CrossTrade confirms conversion to a native Tradovate trailing stop.

Locks and trade copier

Because mutations flow through the same validation and controls as a webhook signal, two behaviors are shared:

  • Account locks apply. If the Tradovate Account Manager (or a manual switch) has locked the account, a blocked request returns {"success": false, "error": "Signal blocked, kill switch engaged ..."}. A closing-only lock rejects opening orders unless they carry flatten-first semantics.
  • Copiers fan out. If a signal-mode Trade Copier is configured on the account as a leader, an order placed here mirrors to its followers, exactly as a webhook would.

Errors

StatuserrorMeaning
400tradovate_rejectedTradovate rejected the request (invalid price, insufficient funds, and similar). detail carries the broker's reason.
401invalid_bearerMissing or invalid token.
401inactive_subscriptionSubscription is not active.
401api_requires_proYour plan does not include API access.
403tradovate_not_linkedNo linked Tradovate identity on your account.
403endpoint_not_availablePath is not part of the current /v1/api/tv surface.
409account_ambiguousThe account name exists on more than one linked identity. Rename one so every linked account name is unique.
429rate_limitedCrossTrade API request budget exceeded (180 requests/min per user). Includes a Retry-After header and retryAfter body field.
429broker_rate_limitedTradovate's own rate-limit penalty is active on your linked identity. A passthrough of the broker's limit, not a CrossTrade limit. Includes Retry-After and retryAfter.
429egress_limitedResponse egress budget exceeded.
500internal_errorUnexpected server error. Safe to retry once; contact support if it persists.
502tradovate_session_expiredYour Tradovate session expired. Reconnect the account under My Account, Brokers.
502tradovate_unavailableTradovate did not respond or returned a server error. Retry shortly.
503temporarily_disabledThe Tradovate API is paused by a kill switch.

The two 429 codes are deliberately distinct: rate_limited means your integration exceeded CrossTrade's own request budget (see Rate Limiting), while broker_rate_limited means Tradovate itself has imposed a penalty window on your linked identity and CrossTrade is holding requests back until it clears. Both include a Retry-After header with seconds to wait. Mutations blocked by a broker penalty return broker_rate_limited along with the usual dispatcher context fields (destination, api, account, instrument, durationMs).

Limitations

  • Trades placed manually inside the Tradovate app are not seen by this API and are not blocked by account locks. The Account Manager can still flatten after the fact.
  • Enforcement and live data run server-side, so flatten and lock latency is measured in seconds, not milliseconds.
  • Account names use realistic placeholders in this doc (DEMO12345678). Use your own account names.