PythonTwitter APIX APITutorialtweepysnscrape

How to Use the Twitter API with Python — 2026 Tutorial

Step-by-step Python tutorial for the Twitter API in 2026. Working code for search, users, DMs, pagination, retries — plus a tweepy migration guide.

GetXAPI·
Python Twitter API tutorial — full working code samples for 2026

Most "how to use the Twitter API in Python" guides are stuck in 2022 — they tell you to install tweepy, set up four OAuth credentials, and pretend the free tier still exists. That advice is broken in 2026. The free tier was removed in February 2023, the pay-per-use model that replaced it makes every request cost money, and tweepy carries the full weight of the official X API's quirks.

This tutorial shows you the version that actually works in 2026: a Python integration with the Twitter / X API that ships in 30 seconds, has no developer-account approval queue, costs $0.05 per 1,000 tweets, and works with a single requests import. Every section has runnable code. Every endpoint is real. By the end you'll have a working Python client for search, user lookups, followers, tweet creation, DMs, and pagination.

TL;DR: The fastest Python integration is pip install requests, sign up at getxapi.com, grab your API key, and run the snippet below. The rest of this guide expands on every common use case.

import requests

API_KEY = "YOUR_API_KEY"  # get one in 30 seconds at getxapi.com/signup

resp = requests.get(
    "https://api.getxapi.com/twitter/user/info",
    params={"userName": "elonmusk"},
    headers={"Authorization": f"Bearer {API_KEY}"},
)
user = resp.json()["data"]
print(user["name"], "—", user["followers"], "followers")

Run that with a real key and you get back a JSON profile with name, followers, bio, verification status, and 30+ other fields. Total setup time: under a minute.

Three Python Paths to Twitter Data in 2026

Most Python developers reach the Twitter API through one of three libraries. Each has a different cost, complexity, and reliability profile.

Path What it is Cost in 2026 Setup time When to pick it
GetXAPI + requests Third-party REST API. Single Bearer header. $0.05 per 1,000 tweets ($0.001 per call). $0.10 free at signup. < 5 minutes Most data-collection workloads — research, analytics, monitoring, bots, dashboards.
tweepy + Official X API Official Python library wrapping the X API v2. OAuth 2.0 / Bearer token. $0.005 per post read, $0.010 per user lookup, $0.015 per write. ~$5–$10 per 1,000 tweets. Hours to days (developer-account approval) Only when you need OAuth user-delegated flows (apps where end users log in with their X account).
snscrape Open-source scraping library. No auth required. $0 — but increasingly broken. < 5 minutes (until it breaks) Almost never in 2026. The maintainers paused active development in 2023; most endpoints are unreliable or fully broken after X tightened scraping defenses.

Most Python tutorials still default to tweepy. That's a 2022-shaped recommendation. In 2026, tweepy means paying official X API rates (100x more per tweet) for an integration that takes a developer-account application, OAuth setup, and rate-limit retry logic on top. For everything except OAuth-login apps, GetXAPI is faster, cheaper, and simpler.

Quick Start: GetXAPI + Python in 5 Minutes

Step 1 — Install requests

pip install requests

That's the entire dependency. No SDK, no compiled extensions. If you're using httpx or aiohttp already, those work too — the API is plain JSON over HTTPS.

Step 2 — Get your API key

Sign up at getxapi.com/signup with Google or email. The dashboard generates your unique Bearer key immediately — no developer-account application, no approval queue, no credit card. Every new account gets $0.10 in free credits, which covers about 100 API calls (~2,000 tweets) — enough to validate every endpoint before you commit.

For the deeper context on what an "X API key" actually is and the four credential types in the official ecosystem, see What is a Twitter API key?.

Step 3 — Make your first call

import os
import requests

API_KEY = os.environ["GETXAPI_KEY"]  # never hardcode keys

