> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://partner.ninjatrader.com/connect/overview/core-concepts/rate-limits/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 IP 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 IP address. If you're behind a shared IP (corporate network, VPN, shared hosting), you may share limits with other clients. * **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)](/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 ---