# 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*