def get_user(username: str) -> dict:
    resp = requests.get(
        "https://api.getxapi.com/twitter/user/info",
        params={"userName": username},
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    resp.raise_for_status()
    return resp.json()["data"]

user = get_user("elonmusk")
print(f"{user['name']} (@{user['userName']})")
print(f"  Followers:  {user['followers']:,}")
print(f"  Following:  {user['following']:,}")
print(f"  Verified:   {user.get('isVerified', False)}")

Save your key as an environment variable (export GETXAPI_KEY=...) and run the script. Successful response includes the user's full profile with all fields populated by default — no field-expansion gymnastics like the official X API v2 requires.

Eight Common Python Use Cases (with Working Code)

This section covers the eight things most Python developers actually want to do with Twitter data. Every snippet is runnable — copy it into a file, swap the API key, and execute.

1. Search Recent Tweets

def search_tweets(query: str, max_results: int = 20) -> list[dict]:
    resp = requests.get(
        "https://api.getxapi.com/twitter/tweet/advanced_search",
        params={"q": query, "product": "Latest"},
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    resp.raise_for_status()
    return resp.json().get("tweets", [])[:max_results]

tweets = search_tweets("from:elonmusk filter:replies")
for t in tweets:
    print(f"[{t['createdAt']}] {t['text'][:140]}")

The q parameter accepts the full Twitter search-operator syntax: from:, to:, since:, until:, min_faves:, min_retweets:, lang:, filter:, etc. For the complete operator reference, see the Twitter advanced search operators guide.

2. User Profile Lookup

def get_user_info(username: str) -> dict:
    resp = requests.get(
        "https://api.getxapi.com/twitter/user/info",
        params={"userName": username},
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    resp.raise_for_status()
    return resp.json()["data"]

profile = get_user_info("naval")
print(profile["name"], "—", profile["followers"], "followers")
print("Bio:", profile["description"])
print("Joined:", profile["createdAt"])

Returns the full profile object: name, username, description, follower / following counts, verification status, profile images, account creation date, and pinned tweet ID.

3. Get a User's Recent Tweets

def get_user_tweets(username: str) -> list[dict]:
    resp = requests.get(
        "https://api.getxapi.com/twitter/user/tweets",
        params={"userName": username},
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    resp.raise_for_status()
    return resp.json().get("tweets", [])

for t in get_user_tweets("paulg")[:5]:
    print(f"♥ {t['likeCount']:>6}{t['retweetCount']:>5}  {t['text'][:80]}")

Each tweet object has the full author data inline — no field-expansion needed. Sort by engagement, filter by date, or pipe straight into your dashboard.

4. Get Followers

def get_followers(username: str, limit: int = 200) -> list[dict]:
    resp = requests.get(
        "https://api.getxapi.com/twitter/user/followers",
        params={"userName": username},
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    resp.raise_for_status()
    return resp.json().get("followers", [])[:limit]

followers = get_followers("elonmusk")
print(f"Got {len(followers)} followers")
verified = [f for f in followers if f.get("isVerified")]
print(f"  ↪ {len(verified)} verified")

For verified-only followers without filtering client-side, use the verified_followers endpoint instead — it returns a curated list and skips the rest of the noise.

5. Get Replies to a Tweet

def get_tweet_replies(tweet_id: str) -> list[dict]:
    resp = requests.get(
        "https://api.getxapi.com/twitter/tweet/replies",
        params={"tweetId": tweet_id},
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    resp.raise_for_status()
    return resp.json().get("replies", [])

replies = get_tweet_replies("1234567890")
for r in replies[:10]:
    print(f"@{r['author']['userName']}: {r['text'][:100]}")

This is one of the endpoints the official X API makes painfully expensive — at $0.005 per resource, fetching 100 replies on the official API costs $0.50. On GetXAPI it's a single $0.001 call.

6. Advanced Search with Date Ranges

from datetime import date

def date_range_search(query: str, start: date, end: date) -> list[dict]:
    full_query = f"{query} since:{start.isoformat()} until:{end.isoformat()}"
    resp = requests.get(
        "https://api.getxapi.com/twitter/tweet/advanced_search",
        params={"q": full_query, "product": "Latest"},
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    resp.raise_for_status()
    return resp.json().get("tweets", [])

results = date_range_search(
    "openai",
    start=date(2026, 4, 1),
    end=date(2026, 5, 1),
)
print(f"April 2026 — {len(results)} tweets matching 'openai'")

The since: / until: operators take YYYY-MM-DD dates. For deep historical sweeps that go beyond the rolling 7-day window, chunk your query by date range and stitch the results together — the Twitter advanced search operators guide covers the chunking pattern.

7. Send a Tweet (Write Action)

def send_tweet(text: str, login_cookies: str) -> dict:
    resp = requests.post(
        "https://api.getxapi.com/twitter/tweet/create",
        json={"text": text, "loginCookies": login_cookies},
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    resp.raise_for_status()
    return resp.json()

result = send_tweet(
    text="Posting from Python via GetXAPI 🐍",
    login_cookies=os.environ["TWITTER_LOGIN_COOKIES"],
)
print("Tweet ID:", result.get("tweet_id"))

Write actions (tweet/create, tweet/favorite, tweet/retweet, dm/send) take your X login cookies as a parameter — they're used in-flight to authorize the action and are never stored. For the full DM workflow, see Sending Twitter DMs via API.

8. Send a Direct Message

def send_dm(recipient_username: str, message: str, login_cookies: str) -> dict:
    resp = requests.post(
        "https://api.getxapi.com/twitter/dm/send",
        json={
            "userName": recipient_username,
            "text": message,
            "loginCookies": login_cookies,
        },
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    resp.raise_for_status()
    return resp.json()

send_dm(
    recipient_username="bozad",
    message="Hello from Python",
    login_cookies=os.environ["TWITTER_LOGIN_COOKIES"],
)

DM endpoints cost $0.002 per call. The recipient must accept DMs from non-followers, or you must already be following each other — no API can override that platform-level setting.

Start building with GetXAPI

$0.05 per 1,000 tweets. $0.10 free credits. No credit card required.

Pagination in Python

Most Twitter API endpoints return paginated results. GetXAPI uses cursor-based pagination — every response includes next_cursor and has_more flags so you can stream through pages cleanly.

def paginate(url: str, params: dict, max_pages: int = 10) -> list[dict]:
    all_items = []
    cursor = None

    for _ in range(max_pages):
        if cursor:
            params["cursor"] = cursor
        resp = requests.get(
            url,
            params=params,
            headers={"Authorization": f"Bearer {API_KEY}"},
        )
        resp.raise_for_status()
        data = resp.json()

        items = data.get("tweets") or data.get("followers") or data.get("replies") or []
        all_items.extend(items)

        if not data.get("has_more"):
            break
        cursor = data.get("next_cursor")

    return all_items

# Example: get up to 200 tweets matching a query
results = paginate(
    "https://api.getxapi.com/twitter/tweet/advanced_search",
    params={"q": "from:elonmusk", "product": "Latest"},
    max_pages=10,
)
print(f"Fetched {len(results)} tweets across paginated calls")

Compare with tweepy.Paginator against the official X API: same pattern, but the tweepy version needs tweet_fields=, expansions=, user_fields= — and you pay $0.005 per result instead of $0.001 per call.

Error Handling and Retries in Python

Production code should handle transient failures gracefully. Even on a no-rate-limit API like GetXAPI, network errors and upstream X outages still happen.

import time
import requests
from requests.exceptions import RequestException

def fetch_with_retry(url: str, params: dict, max_retries: int = 3) -> dict:
    headers = {"Authorization": f"Bearer {API_KEY}"}
    delay = 1.0

    for attempt in range(max_retries):
        try:
            resp = requests.get(url, params=params, headers=headers, timeout=15)
            if resp.status_code == 429:
                # Rare on GetXAPI, but handle it for defensive correctness
                wait = float(resp.headers.get("Retry-After", delay))
                time.sleep(wait)
                continue
            if resp.status_code >= 500:
                time.sleep(delay)
                delay *= 2
                continue
            resp.raise_for_status()
            return resp.json()
        except RequestException as exc:
            if attempt == max_retries - 1:
                raise
            time.sleep(delay)
            delay *= 2

    raise RuntimeError("Exhausted retries")

For more elegant retry logic, the tenacity library is excellent — wrap any function with @retry(stop=stop_after_attempt(3), wait=wait_exponential()) and you get exponential backoff for free.

Rate Limits — What You Actually Have to Handle

This is where Python integrations that target the official X API get painful, and where GetXAPI's design pays off.

Official X API: every endpoint has a 15-minute rate-limit window (and some have additional 24-hour daily caps). Hitting a limit returns 429 Too Many Requests with x-rate-limit-reset headers. Production tweepy code needs per-endpoint queues, exponential backoff, and reset-time parsing — typically 100–200 lines of scaffolding before your first business-logic line.

GetXAPI: no platform-level rate limits. The same Python loop that hits the API once works for 10,000 calls. You don't need queues, backoff, or reset-time parsing for normal-volume workloads — the simple loop is enough.

For the full per-endpoint rate-limit comparison and the headers you need to read on the official API, see the Twitter API rate limits comparison.

The cheapest Twitter API. Try it free.

$0.05 per 1,000 tweets. $0.10 free credits. No credit card required.

Async Python with httpx (Advanced)

For high-throughput scrapers and concurrent fetches, drop in httpx.AsyncClient and run requests in parallel.

import asyncio
import httpx

API_KEY = os.environ["GETXAPI_KEY"]

async def fetch_user(client: httpx.AsyncClient, username: str) -> dict:
    resp = await client.get(
        "https://api.getxapi.com/twitter/user/info",
        params={"userName": username},
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    resp.raise_for_status()
    return resp.json()["data"]

async def fetch_many(usernames: list[str]) -> list[dict]:
    async with httpx.AsyncClient(timeout=15) as client:
        tasks = [fetch_user(client, u) for u in usernames]
        return await asyncio.gather(*tasks)

usernames = ["elonmusk", "naval", "paulg", "patio11", "sama"]
profiles = asyncio.run(fetch_many(usernames))
for p in profiles:
    print(p["name"], "—", p["followers"], "followers")

asyncio.gather runs all five lookups concurrently. On GetXAPI this is fine because there's no platform-level rate limit to coordinate around. On the official X API you'd need a semaphore plus per-endpoint window tracking to avoid burst-throttling.

Migrating from tweepy to GetXAPI

If you have a tweepy codebase and want to move to GetXAPI, the translation is direct. The two libraries cover the same surface area; only the auth model and method names change.

tweepy method (Official X API) GetXAPI equivalent
client.get_user(username="...") GET /twitter/user/info?userName=...
client.get_users_tweets(user_id, max_results=...) GET /twitter/user/tweets?userName=...
client.search_recent_tweets(query=...) GET /twitter/tweet/advanced_search?q=...
client.get_users_followers(user_id) GET /twitter/user/followers?userName=...
client.get_tweet(tweet_id) GET /twitter/tweet/detail?tweetId=...
client.create_tweet(text=...) POST /twitter/tweet/create
client.create_direct_message(...) POST /twitter/dm/send

A side-by-side example — fetching a user's last 20 tweets:

# Before: tweepy + Official X API
import tweepy

client = tweepy.Client(bearer_token="OFFICIAL_X_BEARER_TOKEN")
user = client.get_user(username="elonmusk").data
tweets = client.get_users_tweets(
    user.id,
    max_results=20,
    tweet_fields=["created_at", "public_metrics"],
    expansions=["author_id"],
).data

# After: requests + GetXAPI
import requests

resp = requests.get(
    "https://api.getxapi.com/twitter/user/tweets",
    params={"userName": "elonmusk"},
    headers={"Authorization": f"Bearer {GETXAPI_KEY}"},
)
tweets = resp.json()["tweets"]

The GetXAPI version is roughly half the lines, returns full author and engagement data inline (no expansions, no field selection), and costs ~100x less per tweet. For the full feature-by-feature breakdown, see Twitter API v2 vs GetXAPI.

Build a Python SDK Wrapper (Drop-in Class)

For larger projects, wrap the API in a small client class. Save this as getxapi_client.py and import it from anywhere:

import os
import requests
from typing import Optional

class GetXAPI:
    BASE = "https://api.getxapi.com"

    def __init__(self, api_key: Optional[str] = None, timeout: int = 15):
        self.key = api_key or os.environ["GETXAPI_KEY"]
        self.timeout = timeout
        self.session = requests.Session()
        self.session.headers["Authorization"] = f"Bearer {self.key}"

    def _get(self, path: str, **params) -> dict:
        resp = self.session.get(f"{self.BASE}{path}", params=params, timeout=self.timeout)
        resp.raise_for_status()
        return resp.json()

    def _post(self, path: str, **body) -> dict:
        resp = self.session.post(f"{self.BASE}{path}", json=body, timeout=self.timeout)
        resp.raise_for_status()
        return resp.json()

    def user(self, username: str) -> dict:
        return self._get("/twitter/user/info", userName=username)["data"]

    def search(self, query: str, product: str = "Latest") -> list[dict]:
        return self._get("/twitter/tweet/advanced_search", q=query, product=product).get("tweets", [])

    def user_tweets(self, username: str) -> list[dict]:
        return self._get("/twitter/user/tweets", userName=username).get("tweets", [])

    def followers(self, username: str) -> list[dict]:
        return self._get("/twitter/user/followers", userName=username).get("followers", [])

    def replies(self, tweet_id: str) -> list[dict]:
        return self._get("/twitter/tweet/replies", tweetId=tweet_id).get("replies", [])

    def post_tweet(self, text: str, login_cookies: str) -> dict:
        return self._post("/twitter/tweet/create", text=text, loginCookies=login_cookies)


# Usage
client = GetXAPI()
print(client.user("naval")["name"])
print(len(client.search("from:patio11", )))

That's a 30-line SDK that handles connection pooling (via requests.Session), timeouts, auth, and the most common endpoints. Extend it with pagination, retries, and async variants as your needs grow.

Get Your Python Twitter API Key

GetXAPI gives every new account $0.10 in free credits at signup, with no credit card required — enough to run every snippet in this tutorial. Sign up with Google or email, copy your Bearer key, and your first Python call is one minute away.

Get your API key → · View pricing · Cost calculator

For the official-route walkthrough (developer console, OAuth credentials, common rejection reasons), see How to Get a Twitter API Key (2026 Step-by-Step). For the full feature comparison against the official API, read Twitter API v2 vs GetXAPI.


Pricing data verified May 6, 2026 from the official X API pricing page and GetXAPI pricing. All Python snippets tested against live GetXAPI endpoints.

Frequently Asked Questions

For most use cases, plain `requests` against GetXAPI is the best Python integration in 2026. It costs ~100x less per tweet than `tweepy` against the official X API, takes 30 seconds to set up, and handles search, user lookups, follower exports, replies, and DMs without OAuth scaffolding. Use `tweepy` only when you specifically need OAuth user-delegated flows (apps where end users sign in with their X account).

`snscrape` is largely broken in 2026. The maintainers paused active development in 2023 after X tightened its scraping defenses, and most endpoints (search, user timelines, followers) are unreliable or fully broken. Use a real API instead.

GetXAPI at $0.001 per call (~20 tweets) — about $0.05 per 1,000 tweets — is the cheapest mainstream Python-friendly Twitter API. The official X API costs $0.005 per post read (about $5 per 1,000 tweets), so GetXAPI is roughly 100x cheaper for read-heavy data collection. New GetXAPI accounts get $0.10 in free credits at signup, which is enough to test every endpoint before committing.

For the official X API: respect `x-rate-limit-remaining` headers, sleep until `x-rate-limit-reset` on 429s, and run separate queues per endpoint window. For GetXAPI: the simple loop is enough — there are no platform-level rate caps, so production code is shorter. The full headers and pattern reference is in the [Twitter API rate limits comparison](/twitter-api-rate-limits).

Yes, `tweepy` is still maintained, but it's married to the official X API — every cost, rate-limit, and authentication constraint of the official API also applies to `tweepy`. The library itself is fine; the underlying API economics make it expensive for data-collection workloads.

There's no separate "Twitter API" package — the API is HTTP. To use the GetXAPI Twitter API in Python, run `pip install requests` and authenticate with a single Bearer header. To use the official X API, run `pip install tweepy` and configure OAuth credentials.

Only if you go through the official X API. Sign up for a developer account at `console.x.com`, get an approved use case, generate Bearer + OAuth credentials, and configure them in `tweepy`. To skip all of that, use GetXAPI — sign up with email, copy your Bearer key, and start making Python requests immediately. For more on the credential differences, see [What is a Twitter API key?](/twitter-api-key).

Yes. Use `httpx.AsyncClient` (or `aiohttp`) to make concurrent requests. With GetXAPI you can run dozens of requests in parallel without coordinating around rate-limit windows. Against the official X API you need a semaphore plus per-endpoint window tracking to avoid burst-throttling — see the async section above for a working example.

Check out similar blogs

More guides on the Twitter/X API, scraping, and pricing.

Twitter Search API guide and advanced search operators reference for 2026
Twitter Search APITwitter API

Twitter Search API & Advanced Operators (2026 Guide)

Twitter Search API guide for 2026 — every advanced search operator (from:, to:, min_faves:, since:, until:) with working code in curl, Python, JavaScript.

GetXAPI·
twitterapi.io alternative — migrate to GetXAPI guide for 2026
twitterapi.io alternativeGetXAPI

twitterapi.io Alternative — Migrate to GetXAPI 3x Cheaper

twitterapi.io alternative migration guide — cut your Twitter API bill 3x without rewriting. Step-by-step base URL, auth header, and response-shape mapping.

GetXAPI·
Twitter scraping best practices for production workflows in 2026
Twitter ScrapingTwitter API

Twitter Scraping — Best Practices for Production in 2026

Production-grade Twitter scraping patterns — retry logic, pagination, proxy strategy, rate-limit handling, and cost optimization for any third-party API.

GetXAPI·
Twitter API cost in 2026 — complete pricing guide and ROI scenarios
Twitter APIX API

Twitter API Cost 2026: Complete Pricing Guide [$0–$42K]

X moved to pay-per-use in February 2026. Compare official pricing, third-party APIs, and real monthly bills at every volume — with ROI scenarios.

GetXAPI·
Twitter DM API guide — bots, rate limits, and error handling for 2026
Twitter DM APITwitter DM Bot

Twitter DM API — Bots, Rate Limits & Errors (2026)

Send Twitter DMs via API in 2026 without OAuth pain. Build DM bots, handle daily rate limits, fix sending failures — with full code examples.

GetXAPI·
Twitter API v2 vs GetXAPI — feature-by-feature comparison
Twitter API v2GetXAPI

Twitter API v2 vs GetXAPI — Feature-by-Feature Comparison

Side-by-side comparison of the Twitter API v2 and GetXAPI. Endpoints, pricing, rate limits, auth, and response format — honest breakdown of where each wins.

GetXAPI·
Best Twitter scraper 2026 — API, browser, and Python tools compared
Twitter ScraperBest Twitter Scraper

Best Twitter Scraper 2026: API, Browser & Python Compared

Compare the best Twitter scrapers in 2026 — official API, third-party APIs, browser scrapers, and Python libraries. What works, what gets you sued, what each costs.

GetXAPI·
Step-by-step guide to getting a Twitter (X) API key in 2026
Twitter API KeyX API Key

How to Get a Twitter API Key in 2026 (Step-by-Step Guide)

The X developer portal changed completely in 2026. Here's exactly how to get your X / Twitter API key — the official way and the 30-second alternative.

GetXAPI·