> This page is for NT Prop.

> 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.

# Rate Limits

Understanding and respecting API rate limits ensures reliable, high-performance integrations that scale with your prop firm's growth.

## Rate Limit Overview

The NinjaTrader Partner API implements a **two-tier rate limiting system**:

1. **User-Level Limits**: Applied per user (by user ID) across all endpoints
2. **Endpoint-Level Limits**: Applied per IPv4 `/24` subnet or individual full IPv6 address for specific endpoints

When an endpoint rate limit is exceeded, the user must wait the number of seconds specified in the `p-time` before making another request of the same type.

## Considerations

* **Two-tier rate limiting**: Both user-level limits (based on authentication) and endpoint-level limits apply simultaneously. Your requests must respect both.
* **Sliding time window**: Endpoint limits use a rolling one-hour window, not a fixed hourly reset.
* **Shared IP limits**: Endpoint limits are tracked by IPv4 `/24` subnet or individual full IPv6 address, not by individual IPv4 address. If you're behind a shared IP (corporate network, VPN, shared hosting) or send requests from the same IPv4 `/24` subnet as other clients, you may share limits with them.
* **Back-off**: Repeated violations add a fixed back-off to your `p-time` before you can retry. The back-off is set per endpoint (shown in the tables below).
* **Request counting**: Some endpoints count all requests toward the limit, while others only count failed requests. See the "Requests Counted" column in each table.

## Rate Limits

### User-Level Rate Limits

| **User Type**     | **Per Hour** | **Per Minute** | **Per Second** |
| ----------------- | ------------ | -------------- | -------------- |
| **Anonymous**     | 1,000        | 1,000          | 100            |
| **Authenticated** | 5,000        | 5,000          | 5,000          |

### Endpoint-Level Rate Limits

> **Note**
>
> **Note:** *Requests Counted* indicates which requests count toward the hourly limit: All requests or failed requests only.

> **Note**
>
> **Note:** Endpoints showing "n/a" do not have specific endpoint-level limits. They follow the standard user-level rate limits.

#### Authentication Endpoints

| **Endpoint**         | **Limit/Hour** | **Back-off (sec)** | **Requests Counted** |
| -------------------- | -------------- | ------------------ | -------------------- |
| `accesstokenrequest` | 5              | 15                 | Failed only          |
| `renewaccesstoken`   | 15             | 15                 | All                  |
| `me`                 | 10             | 30                 | Failed only          |

#### User Management Endpoints

| **Endpoint**               | **Limit/Hour** | **Back-off (sec)** | **Requests Counted** |
| -------------------------- | -------------- | ------------------ | -------------------- |
| `createevaluationusers`    | 100            | 1                  | Failed only          |
| `createevaluationaccounts` | 100            | 1                  | Failed only          |
| `signuporganizationmember` | 100            | 1                  | Failed only          |
| `canceleverything`         | n/a            | n/a                | n/a                  |
| `syncrequest`              | 300            | 3                  | All                  |
| `changeuserstatus`         | n/a            | n/a                | n/a                  |

#### Customer Application / Subaccount Endpoints

| **Endpoint**                             | **Limit/Hour** | **Back-off (sec)** | **Requests Counted** |
| ---------------------------------------- | -------------- | ------------------ | -------------------- |
| `createpartnersubaccountrequest`         | 250            | 30                 | All                  |
| `submitpartnersubaccountdocument`        | 750            | 30                 | All                  |
| `submitcustomerapplicationdocument`      | 750            | 30                 | All                  |
| `getpartnersubaccountrequeststatus`      | n/a            | n/a                | n/a                  |
| `getpartnersubaccountdocumentuploadurls` | n/a            | n/a                | n/a                  |
| `checkduplicate`                         | n/a            | n/a                | n/a                  |
| `startcustomerapplication`               | 10             | 30                 | All                  |
| `submitapplicant`                        | n/a            | n/a                | n/a                  |
| `prepareagreementdocuments`              | 10             | 30                 | All                  |
| `signagreementdocuments`                 | 10             | 30                 | All                  |
| `signnonprocertification`                | 10             | 30                 | All                  |

