---
name: X
description: Use when building applications that read or publish posts, search historical data, manage user relationships, stream real-time data, or access trends and analytics on X. Reach for this skill when agents need to authenticate, construct queries, handle pagination, manage rate limits, or troubleshoot API responses.
metadata:
    mintlify-proj: x
    version: "1.0"
---

# X API Skill

## Product summary

The X API provides programmatic access to X's public conversation through modern REST endpoints. Agents use it to search posts, retrieve user data, publish content, manage relationships (follows, blocks, mutes), access real-time streams, and analyze trends. Key entry points: Bearer Token authentication (app-only) or OAuth 1.0a/2.0 (user context). Primary docs: https://docs.x.com/x-api/introduction. Official SDKs available for Python (`xdk`) and TypeScript (`@xdevplatform/xdk`). CLI tool `xurl` handles OAuth automatically. Pay-per-use pricing with no commitments.

## When to use

Reach for this skill when:
- **Reading data**: Search posts (recent 7 days or full archive), look up users by username/ID, retrieve timelines, get trending topics
- **Publishing**: Create posts, manage bookmarks, like/repost content, send direct messages
- **Real-time monitoring**: Set up filtered streams with rules to receive matching posts as they're published
- **User management**: Follow/unfollow, block/mute users, manage lists
- **Analytics**: Access engagement metrics (likes, reposts, impressions) for posts
- **Troubleshooting**: Handle 401/403/429 errors, implement pagination, manage rate limits, validate authentication

## Quick reference

### Authentication methods

| Method | Use case | Credentials |
|:-------|:---------|:------------|
| Bearer Token (app-only) | Read public data, no user context | API Key + Secret → Bearer Token |
| OAuth 1.0a | Act on behalf of authenticated user | API Key + Secret + Access Token + Secret |
| OAuth 2.0 PKCE | User-context requests, modern flow | Client ID + Secret + Authorization Code |

Get credentials from Developer Console at https://console.x.com.

### Common endpoints

| Task | Endpoint | Method | Auth |
|:-----|:---------|:-------|:-----|
| Look up user | `/2/users/by/username/{username}` | GET | Bearer |
| Get user's posts | `/2/users/{id}/tweets` | GET | Bearer |
| Search recent posts | `/2/tweets/search/recent` | GET | Bearer |
| Search full archive | `/2/tweets/search/all` | GET | Bearer |
| Create post | `/2/tweets` | POST | OAuth 1.0a or 2.0 |
| Get filtered stream | `/2/tweets/search/stream` | GET | Bearer |
| Add stream rule | `/2/tweets/search/stream/rules` | POST | Bearer |

### Request structure

```bash
curl "https://api.x.com/2/users/by/username/xdevelopers?user.fields=created_at,public_metrics" \
  -H "Authorization: Bearer $BEARER_TOKEN"
```

### Response structure

```json
{
  "data": {
    "id": "2244994945",
    "name": "X Developers",
    "username": "xdevelopers",
    "created_at": "2013-12-14T04:35:55.000Z",
    "public_metrics": {
      "followers_count": 570842,
      "following_count": 2048
    }
  }
}
```

### Fields and expansions

**Fields**: Request additional data for an object type.
```bash
?tweet.fields=created_at,public_metrics,lang
?user.fields=description,verified,location
```

**Expansions**: Include related objects (author, media, polls).
```bash
?expansions=author_id&user.fields=username
```

### Pagination

```bash
# First request
?max_results=100

# Response includes meta.next_token
# Next request
?max_results=100&pagination_token=abc123
```

Stop when `next_token` is absent from response.

### Rate limit headers

Every response includes:
- `x-rate-limit-limit`: Max requests in window
- `x-rate-limit-remaining`: Requests left
- `x-rate-limit-reset`: Unix timestamp when window resets

## Decision guidance

| Scenario | Choose | Why |
|:---------|:-------|:----|
| Need recent posts only | `/2/tweets/search/recent` | Free, 7-day window, all developers |
| Need historical data | `/2/tweets/search/all` | Full archive back to 2006, pay-per-use |
| Real-time monitoring | Filtered Stream | Near real-time (6-7s latency), persistent connection |
| Lowest latency | Powerstream | Enterprise only, minimal delay |
| Simple testing | cURL or Postman | No setup, immediate feedback |
| Production code | Official SDK (Python/TypeScript) | Handles auth, pagination, rate limits automatically |
| Manual HTTP requests | Bearer Token | Simplest for read-only, app-only requests |
| User-context actions | OAuth 1.0a or 2.0 | Required for posting, DMs, managing relationships |

