Overview
The TradeStation API enforces rate limits on requests to ensure fairness between users and prevent abuse to the network.
Rate limiting is enforced by the TradeStation API infrastructure. All throttling is handled centrally before requests are accepted.
Each API Key is allocated quota settings upon creation. These settings are applied on a per-user basis. If the quota is exceeded, an HTTP response of 429 Too Many Requests will be returned.
The number of available requests is calculated using a rolling interval, or by the number of simultaneously open connections for concurrent streaming limits. Rate limiting information is returned in response headers to help you manage requests.
We recommend using streaming services if available.
Rate Limiting Overview
Understanding Rate Limits
Rate limiting is implemented across all TradeStation API endpoints to ensure system stability and fair resource allocation among all users. Each API key receives specific quota allocations that are enforced on a per-user basis across different resource categories.
Default Rate Limit Configuration
TradeStation API Keys come with predefined rate limit configurations that vary by resource type and endpoint category. Unless you have specific application requirements that have been communicated to TradeStation Client Experience, your API key will use the standard rate limiting configuration.
Key Rate Limiting Concepts
Quota Allocation: Each API key is allocated specific request quotas based on the resource category being accessed. These quotas are designed to provide sufficient capacity for typical application usage while preventing system abuse.
Rolling Intervals: Rate limits operate within configured intervals, typically 5-minute intervals for most resources and 1-minute intervals for others. As requests consume quota, request capacity is replenished gradually over the interval.
Resource Categories: Different API endpoints are grouped into resource categories, each with its own quota and interval settings. This allows for more granular control over different types of API usage.
Concurrent Limits: Some resources, particularly streaming endpoints, have concurrent connection limits in addition to request rate limits.
Best Practices for Rate Limit Management
Use Streaming Services: When available, streaming services provide real-time data without consuming request quotas, making them the preferred option for continuous data feeds.
Implement Exponential Backoff: When receiving
429responses, implement exponential backoff retry logic to avoid overwhelming the system during high-traffic periods.Monitor Usage Patterns: Track your application's request patterns to identify potential quota issues before they impact your users.
Cache Responses: Implement appropriate caching strategies to reduce unnecessary API calls and optimize quota usage.
Request Quota Adjustments: If your application consistently exceeds standard quotas, contact Client Experience to discuss potential quota adjustments based on your specific use case.
Resource Categories
The rate limit applies to the following resource-categories:
| Resource-Category | Quota | Interval |
|---|---|---|
| Accounts | 320 | 5-minute |
| Order Details | 320 | 5-minute |
| Balances | 320 | 5-minute |
| Positions | 320 | 5-minute |
| Quote Change Stream | 500 | 5-minute |
| Barchart Stream | 500 | 5-minute |
| TickBar Stream | 500 | 5-minute |
| Each Option Endpoint | 90 | 1-minute |
| Quote Snapshot | 500 | 5-minute |
| MarketDepth Stream* | 30 | 1-minute |
| MarketDepth Stream* | 10 | concurrent |
| Option Quote Stream | 10 | concurrent |
| Option Chain Stream | 10 | concurrent |
| Order Stream | 40 | concurrent |
| Order Stream by Order Id | 40 | concurrent |
| Positions Stream | 40 | concurrent |
*The MarketDepth rate limit is a combined amount that applies to Quotes and Aggregate streams.
Rate Limit Response Headers
The API returns headers that help you manage request limits. These headers indicate the quota for the resource, how much capacity remains, and when capacity resets.
For streaming endpoints with concurrency limits, headers starting with X-Concurrency-* show the maximum number of streams that can be open at the same time, how many additional streams can be opened, and which streaming resource or group the limit applies to. These limits apply to active streaming connections; they do not limit the number of simultaneous non-streaming API requests.
For request rate limits, headers starting with X-RateLimit-* indicate the maximum number of requests within the interval, the remaining number of requests, the time until the limit fully resets, and the resource or endpoint this limit applies to.
| Header | Description |
|---|---|
X-Concurrency-Limit | The maximum number of streams that can be open concurrently for the resource. |
X-Concurrency-Remaining | The number of additional streams that can be opened before the concurrency limit is reached. |
X-Concurrency-Resource | The streaming resource or group for which the concurrency limit applies. |
X-RateLimit-Limit | The maximum number of requests allowed in a given period. |
X-RateLimit-Period | The time period, in seconds, for which the rate limit applies. |
X-RateLimit-Remaining | The number of remaining requests that can be made in the current period. |
X-RateLimit-Reset | The time, in seconds, until the rate limit fully resets. |
X-RateLimit-Resource | The resource or endpoint for which the rate limit applies. |
Replenishment Rate
As you make requests, the number of remaining requests is shown in the X-RateLimit-Remaining header. When this number reaches zero, you have hit the limit and cannot make more requests until enough capacity has been replenished.
For example, if a resource allows 500 requests over 300 seconds, request capacity is replenished at approximately one request every 0.6 seconds:
Replenishment Rate = Time Period / Request Quota
= 300 seconds / 500 requests
= 0.6 seconds per request
If you hit the limit and wait 100 seconds, approximately 167 requests would be replenished:
Requests Replenished = Wait Time / Replenishment Rate
= 100 seconds / 0.6 seconds per request
= 167 requests
This continuous replenishment lets you make requests steadily as capacity replenishes. If you burst usage and hit the limit, pause briefly before resuming. The X-RateLimit-Reset header indicates when the quota fully resets.
Rate Limit Example
For regular API requests, the X-RateLimit-* headers help you manage the number of allowed requests within a specific time frame. Each response includes headers that indicate the request limit, the remaining quota, and the reset time. These headers guide you on when to throttle requests and avoid hitting the limit.
Handling a 429 Response
When the quota is exceeded, the API returns HTTP 429 Too Many Requests. Use the X-RateLimit-Reset header to determine when to retry:
async function requestWithRateLimitHandling(url, options) {
const response = await fetch(url, options);
if (response.status === 429) {
const resetSeconds = parseInt(response.headers.get('X-RateLimit-Reset'), 10) || 60;
console.warn(`Rate limited. Retrying in ${resetSeconds}s...`);
await new Promise(resolve => setTimeout(resolve, resetSeconds * 1000));
return fetch(url, options);
}
return response;
}
Example Usage
By monitoring X-RateLimit-Remaining, you can throttle or batch requests as you approach the limit, ensuring you stay within allowed quotas without hitting the limit unexpectedly.
Suppose the API allows 320 requests in a rolling 5-minute interval. As requests are made, X-RateLimit-Remaining decreases. Once it reaches zero, further requests will fail with 429 Too Many Requests until enough capacity has been replenished.
while making requests to /v3/brokerage/accounts:
if X-RateLimit-Remaining > 0:
proceed with request
else:
wait(X-RateLimit-Reset)
retry the request
Example Throttled Request
GET https://api.tradestation.com/v3/marketdata/quotes/MSFT HTTP/2
Host: api.tradestation.com
Authorization: Bearer <token>
Accept: application/json
Example Failed Response
HTTP/2 429
date: Fri, 08 Nov 2024 20:04:56 GMT
content-type: application/json
access-control-allow-origin: *
cache-control: no-cache, no-store
strict-transport-security: max-age=31536000; includeSubDomains
vary: Origin
x-content-type-options: nosniff
x-ratelimit-limit: 500
x-ratelimit-period: 300
x-ratelimit-remaining: 0
x-ratelimit-reset: 287
x-ratelimit-resource: quotes
x-ts-request-id: 30c8b23c2cdedcc39c6ba38339d1818a
{"Error":"TooManyRequests","Message":"Rate quota exceeded"}
Concurrency Limit Example
For streaming endpoints, the X-Concurrency-* headers help you manage the number of concurrent streaming connections. These headers specify the maximum number of simultaneous connections allowed for a resource, helping you prevent overload and ensure stable streaming.
Example Usage
By monitoring X-Concurrency-Remaining, you can prioritize essential streams and close lower-priority ones when necessary. Efficiently managing active connections allows you to make the most of your streaming capacity without hitting the concurrency limit.
As streams are opened, X-Concurrency-Remaining decreases for each active connection. When it reaches zero, additional connection attempts will fail with 429 Too Many Requests. To open more streams, close existing connections to free capacity.
Example Throttled Request
GET https://api.tradestation.com/v3/brokerage/stream/accounts/<account-ids>/positions HTTP/2
Host: api.tradestation.com
Authorization: Bearer <token>
Accept: application/json
Example Failed Response
HTTP/2 429
date: Fri, 08 Nov 2024 20:03:42 GMT
content-type: application/json
access-control-allow-origin: *
cache-control: no-cache, no-store
strict-transport-security: max-age=31536000; includeSubDomains
vary: Origin
x-concurrency-limit: 40
x-concurrency-remaining: 0
x-concurrency-resource: streaming-positions
x-content-type-options: nosniff
x-ratelimit-limit: 251
x-ratelimit-period: 300
x-ratelimit-remaining: 25
x-ratelimit-reset: 272
x-ratelimit-resource: streaming-positions
{"Error":"TooManyRequests","Message":"Stream quota exceeded"}
Common Rate Limiting Scenarios
Market Data Applications: Applications requiring frequent market data updates should prioritize streaming endpoints over snapshot requests to optimize quota usage.
Portfolio Management Tools: Applications that need regular account, position, and balance updates should implement efficient polling strategies and consider using streaming services where available.
Algorithmic Trading: High-frequency trading applications may require custom quota configurations and should contact Client Experience to discuss specialized rate limiting arrangements.