#### Trading Permission Endpoints

| **Endpoint**                   | **Limit/Hour** | **Back-off (sec)** | **Requests Counted** |
| ------------------------------ | -------------- | ------------------ | -------------------- |
| `getaccounttradingpermissions` | 100            | 1                  | All                  |
| `requesttradingpermission`     | 20             | 2                  | Failed only          |
| `revoketradingpermission`      | n/a            | n/a                | n/a                  |
| `revoketradingpermissions`     | n/a            | n/a                | n/a                  |

#### Account & Risk Management Endpoints

| **Endpoint**                     | **Limit/Hour** | **Back-off (sec)** | **Requests Counted** |
| -------------------------------- | -------------- | ------------------ | -------------------- |
| `resetdemoaccountstate`          | n/a            | n/a                | n/a                  |
| `switchriskcategory`             | 5,000          | 1                  | All                  |
| `setadminautoliqaction`          | n/a            | n/a                | n/a                  |
| `organizationadminlockaccount`   | n/a            | n/a                | n/a                  |
| `organizationadminunlockaccount` | n/a            | n/a                | n/a                  |
| `updatemaxnetliq`                | n/a            | n/a                | n/a                  |
| `useraccountautoliq/update`      | n/a            | n/a                | n/a                  |
| `updateuserautoliq`              | n/a            | n/a                | n/a                  |
| `updateuserautoliqs`             | n/a            | n/a                | n/a                  |
| `setdemohalt`                    | 20             | 5                  | All                  |
| `changedemobalance`              | 1,000          | 10                 | All                  |

#### Subscription & Entitlement Endpoints

| **Endpoint**                 | **Limit/Hour** | **Back-off (sec)** | **Requests Counted** |
| ---------------------------- | -------------- | ------------------ | -------------------- |
| `addmarketdatasubscription`  | n/a            | n/a                | n/a                  |
| `addtradovatesubscription`   | n/a            | n/a                | n/a                  |
| `addentitlementsubscription` | n/a            | n/a                | n/a                  |

#### Admin Alert Endpoints

| **Endpoint**                           | **Limit/Hour** | **Back-off (sec)** | **Requests Counted** |
| -------------------------------------- | -------------- | ------------------ | -------------------- |
| `adminalertsignal/deps`                | n/a            | n/a                | n/a                  |
| `adminalertsignal/completealertsignal` | n/a            | n/a                | n/a                  |

#### Workspace Template Endpoints

| **Endpoint**                | **Limit/Hour** | **Back-off (sec)** | **Requests Counted** |
| --------------------------- | -------------- | ------------------ | -------------------- |
| `getorgworkspacetemplate`   | n/a            | n/a                | n/a                  |
| `workspacetemplate/create`  | n/a            | n/a                | n/a                  |
| `workspacetemplate/find`    | n/a            | n/a                | n/a                  |
| `workspacetemplate/finds`   | n/a            | n/a                | n/a                  |
| `workspacetemplate/item`    | n/a            | n/a                | n/a                  |
| `workspacetemplate/items`   | n/a            | n/a                | n/a                  |
| `workspacetemplate/list`    | n/a            | n/a                | n/a                  |
| `workspacetemplate/suggest` | n/a            | n/a                | n/a                  |
| `workspacetemplate/update`  | n/a            | n/a                | n/a                  |

#### Contact Info Endpoints

| **Endpoint**                    | **Limit/Hour** | **Back-off (sec)** | **Requests Counted** |
| ------------------------------- | -------------- | ------------------ | -------------------- |
| `contactinfo/updatecontactinfo` | n/a            | n/a                | n/a                  |

#### Order Endpoints

| **Endpoint** | **Limit/Hour** | **Back-off (sec)** | **Requests Counted** |
| ------------ | -------------- | ------------------ | -------------------- |
| `dryrun`     | 500            | 1                  | All                  |

