# Rate limits

> TwittrAPI rate limits per API key in requests per second, the tiers for direct keys, the 429 response and how to back off.

HTML page: https://www.twittrapi.com/docs/helpful-infos/rate-limits

Each API key has a limit in requests per second. It applies to all endpoints together. Going over it returns **429**, which is not charged.

## Tiers for direct keys

| Tier | Requests per second | Price per month |
| --- | --- | --- |
| Trial | 3 | 7 days, $0.50 test credit |
| Standard | 30 | Included after the first top-up |
| Plus | 50 | $29 |
| Pro | 100 | $59 |
| Business | 300 | $149 |
| Scale | 1,000 | $349 |
| Enterprise | 3,000 | from $899, on request |

Standard is included once you have topped up. Plus, Pro, Business and Scale are booked under Plan & limits in the dashboard; the monthly fee comes out of your prepaid balance and you can cancel any time. Enterprise is set up with you: write to [support@twittrapi.com](mailto:support@twittrapi.com). The same table is on the [pricing page](https://www.twittrapi.com/pricing#rate-limits).

RapidAPI and JojAPI keys have the limits of the plan you bought there, shown on the marketplace listing.

## How the limit is counted

The limit is a token bucket per key. The bucket holds as many requests as your per-second limit and refills at that rate. A burst of up to one second's worth of requests goes through at once; after that, requests are accepted at the steady rate.

- Every request to an API endpoint counts, including ones that end in an error.
- `GET /balance` has its own limit of 10 requests per second (burst 20) and does not use your API limit.
- There are no rate-limit headers and no `Retry-After` header. Pace your requests on the client side.

## The 429 response

```json
{ "error": "Rate limit exceeded. Max 30 requests per second" }
```

The number is your current limit.

## Handling 429

Wait and retry. Because the window is one second, a short exponential backoff is enough:

```python
import time
import httpx

def get(url, params=None, tries=5):
    for attempt in range(tries):
        resp = httpx.get(url, params=params, headers={"X-API-KEY": "YOUR_API_KEY"}, timeout=60)
        if resp.status_code != 429:
            return resp
        time.sleep(0.25 * 2 ** attempt)  # 0.25 s, 0.5 s, 1 s, ...
    return resp
```

The official SDKs do this for you: they retry 429 and 5xx responses with backoff (2 retries by default, configurable with `max_retries` / `maxRetries`).

For steady high volume, limit concurrency instead of reacting to 429s. With a limit of 30 requests per second and responses that take about one second, around 25 parallel workers keep you under the limit. If you hit 429 regularly, book a higher tier.

## Ways to need fewer calls

- `/user/users/by/ids` returns up to 500 profiles per call, `/user/usernames/to/ids` resolves up to 100 handles, and `/user/usernames/status` checks up to 500 handles. Each is one call.
- Pass the numeric user ID instead of `username` on user timelines. It costs the same and is faster.
- Cache profiles and tweets you have already fetched.
