Authentication & Access
Authentication & Access
Before a client can reach a protected resource, it must obtain an access token. Your client then sends that token on every request using the Bearer authentication scheme. You can get a token by exchanging your credentials directly, by using a social login, or by delegating authentication to OAuth.
For runnable walkthroughs, see the JavaScript example project, the C# API and WebSocket guide, the OAuth example, and the API FAQ and code samples.
Servers
The API is split across hostnames by the service each one provides. Use the host that corresponds to what you need:
Code examples in these docs default to the Demo host so you can test safely. Swap in live.tradovateapi.com for Live. In the API Reference, use the environment selector to switch the playground and generated snippets between Demo and Live.
The API is a relaxed REST API: it accepts either GET or POST for most endpoints rather than enforcing a method. As a rule of thumb, send a POST when the request carries a JSON body and a GET when it doesn’t. All responses are returned in JSON.
Access Tokens
To request a token, exchange your credentials with the accessTokenRequest operation. The response includes the token and an expirationTime — the token stays valid until then.
A successful response looks like this:
Token Lifetime and Sessions
An access token lasts about 90 minutes — the exact moment is in the response’s expirationTime field. To keep a long-running application connected, extend the session by calling renewAccessToken about 15 minutes before the token expires, rather than requesting a brand-new token. Renewing keeps your existing session alive; repeatedly calling accessTokenRequest starts new sessions.
You’re limited to two concurrent sessions per user. When a third session starts, the oldest is closed — which can drop dependent services that share a token. To avoid this:
- Use a dedicated API user that isn’t also logging in to the
.tradovate.comwebsites. - Centralize token issuance in one service and distribute the same valid token to the services that depend on it.
Two-Factor Authentication
To enable two-factor authentication for your application, supply three additional fields in the access token request body:
deviceIdis a string of up to 64 characters that uniquely and permanently identifies the physical device. Supplying this value is your responsibility — there’s no built-in device-identification solution. For example, you can use the DeviceId package for C#, or a package like device-uuid for JavaScript.cidis a client app ID provided to you.secis a secret (or API key) provided to you. Keep this key out of public access — for example, don’t commit the file that holds it to a public repository.
Unlike cid, the appId and appVersion fields are free-form identifiers that can be displayed to end users in the trader application to show which apps are connected.
Use two-factor authentication. Your account — or your client’s — represents real money and identity, and two-factor authentication is an industry standard in financial technology. Don’t take risks with your clients’ credentials.
OAuth
If your application authenticates other users, it can delegate authentication to NinjaTrader via OAuth instead of handling their credentials directly. See OAuth Integration for the authorization-code flow.
Using Your Access Token
To reach the API’s endpoints, follow the Bearer authentication scheme by setting the Authorization header on each request:
Social logins aren’t currently allowed for customers with Live accounts.
Streaming via WebSocket
WebSockets let you open an interactive session so you can receive and respond to data in real time without polling. The protocol uses the same request semantics as the REST API, adapted to the JSON format the standard WebSocket protocol expects. See Real-Time Data via WebSocket for the full protocol.
Request Rate Limits and Time Penalties
To protect the service, request rates are limited and time penalties are imposed when certain thresholds are crossed. There are limits on the hour, minute, and second intervals. When a limit is reached, the server stops handling requests for a period and responds with HTTP 429, Too Many Requests. The limits are generally high enough that normal operations won’t reach them.
Operations known to be called infrequently — such as requesting an access token, signing up for an account, changing a password, or changing contact information — carry tighter constraints. When one of these limits is reached, the server issues a time-penalty response: a JSON object with p-ticket and p-time fields. This means the request wasn’t handled and a time penalty was imposed. The client can retry after p-time seconds, including p-ticket as an additional parameter in the request body.
The response may also include a p-captcha field. When it’s true, the failed operation can’t be retried from a third-party application, and you should alert users to try again in about an hour. This can happen, for example, after too many authentication requests with bad credentials.
For more on rate limits, see the API FAQ.
Connection Limits
There’s a limit of one simultaneous client connection per customer. Additional simultaneous connections are supported by subscription — see the trader application’s connection settings for allowances and pricing. When a customer reaches their connection limit, the server disconnects the oldest connections.
Account Risk Status
Accounts that fall below a set of health criteria may be auto-liquidated. You can review the full liquidation policy for details. The easiest way to retrieve an account’s current liquidation status is the accountRiskStatus/list operation, which returns the calling account’s status. The response includes the current status as adminAction, timestamps for the last auto-liquidation period and review time, a reason code for the action taken, and a counter tracking how many times the account has been auto-liquidated.
To help avoid auto-liquidation, the API exposes the same risk-management services available in the trader application. See the Risks endpoints in the API Reference. Some of the ways you can limit your risk include:
- Position limits (how much you can trade).
- Product limitations (what you can trade).
- Daily and weekly loss limits.
- Trailing max drawdown.
You can query your current risk limits with the userAccountPositionLimit/deps or userAccountPositionLimit/ldeps operations, supplying your account ID as a query parameter. Each returns a list of UserAccountPositionLimit entities — note their IDs, since you’ll use them to read the paired parameters.
Your account ID is the integer entity ID, not the LIVE12345 or DEMO12345 string. Retrieve it from the account/list operation — the id field is the real entity ID.
To read the related risk-parameter entities (the actual values set by risk limits), use the userAccountRiskParameter/deps operation. It returns all parameters related to a given UserAccountPositionLimit. For example, a hard position limit of 30 open contracts returns a risk parameter like this:
To set your own risk limits through the API, combine the userAccountPositionLimit/create and userAccountRiskParameter/create operations: first create a position-limit entity, then parameterize it with a risk-parameter entity. For example, to cap your maximum allowed position at 30 open contracts:

