> This page is for NT Connect.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://partner.ninjatrader.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://partner.ninjatrader.com/_mcp/server.

# Setting Up OAuth

OAuth lets your platform get an access token for each end user (a trader using your platform), so you can place orders and view real-time updates about their account. Each end user logs in with their own NinjaTrader credentials on a NinjaTrader-hosted page, so your platform doesn't handle their password. You redirect the end user to an authorize URL, capture the `code` that comes back, and exchange it at [`oAuthToken`](/connect/api/rest-api-endpoints/authentication/o-auth-token) for that user's access token and refresh token.

## Prerequisites

Generate an OAuth API key in Web Trader (see [API Keys](/connect/overview/quick-setup/api-keys)): choose the OAuth option and provide a redirect URI. This is your platform's own key, and you use it to authorize every end user. The key's client ID (`cid`) is your `client_id`, its secret (`sec`) is your `client_secret`, and the redirect URI you register is your `redirect_uri`. Keep a separate key for staging and for production, and store the secret server-side.

## Getting an Access Token

1. **Redirect the end user to the authorize URL** with `response_type=code`, your `client_id`, and your `redirect_uri`. Use the staging host while you integrate and the production host when you go live:

   * **Staging:** `https://trader.staging.ninjatrader.dev/oauth?response_type=code&client_id=<your-client-id>&redirect_uri=<your-redirect-uri>`

   * **Production:** `https://trader.tradovate.com/oauth?response_type=code&client_id=<your-client-id>&redirect_uri=<your-redirect-uri>`

2. **The end user logs in** with their NinjaTrader credentials on that NinjaTrader-hosted page. A successful login redirects back to your `redirect_uri` with the code in the URL. The response code looks like `xfjb7tdbgclx2gkwgeaiiwtr2lusv53`.

3. **Exchange the code** for that end user's token by calling `oAuthToken` with `grant_type` set to `authorization_code`. Post a JSON body (not form-encoded) to the staging endpoint (`https://live-api.staging.ninjatrader.dev/v1/auth/oauthtoken`) while you integrate, and the production endpoint (`https://live.tradovateapi.com/v1/auth/oauthtoken`) when you go live:

   ```json
   {
     "grant_type": "authorization_code",
     "code": "<authorization-code>",
     "redirect_uri": "<your-redirect-uri>",
     "client_id": "<your-client-id>",
     "client_secret": "<your-client-secret>"
   }
   ```

   The response carries the tokens and their lifetimes:

   ```json
   {
     "access_token": "<access-token>",
     "refresh_token": "<refresh-token>",
     "token_type": "bearer",
     "expires_in": 4800,
     "refresh_token_expires_in": 93600
   }
   ```

   Read the lifetimes from the response rather than hard-coding them: the access token lasts 80 minutes (`expires_in` of 4800 seconds) and the refresh token 26 hours (`refresh_token_expires_in` of 93600 seconds). These lifetimes are the same in staging and production. This endpoint returns `HTTP 200` even for errors, so check for an `error` field in the response, not the status code.

4. **Store each end user's tokens.** Save the access token, its expiry, and the refresh token for that user (for example, in your database), so you can keep their connection alive and refresh it without making them log in again.

## Refreshing a Token

To keep a user connected, request a new access token with the refresh-token grant on the same endpoint before the current access token expires, instead of redirecting the user to the authorize URL again. As long as you refresh before the 26-hour refresh token expires, that user stays connected; if a refresh token lapses, the user logs in again:

```json
{
  "grant_type": "refresh_token",
  "refresh_token": "<previously-issued>",
  "client_id": "<your-client-id>",
  "client_secret": "<your-client-secret>"
}
```

Each refresh returns a new token pair, so store the most recent one for that user.