Overview
The Tiger Agency API applies rate limits per end user, not per API client. When a single API client serves multiple users, each user has an independent quota and does not consume the quotas of others.
Requests that exceed a limit are rejected with HTTP 429 Too Many Requests.
How Requests Are Counted
Each request is counted against a bucket derived from the user identity behind the request. How that identity is resolved depends on the authorization mode.
Individual Authorization Mode
- Bucket = the authorized end user, identified by the OAuth2 access token.
- No additional header is required.
Institution (Client Credentials) Mode
- Every FA API call must include the header
X-TIGR-UID: {uid}(see Authentication → Overview for the definition ofuid). - Bucket = the user referenced by
X-TIGR-UID. - When the same institution client calls the API on behalf of different
uidvalues, eachuidhas its own independent bucket.
| Mode | Bucket identifier | Required header |
|---|---|---|
| Individual authorization | Authorized end user (from access token) | — |
| Institution (client credentials) | User referenced by X-TIGR-UID | X-TIGR-UID: {uid} |
Rate Limit Tiers
Endpoints are grouped into three tiers. Each tier defines a maximum number of requests per rolling window, applied per bucket as described above.
Path parameters ({symbol}, {orderId}, {accountId}) are placeholders. The deployment base URL / context path is not shown in the tables below and does not affect which tier applies.
High-frequency tier — 120 requests / 60 seconds
| Method | URL Path |
|---|---|
| GET | /v1/contracts/{symbol} |
| POST | /v1/orders |
| PUT | /v1/orders/{orderId} |
| DELETE | /v1/orders/{orderId} |
Common tier — 60 requests / 60 seconds
| Method | URL Path |
|---|---|
| GET | /v1/accounts/{accountId}/assets |
| GET | /v1/accounts/{accountId}/positions |
| POST | /v1/orders/forex |
| GET | /v1/orders |
| GET | /v1/orders/{orderId} |
| GET | /v1/orders/filled |
| GET | /v1/orders/inactive |
| GET | /v1/orders/active |
Low-frequency tier — 5 requests / 60 seconds
| Method | URL Path |
|---|---|
| GET | /v1/stocks |
| GET | /v1/futures |
| GET | /v1/orders/forex/quotes |
Exceeding the Limit
When a request exceeds its tier's limit, the server responds with:
- HTTP status:
429 Too Many Requests Content-Type: application/json;charset=UTF-8
Example response body:
{
"code": 400,
"message": "rate limit error(current limiting interface:/v1/orders, up to 120 times per minute)",
"data": null,
"timestamp": 1734100000000
}| Field | Type | Description |
|---|---|---|
code | integer | Generic business error code. Not a rate-limit specific code — always use the HTTP status 429 to detect rate limiting. |
message | string | Human-readable error. Includes the endpoint identifier and the configured limit. |
data | object / null | Reserved payload. null for rate-limit errors. |
timestamp | long | Server epoch time in milliseconds. |
Detection rule: rely on HTTP status 429. Do not parse the body code field to determine whether a response was rate-limited.
Best Practices
- On receiving
429, wait for the corresponding window (currently 60 seconds for all tiers) before retrying. Combine with exponential backoff to avoid hammering the server the moment the window resets. - For critical endpoints (order placement, modification, cancellation) implement a client-side token bucket to stay under the tier limit rather than relying on server-side rejection.
- Institution clients that need higher aggregate throughput can distribute requests across different
X-TIGR-UIDvalues — eachuidreceives its own independent quota per tier. - Do not treat
429as a queuing signal. Rejected requests are not retried on the server side; the client must decide whether and when to retry. - Endpoints not listed in the tables above are not currently rate-limited. Do not rely on this as a guarantee — coverage and thresholds may change in future releases and will be announced through the release notes.