## Workflow

1. **Verify credentials**: Confirm Bearer Token or OAuth tokens are in Developer Console. Store securely (environment variables, not hardcoded).

2. **Choose endpoint**: Identify what data you need (posts, users, trends). Check if it requires user context or app-only auth.

3. **Build query**: For search, use operators: `from:username`, `#hashtag`, `lang:en`, `-is:retweet`, `has:images`. For streams, define rules with same operators.

4. **Add fields and expansions**: Request only the fields you need to minimize response size and API costs. Use expansions to include related objects (author, media).

5. **Make request**: Include `Authorization: Bearer $TOKEN` header. For POST requests, include JSON body with required fields.

6. **Handle pagination**: Check response `meta.next_token`. If present, make another request with `pagination_token=<token>`. Repeat until no token.

7. **Check rate limits**: Monitor `x-rate-limit-remaining` header. If approaching 0, implement exponential backoff before retrying.

8. **Parse response**: Extract data from `data` array. Related objects appear in `includes` section (users, media, polls). Match by ID.

9. **Verify results**: Confirm response contains expected fields. Check for `errors` array indicating partial failures.

## Common gotchas

- **Missing fields**: By default, endpoints return minimal data (post ID and text only). Always add `tweet.fields` or `user.fields` to get metrics, timestamps, etc.
- **Expansions without fields**: Adding `expansions=author_id` includes the author object, but you must also add `user.fields=username` to get author details.
- **Pagination tokens expire**: Don't store tokens for later use. Fetch all pages in one session.
- **Rate limit 429**: Don't retry immediately. Check `x-rate-limit-reset` header and wait. Implement exponential backoff (1s, 2s, 4s, 8s...).
- **401 Unauthorized**: Verify Bearer Token is correct and hasn't been regenerated. Check `Authorization: Bearer` format (space between Bearer and token).
- **403 Forbidden**: App may lack access to endpoint. Some endpoints require user-context auth (OAuth 1.0a/2.0), not app-only. Check Developer Console permissions.
- **404 Not Found**: Post may be deleted, user suspended, or protected. Deleted posts always return 404.
- **Search query syntax**: Operators are case-sensitive. `from:` not `FROM:`. Phrases need quotes: `"breaking news"` not `breaking news`.
- **Streaming connection drops**: Implement automatic reconnect with backoff. Stream sends keep-alive every 20s; if no data for 20s, reconnect.
- **Stream rules limit**: Max 1,000 rules per app. Each rule max 2,048 characters. Embedding rules (Enterprise) are asynchronous—may take seconds to start matching.
- **Character counting**: X counts characters differently (emoji = 2, URLs = 23). Use `twitter-text` library to validate before posting.

## Verification checklist

Before submitting work:

- [ ] Authentication header is present and correctly formatted (`Authorization: Bearer $TOKEN`)
- [ ] Fields and expansions are specified (not relying on defaults)
- [ ] Pagination is handled (loop until no `next_token`)
- [ ] Rate limit headers are checked; exponential backoff implemented for 429
- [ ] Error responses are parsed (check `errors` array in response)
- [ ] Response data is extracted from correct location (`data` array, `includes` for related objects)
- [ ] Credentials are not hardcoded; stored in environment variables
- [ ] Search queries use correct operator syntax (case-sensitive, phrases quoted)
- [ ] For streams, rules are added before connecting to stream endpoint
- [ ] For POST requests, required fields are included in JSON body

## Resources

- **Comprehensive navigation**: https://docs.x.com/llms.txt — Full page-by-page listing for agent reference
- **API Reference**: https://docs.x.com/x-api/introduction — All endpoints, parameters, and response schemas
- **Authentication Guide**: https://docs.x.com/fundamentals/authentication/overview — OAuth flows, token generation, best practices
- **Search Operators**: https://docs.x.com/x-api/posts/search/integrate/operators — Complete operator reference for queries and rules

---

> For additional documentation and navigation, see: https://docs.x.com/llms.txt