> ## Documentation Index
> Fetch the complete documentation index at: https://x-preview-mintlify-24fef6d1.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# X API Rate Limits

> Per-endpoint X API v2 rate limits for posts, users, search, streams, and DMs, plus how to read the x-rate-limit response headers and handle 429s.

Rate limits control the number of requests you can make to each endpoint. Exceeding limits results in a 429 error until the window resets.

***

## How rate limits work

| Concept | Description |
| :- | :- |
| **Time window** | Usually 15 minutes or 24 hours |
| **Per-user limits** | Apply with OAuth 1.0a or OAuth 2.0 user tokens |
| **Per-app limits** | Apply with Bearer Token (app-only) |
| **Per-endpoint** | Each endpoint has its own limits |

***

## Checking your limits

Response headers show your current rate limit status:

```
x-rate-limit-limit: 900
x-rate-limit-remaining: 847
x-rate-limit-reset: 1705420800
```

| Header | Description |
| :- | :- |
| `x-rate-limit-limit` | Maximum requests allowed |
| `x-rate-limit-remaining` | Requests remaining in window |
| `x-rate-limit-reset` | Unix timestamp when window resets |

***

## Rate limit tables

View the rate limit for each endpoint below. You can also see these limits in the [Developer Console](https://console.x.com).

<Note>
  Limits are shown per 15 minutes unless otherwise noted (e.g., "/24hrs" or "/sec").
</Note>

### Posts (25 endpoints)

#### Tweets lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/tweets` | 3,500/15min | 5,000/15min |
| GET | `/2/tweets/:id` | 450/15min | 900/15min |

#### Recent search

| Method | Endpoint | Per App | Per User | Notes |
| :- | :- | :- | :- | :- |
| GET | `/2/tweets/search/recent` | 450/15min | 300/15min | 10 default, 100 max results; 512 query length |

#### Full-archive search

| Method | Endpoint | Per App | Per User | Notes |
| :- | :- | :- | :- | :- |
| GET | `/2/tweets/search/all` | 1/sec, 300/15min | 1/sec | 10 default, 500 max results; 1024 query length |

#### Post counts

| Method | Endpoint | Per App | Per User | Notes |
| :- | :- | :- | :- | :- |
| GET | `/2/tweets/counts/recent` | 300/15min | — | 512 query length |
| GET | `/2/tweets/counts/all` | 300/15min | — | 1024 query length |

#### Filtered stream

| Method | Endpoint | Per App | Per User | Notes |
| :- | :- | :- | :- | :- |
| GET | `/2/tweets/search/stream` | 50/15min | — | 1 connection; 1000 rules; 1024 rule length; 250 posts/sec |
| GET | `/2/tweets/search/stream/rules` | 450/15min | — | 1 connection; 1000 rules; 1024 rule length |
| POST | `/2/tweets/search/stream/rules` | 100/15min | — | 1 connection; 1000 rules; 1024 rule length |

#### Manage posts

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/tweets` | 10,000/24hrs | 100/15min |
| DELETE | `/2/tweets/:id` | — | 50/15min |

#### Timelines

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/users/:id/tweets` | 10,000/15min | 900/15min |
| GET | `/2/users/:id/mentions` | 450/15min | 300/15min |
| GET | `/2/users/:id/timelines/reverse_chronological` | — | 180/15min |

#### Likes lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/tweets/:id/liking_users` | 75/15min | 75/15min |
| GET | `/2/users/:id/liked_tweets` | 75/15min | 75/15min |

#### Manage likes

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/users/:id/likes` | — | 50/15min, 1,000/24hrs |
| DELETE | `/2/users/:id/likes/:tweet_id` | — | 50/15min, 1,000/24hrs |

#### Retweets lookup

| Method | Endpoint | Per App | Per User | Notes |
| :- | :- | :- | :- | :- |
| GET | `/2/tweets/:id/retweeted_by` | 75/15min | 75/15min | — |
| GET | `/2/tweets/:id/quote_tweets` | 75/15min | 75/15min | — |
| GET | `/2/users/reposts_of_me` | — | 75/15min | 100 max results |

#### Manage retweets

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/users/:id/retweets` | — | 50/15min |
| DELETE | `/2/users/:id/retweets/:tweet_id` | — | 50/15min |

#### Hide replies

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| PUT | `/2/tweets/:tweet_id/hidden` | — | 50/15min |

***

### Users (14 endpoints)

#### Users lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/users` | 300/15min | 900/15min |
| GET | `/2/users/:id` | 300/15min | 900/15min |
| GET | `/2/users/by` | 300/15min | 900/15min |
| GET | `/2/users/by/username/:username` | 300/15min | 900/15min |
| GET | `/2/users/me` | — | 75/15min |

#### Search users

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/users/search` | 300/15min | 900/15min |

#### Follows lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/users/:id/following` | 300/15min | 300/15min |
| GET | `/2/users/:id/followers` | 300/15min | 300/15min |

#### Manage follows

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/users/:id/following` | — | 50/15min |
| DELETE | `/2/users/:source_user_id/following/:target_user_id` | — | 50/15min |

#### Blocks lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/users/:id/blocking` | — | 15/15min |

#### Mutes lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/users/:id/muting` | — | 15/15min |

#### Manage mutes

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/users/:id/muting` | — | 50/15min |
| DELETE | `/2/users/:source_user_id/muting/:target_user_id` | — | 50/15min |

***

### Spaces (6 endpoints)

#### Spaces lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/spaces/:id` | 300/15min | 300/15min |
| GET | `/2/spaces` | 300/15min | 300/15min |
| GET | `/2/spaces/:id/tweets` | 300/15min | 300/15min |
| GET | `/2/spaces/by/creator_ids` | 300/15min, 1/sec | 300/15min, 1/sec |
| GET | `/2/spaces/:id/buyers` | 300/15min | 300/15min |

#### Search Spaces

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/spaces/search` | 300/15min | 300/15min |

***

### Direct Messages (8 endpoints)

#### Direct Messages lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/dm_events` | — | 15/15min |
| GET | `/2/dm_events/:id` | — | 15/15min |
| GET | `/2/dm_conversations/:dm_conversation_id/dm_events` | — | 15/15min |
| GET | `/2/dm_conversations/with/:participant_id/dm_events` | — | 15/15min |

#### Manage Direct Messages

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/dm_conversations` | 1,440/24hrs | 15/15min, 1,440/24hrs |
| POST | `/2/dm_conversations/with/:participant_id/messages` | 1,440/24hrs | 15/15min, 1,440/24hrs |
| POST | `/2/dm_conversations/:dm_conversation_id/messages` | 1,440/24hrs | 15/15min, 1,440/24hrs |
| DELETE | `/2/dm_events/:id` | 4,000/24hrs | 300/15min, 1,500/24hrs |

***

### Lists (14 endpoints)

#### Lists lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/lists/:id` | 75/15min | 75/15min |
| GET | `/2/users/:id/owned_lists` | 15/15min | 15/15min |

#### List Tweets lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/lists/:id/tweets` | 900/15min | 900/15min |

#### List member lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/lists/:id/members` | 900/15min | 900/15min |
| GET | `/2/users/:id/list_memberships` | 75/15min | 75/15min |

#### Manage Lists

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/lists` | — | 300/15min |
| DELETE | `/2/lists/:id` | — | 300/15min |
| PUT | `/2/lists/:id` | — | 300/15min |

#### Manage List members

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/lists/:id/members` | — | 300/15min |
| DELETE | `/2/lists/:id/members/:user_id` | — | 300/15min |

#### Manage List follows

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/users/:id/followed_lists` | — | 50/15min |
| DELETE | `/2/users/:id/followed_lists/:list_id` | — | 50/15min |

#### Pinned Lists

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/users/:id/pinned_lists` | 15/15min | 15/15min |
| POST | `/2/users/:id/pinned_lists` | — | 50/15min |
| DELETE | `/2/users/:id/pinned_lists/:list_id` | — | 50/15min |

***

### Bookmarks (5 endpoints)

#### Bookmarks lookup

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/users/:id/bookmarks` | — | 180/15min |
| GET | `/2/users/:id/bookmarks/folders` | 50/15min | 50/15min |
| GET | `/2/users/:id/bookmarks/folders/:folder_id` | 50/15min | 50/15min |

#### Manage Bookmarks

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/users/:id/bookmarks` | — | 50/15min |
| DELETE | `/2/users/:id/bookmarks/:tweet_id` | — | 50/15min |

***

### Compliance (3 endpoints)

#### Batch compliance

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/compliance/jobs` | 150/15min | — |
| GET | `/2/compliance/jobs/:job_id` | 150/15min | — |
| GET | `/2/compliance/jobs` | 150/15min | — |

***

### Usage (1 endpoint)

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/usage/tweets` | 50/15min | — |

***

### Trends (2 endpoints)

#### Personalized Trends

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/users/personalized_trends` | 200/24hrs, 200/15min | 100/24hrs, 10/15min |

#### Trends by WOEID

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/trends/by/woeid/:id` | 75/15min | — |

***

### Communities (2 endpoints)

| Method | Endpoint | Per App | Per User | Notes |
| :- | :- | :- | :- | :- |
| GET | `/2/communities/:id` | 300/15min | 300/15min | — |
| GET | `/2/communities/search` | 300/15min | 300/15min | 100 max results |

***

### Analytics (1 endpoint)

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/tweets/analytics` | 300/15min | 300/15min |

***

### Media (8 endpoints)

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| POST | `/2/media/upload` | 50,000/24hrs | 500/15min |
| GET | `/2/media/upload` | 100,000/24hrs | 1,000/15min |
| POST | `/2/media/upload/initialize` | 180,000/24hrs | 1,875/15min |
| POST | `/2/media/upload/:id/append` | 180,000/24hrs | 1,875/15min |
| POST | `/2/media/upload/:id/finalize` | 180,000/24hrs | 1,875/15min |
| POST | `/2/media/metadata` | 50,000/24hrs | 500/15min |
| POST | `/2/media/subtitles` | 10,000/24hrs | 100/15min |
| DELETE | `/2/media/subtitles` | 10,000/24hrs | 100/15min |

***

### Activity & Webhooks

| Method | Endpoint | Per App | Per User | Notes |
| :- | :- | :- | :- | :- |
| GET | `/2/activity/stream` | 450/15min | — | 2 connections; 250 posts/sec |
| POST | `/2/activity/subscriptions` | 500/15min | — | — |
| GET | `/2/activity/subscriptions` | 500/15min | — | — |
| PUT | `/2/activity/subscriptions/:subscription_id` | 500/15min | — | — |
| DELETE | `/2/activity/subscriptions/:subscription_id` | 500/15min | — | — |
| POST | `/2/webhooks` | 450/15min | — | — |
| GET | `/2/webhooks` | 450/15min | — | — |
| PUT | `/2/webhooks/:webhook_id` | 450/15min | — | — |
| DELETE | `/2/webhooks/:webhook_id` | 450/15min | — | — |
| POST | `/2/webhooks/replay` | 100/15min | — | — |

***

### Other endpoints

| Method | Endpoint | Per App | Per User |
| :- | :- | :- | :- |
| GET | `/2/tweets/sample10/stream` | 100/15min | — |
| GET | `/2/news/:id` | 200/15min | — |
| GET | `/2/news/search` | 200/15min | 200/15min |
| POST | `/2/users/:id/dm/block` | 25/15min, 1,000/24hrs | 10/15min, 400/24hrs |
| POST | `/2/users/:id/dm/unblock` | 25/15min, 1,000/24hrs | 10/15min, 400/24hrs |
| GET | `/2/users/by/username/:username/tweets` | 1,500/15min | 900/15min |
| GET | `/2/users/by/username/:username/mentions` | 450/15min | 180/15min |
| GET | `/2/users/:id/following/spaces` | 300/15min | 300/15min |
| GET | `/2/tweets/:id/retweets` | 75/15min | 75/15min |
| DELETE | `/2/connections/all` | 25/15min | 25/15min |

***

## Handling rate limits

When you hit a rate limit, you'll receive a 429 response:

```json theme={null}
{
  "errors": [{
    "code": 88,
    "message": "Rate limit exceeded"
  }]
}
```

### Recovery strategy

1. Check `x-rate-limit-reset` for when the window resets
2. Wait until that time before retrying
3. Use exponential backoff if needed

```python title="Example" lines wrap icon="python" theme={null}
import time

def make_request_with_backoff(url, headers):
    response = requests.get(url, headers=headers)
    
    if response.status_code == 429:
        reset_time = int(response.headers.get('x-rate-limit-reset', 0))
        wait_time = max(reset_time - time.time(), 60)
        time.sleep(wait_time)
        return make_request_with_backoff(url, headers)
    
    return response
```

***

## Best practices

<CardGroup cols={2}>
  <Card title="Cache responses" icon="database">
    Store results locally to reduce repeated requests.
  </Card>

  <Card title="Use streaming" icon="signal-stream">
    For real-time data, use filtered stream instead of polling.
  </Card>

  <Card title="Monitor headers" icon="gauge-high">
    Track remaining requests to avoid hitting limits.
  </Card>

  <Card title="Spread requests" icon="clock">
    Distribute requests across the time window.
  </Card>
</CardGroup>

***

## Rate limits vs. billing

Rate limits and billing are separate:

| Concept | Purpose |
| :- | :- |
| **Rate limits** | Control request frequency for system stability |
| **Usage billing** | Charge for data retrieved (pay-per-usage) |

You can be within rate limits but still incur usage costs, or hit rate limits without additional cost.

***

## Enterprise rate limits

Enterprise customers have custom rate limits. Contact your account manager or [apply for Enterprise access](/enterprise/forms/enterprise-api-interest).

***

## Next steps

<CardGroup cols={2}>
  <Card title="Error handling" icon="https://mintcdn.com/x-preview-mintlify-24fef6d1/59IoAvAuVo7j6MWt/icons/xds/icon-warning.svg?fit=max&auto=format&n=59IoAvAuVo7j6MWt&q=85&s=d31440d63e8316821513e1b53ab16570" href="/x-api/fundamentals/response-codes-and-errors" width="24" height="24" data-path="icons/xds/icon-warning.svg">
    Handle 429 and other errors.
  </Card>

  <Card title="Getting started" icon="https://mintcdn.com/x-preview-mintlify-24fef6d1/HazjhzcnQyryvfGR/icons/xds/icon-rocket.svg?fit=max&auto=format&n=HazjhzcnQyryvfGR&q=85&s=d0f5cef99b2c696bbfb49fa10afdd62f" href="/x-api/getting-started/about-x-api" width="24" height="24" data-path="icons/xds/icon-rocket.svg">
    Learn about access levels and features.
  </Card>
</CardGroup>
