# X (Twitter) API Setup Guide

This guide provides step-by-step instructions for setting up X (formerly Twitter) API integration for managing tweets and replies.

---

## Table of Contents

1. [Overview](#overview)
2. [Prerequisites](#prerequisites)
3. [X Developer Portal Setup](#x-developer-portal-setup)
4. [Environment Configuration](#environment-configuration)
5. [OAuth Redirect URI Configuration](#oauth-redirect-uri-configuration)
6. [Permissions & Scopes](#permissions--scopes)
7. [API Tiers & Limitations](#api-tiers--limitations)
8. [Development vs Production](#development-vs-production)
9. [Troubleshooting](#troubleshooting)

---

## Overview

**API Version:** X API v2
**Base URL:** `https://api.twitter.com/2`
**Auth URL:** `https://twitter.com/i/oauth2/authorize`
**Token URL:** `https://api.twitter.com/2/oauth2/token`
**Auth Method:** OAuth 2.0 with PKCE (Proof Key for Code Exchange)

### Features Supported
- Fetch user tweets
- Read tweet replies (conversation threads)
- Reply to tweets
- Automatic token refresh

### ⚠️ Important Limitations
- **Search API** (for fetching replies) requires **Basic tier or higher**
- **Free tier** cannot search for replies - only direct mentions accessible
- The system supports both tiers with graceful degradation

---

## Prerequisites

- An X (Twitter) account
- Access to [X Developer Portal](https://developer.twitter.com/)
- HTTPS-enabled server for production (required for OAuth redirect URIs)

---

## X Developer Portal Setup

### Step 1: Apply for Developer Access

1. Navigate to [X Developer Portal](https://developer.twitter.com/en/portal/dashboard)
2. Sign in with your X account
3. Click **"Sign up"** for free access (or choose a paid tier)
4. Fill out the application form:
   - **Country:** Select your country
   - **Use Case:** Select "Building tools for my own use" or appropriate option
   - **Description:** Describe your use case in detail:
     > "We are building a social media management dashboard that allows organizations to manage and respond to comments and replies on their X/Twitter posts from a centralized interface. This helps community managers respond faster to audience engagement."
5. Review and accept the developer agreement
6. Click **"Submit"**

### Step 2: Create a Project & App

1. Once approved, go to the [Developer Portal](https://developer.twitter.com/en/portal/dashboard)
2. Create a **Project**:
   - **Project Name:** e.g., "PX360 Social"
   - **Use Case:** Select "Building tools for my own use"
   - **Project Description:** Brief description of your application
3. Create an **App** within the project:
   - **App Name:** Unique name for your app (must be globally unique)
   - **Environment:** Select "Production"

### Step 3: Configure OAuth 2.0

1. In your app settings, go to **"Settings"** tab
2. Scroll to **"User authentication settings"**
3. Click **"Set up"**
4. Select **"Web App, Automated App or Bot"**
5. Configure OAuth 2.0:

   **General Settings:**
   - **Callback URI / Redirect URL:** 
     - Development: `http://127.0.0.1:8000/social/callback/X/`
     - Production: `https://yourdomain.com/social/callback/X/`
   - **Website URL:** Your application URL
   - **Terms of Service URL:** (Optional) Your ToS URL
   - **Privacy Policy URL:** (Optional) Your privacy policy URL

6. Click **"Save"**

### Step 4: Get API Credentials

1. Go to **"Keys and Tokens"** tab in your app
2. Under **"OAuth 2.0 Client ID and Client Secret"**:
   - Click **"Regenerate"** if needed
   - Copy the **Client ID** → This is your `X_CLIENT_ID`
   - Copy the **Client Secret** → This is your `X_CLIENT_SECRET`

> ⚠️ **Important:** The Client Secret is only shown once. Store it securely!

---

## Environment Configuration

### Django Settings (settings.py)

```python
# X (Twitter) API Configuration
X_CLIENT_ID = 'your_client_id_here'
X_CLIENT_SECRET = 'your_client_secret_here'
X_REDIRECT_URI = 'https://yourdomain.com/social/callback/X/'

# TIER CONFIGURATION
# Set to True if you have Enterprise Access (Full-Archive Search)
# Set to False for Free/Basic/Pro tiers (Recent Search)
X_USE_ENTERPRISE = False
```

### Environment Variables (.env)

```env
X_CLIENT_ID=your_client_id_here
X_CLIENT_SECRET=your_client_secret_here
X_REDIRECT_URI=https://yourdomain.com/social/callback/X/
X_USE_ENTERPRISE=False
```

---

## OAuth Redirect URI Configuration

The redirect URI must match exactly what's configured in the X Developer Portal.

### Development

```
http://127.0.0.1:8000/social/callback/X/
http://localhost:8000/social/callback/X/
```

### Production

```
https://yourdomain.com/social/callback/X/
```

> ⚠️ **Note:** X requires HTTPS for production redirect URIs. Localhost is allowed for development.

---

## Permissions & Scopes

The application requests the following OAuth scopes:

| Scope | Description | Required |
|-------|-------------|----------|
| `tweet.read` | Read tweets and timeline | ✅ Yes |
| `tweet.write` | Post and reply to tweets | ✅ Yes |
| `users.read` | Read user profile information | ✅ Yes |
| `offline.access` | Refresh tokens for long-term access | ✅ Yes |

### Code Reference

```python
# apps/social/utils/x.py
class XConfig:
    BASE_URL = "https://api.twitter.com/2"
    AUTH_URL = "https://twitter.com/i/oauth2/authorize"
    TOKEN_URL = "https://api.twitter.com/2/oauth2/token"
    
    SCOPES = [
        "tweet.read", 
        "tweet.write", 
        "users.read", 
        "offline.access"
    ]
```

---

## API Tiers & Limitations

X API has different access tiers with varying capabilities:

### Free Tier ($0/month)

| Feature | Limit |
|---------|-------|
| Post Tweets | 1,500/month |
| User Lookup | 500/month |
| **Search API** | ❌ **NOT AVAILABLE** |

> ⚠️ **Critical:** Free tier cannot use the search endpoint, which means **fetching tweet replies is not possible**. You will see a 403 Forbidden error when trying to search.

### Basic Tier ($100/month)

| Feature | Limit |
|---------|-------|
| Post Tweets | 3,000/month |
| Recent Search | 60 requests/15 min |
| User Lookup | 900/15 min |
| **Reply Fetching** | ✅ **SUPPORTED** |

> ✅ **Recommended:** Basic tier is the minimum required for full functionality.

### Pro Tier ($5,000/month)

| Feature | Limit |
|---------|-------|
| Post Tweets | 100,000/month |
| Recent Search | 300 requests/15 min |
| Full-Archive Search | Available |

### Enterprise Tier (Custom)

| Feature | Limit |
|---------|-------|
| Full-Archive Search | ✅ Available |
| Higher Rate Limits | Custom |

### Setting the Tier

```python
# For Basic/Pro tiers (Recent Search)
X_USE_ENTERPRISE = False  # Uses tweets/search/recent

# For Enterprise tier (Full-Archive Search)
X_USE_ENTERPRISE = True   # Uses tweets/search/all
```

---

## Development vs Production

### Development Setup

| Setting | Value |
|---------|-------|
| `X_REDIRECT_URI` | `http://127.0.0.1:8000/social/callback/X/` |
| Protocol | HTTP allowed for localhost |
| `X_USE_ENTERPRISE` | `False` |
| Rate Limits | Lower limits per 15-min window |

### Production Setup

| Setting | Value |
|---------|-------|
| `X_REDIRECT_URI` | `https://yourdomain.com/social/callback/X/` |
| Protocol | **HTTPS required** |
| `X_USE_ENTERPRISE` | Based on your tier |
| Rate Limits | Higher limits for paid tiers |

### Using ngrok for Local Testing

If you need to test with HTTPS locally:

```bash
# Install ngrok
npm install -g ngrok

# Create tunnel to local server
ngrok http 8000

# Use the ngrok URL as your redirect URI
# Example: https://abc123.ngrok.io/social/callback/X/

# Update X Developer Portal with the ngrok URL
```

---

## Troubleshooting

### Common Error: "403 Forbidden on Search"

**Cause:** You're on the Free tier which doesn't include Search API access.

**Solution:**
1. Upgrade to at least **Basic tier** ($100/month)
2. Or, accept limited functionality (cannot fetch replies)
3. Check your tier in X Developer Portal → Products

---

### Common Error: "Invalid Redirect URI"

**Cause:** The redirect URI doesn't match what's configured in X Developer Portal.

**Solution:**
1. Go to X Developer Portal → Your App → Settings
2. Check "User authentication settings"
3. Ensure redirect URI matches exactly (including trailing slash)
4. Wait a few minutes for changes to propagate

---

### Common Error: "Client Authentication Failed"

**Cause:** Invalid Client ID/Secret or incorrect auth header format.

**Solution:**
1. Verify credentials in X Developer Portal → Keys and Tokens
2. Ensure you're using **Basic Auth** for token exchange:
   ```python
   # Correct: Base64 encoded "client_id:client_secret"
   Authorization: Basic base64(client_id:client_secret)
   ```
3. Regenerate credentials if needed

---

### Common Error: "Rate Limit Exceeded (429)"

**Cause:** Too many API requests in the rate limit window.

**Solution:**
- Application handles rate limits with automatic retry
- Check `x-rate-limit-reset` header for reset time
- Wait for the window to reset (usually 15 minutes)
- Consider upgrading to a higher tier for more capacity

---

### Common Error: "Token Expired"

**Cause:** Access token expired (typically after 2 hours).

**Solution:**
- Application automatically refreshes tokens using `offline.access` scope
- If refresh fails, user needs to re-authenticate
- Check that refresh token is stored in database

---

### Common Error: "PKCE Verification Failed"

**Cause:** Code verifier doesn't match the challenge used during authorization.

**Solution:**
- Application generates PKCE pair automatically
- Ensure `code_verifier` is stored in session during auth flow
- Verify S256 challenge method is used

---

## API Rate Limits

### Free Tier

| Endpoint | Rate Limit |
|----------|------------|
| Post Tweet | 1,500/month |
| Get User | 500/month |

### Basic Tier

| Endpoint | Rate Limit |
|----------|------------|
| Post Tweet | 3,000/month |
| Recent Search | 60/15 min |
| Get User | 900/15 min |

### Pro Tier

| Endpoint | Rate Limit |
|----------|------------|
| Post Tweet | 100,000/month |
| Recent Search | 300/15 min |
| Get User | 900/15 min |

---

## Verification

After setup, verify the integration:

1. Navigate to `/social/` in your application
2. Click "Connect X (Twitter)"
3. Authorize with your X account
4. Verify your profile is fetched
5. Check if tweets are loaded
6. Test posting a reply to a tweet

### Testing Search (Basic+ Tier Required)

```python
# In Django shell
from apps.social.services.x import XService
from apps.social.models import SocialAccount

account = SocialAccount.objects.filter(platform='X').first()
tweets = XService.get_user_tweets(account)
print(f"Fetched {len(tweets)} tweets")
```

---

## Support Resources

- [X API Documentation](https://developer.twitter.com/en/docs/twitter-api)
- [X API v2 Reference](https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference)
- [OAuth 2.0 PKCE Guide](https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code)
- [X Developer Forum](https://twittercommunity.com/)
- [X API Status](https://api.twitterstat.us/)

---

*Last Updated: February 2026*
*API Version: X API v2*