## Rate Limit Responses

### User-Level Rate Limits Exceeded (429 Response)

For general rate limit violations, when a limit is reached, the server stops handling requests for a period of time and responds to each new request with a 429 status code.

**HTTP Response**

```http
HTTP/1.1 429 Too Many Requests
Content-Length: 0
```

**WebSocket Response**

```json
[{"s": 429, "i": "request_id"}]
```

#### Handling 429 Responses

* Wait one hour before sending another request
* **Cannot be resolved programmatically** from third-party applications

### Endpoint-Level Rate Limits Exceeded (Penalty Ticket)

For endpoint-level rate limit violations, the system may return a penalty ticket (p-ticket) returned in **successful HTTP responses** (200 OK), not as 429 errors. When you receive a penalty ticket, the request was not handled and the server has imposed a time penalty.

* `p-ticket`: Encrypted penalty token tied to your IP address - **must be included as an additional parameter in the request body's JSON when retrying**
* `p-time`: Penalty duration in seconds - **wait this long before retrying the call**
* `p-captcha`: Whether reCAPTCHA verification is required (optional field) - **when `true`, the operation cannot be tried again from a third-party application and users should be alerted that they should try the operation again in an hour**
* `p-message`: Description of the specific limit that was exceeded - for example, `"Rate limit exceeded: more than 20 requests per hour"`

**HTTP Response**

```json
{
    "p-ticket": "encrypted_ticket_string",
    "p-time": 15,
    "p-captcha": true,
    "p-message": "Rate limit exceeded: more than 20 requests per hour"
}
```

**WebSocket Response**

```
a[{"s":200,"i":"42","d":{"p-ticket":"abc123xyz","p-time":15,"p-message":"Rate limit exceeded: more than 20 requests per hour"}}]
```

#### Handling Penalty Tickets (P-Tickets)

For how to recover from a penalty ticket, why retrying early makes the penalty worse, what does and doesn't clear it, and how to reduce penalty tickets in normal operation, see

[Penalty Tickets (P-Tickets)](/prop/overview/core-concepts/penalty-tickets)

.

## Rate Limits Best Practices

### Dos ✅

1. **Check response bodies for penalty tickets** - Even successful (200 OK) responses may contain `p-ticket` fields
2. **Wait the full `p-time` duration** before retrying penalty ticket requests
3. **Include `p-ticket` in retry requests** - Add it to the original request body when retrying
4. **Check `p-captcha` first** - Always verify this field before attempting retries
5. **Cache responses** appropriately to reduce API calls
6. **Use batch endpoints** when available
7. **Prioritize critical requests** (orders, risk management)
8. **Set up monitoring and alerting** for rate limit usage
9. **Handle authentication failures gracefully** - Track failed attempts to prevent lockouts

### Don'ts ❌

1. **Don't ignore penalty tickets** - Always check response bodies for `p-ticket` fields, even on successful responses
2. **Don't retry when `p-captcha: true`** - Stop immediately and inform users to wait one hour
3. **Don't retry before waiting `p-time` seconds** - Respect the full penalty duration
4. **Don't forget to include `p-ticket`** - The retry request must include the penalty ticket
5. **Don't make unnecessary API calls** - Cache when possible to avoid hitting limits
6. **Don't exceed rate limits consistently** - This may result in temporary blocks or reCAPTCHA requirements
7. **Don't implement infinite retry loops** - Set maximum retry attempts
8. **Don't skip authentication rate limits** - These are stricter and may trigger reCAPTCHA

## Requesting Higher Limits

For high-volume integrations, you can request increased rate limits:

### Eligibility Criteria

* **Established partnership** with proven integration
* **Proper rate limit handling** implemented
* **Business justification** for higher limits
* **Technical review** of integration architecture

## Support

Need help with rate limiting?

* **[Partner Success Team](mailto:partners@tradovate.com)** - Rate limit increase requests
* **[Support Center](https://support.tradovate.com)** - Troubleshooting guides

---