X/Twitter Data API
Pricing
from $0.10 / 1,000 results
Pricing
from $0.10 / 1,000 results
Rating
0.0
(0)
Developer
quan qing
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
16 hours ago
Last modified
Categories
Share
X/Twitter Scraper — Profile, Tweets & Media API
Scrape public X/Twitter data in one call: user profile + latest tweets + media + followers. Export as JSON, CSV, or Excel. No OAuth approval, no login required for public data.
Why use this instead of the X/Twitter API?
| Problem with X API | How this Actor solves it |
|---|---|
| $100+/month for Basic tier, $5,000/mo for Pro | Pay-per-event — $0.00025 per result. No monthly fee. |
| OAuth approval can take days | No approval needed — paste a URL or @handle and run |
| 3+ API calls for profile + tweets + media | One call — profile endpoint returns everything in a single run |
| No email/lead extraction from bios | Auto-extracts emails and links from user bios |
| Rate limits (17k reads/mo on Basic) | No hard cap — scale to 10k+ profiles with concurrent runs |
| No followers list without enterprise tier | Followers/following with a browser cookie (free) |
| JSON only output | JSON, CSV, Excel, JSONL — pick your format |
Bottom line: if you need X/Twitter data for lead gen, research, or monitoring — this costs less, starts faster, and extracts more than the official API.
🚀 Quick Start — One-Call Profile
Paste a profile URL, @handle, or numeric user ID, and pull everything in one run.
{"profileUrls": "https://x.com/NASA\nhttps://twitter.com/elonmusk"}
Or use any of these input formats (all auto-detected):
{ "handles": "NASA, elonmusk, SpoxCHN_MaoNing" }
{ "userIds": "44196397, 813286" }
Default output: profile info + latest 20 tweets + media info.
📥 Input Reference
You pick who/what (the target) and what to extract (the switches). Mix and match freely.
Target (choose one or several)
| Field | What to paste | Example |
|---|---|---|
profileUrls | Full X/Twitter profile URLs, one per line | https://x.com/NASA |
handles | @handles, comma- or newline-separated. @ is optional | NASA, elonmusk |
userIds | Numeric user IDs (rest_id) | 44196397 |
searchQuery | Keyword to search X/Twitter users | AI researcher |
tweetUrls | Full tweet URLs, one per line | https://x.com/user/status/2090877991228264814 |
tweetIds | Numeric tweet IDs | 2090877991228264814 |
Extract switches (turn on what you need)
| Switch | Default | What it adds to output |
|---|---|---|
getProfile | ✅ on | bio, followers, following, verified status, account age, avatar, banner |
getRecentTweets | ✅ on | user's latest 20 tweets, text + media + engagement |
getRecentMedia | ❌ off | user's recent image & video posts as separate items |
getFollowers | ❌ off | list of accounts following the user (requires cookie) |
getFollowing | ❌ off | list of accounts the user follows (requires cookie) |
getRetweeters | ❌ off | list of accounts who retweeted a given tweet (requires cookie) |
includeBlueVerifiedFollowers | ❌ off | restrict followers list to blue-check subscribers |
includeTweetsForFollowers | ❌ off | pull latest tweet for each follower (context enrichment) |
Count knobs
| Field | Default | Max |
|---|---|---|
recentTweetCount | 20 | 200 |
recentMediaCount | 5 | 50 |
followListCount | 100 | 5000 |
Advanced (only when needed)
| Field | When to fill |
|---|---|
auth_token | Required for getFollowers, getFollowing, getRetweeters. X.com auth cookie. |
ct0 | Required together with auth_token. X.com csrf cookie. |
proxyUrl | Custom HTTP/SOCKS5 proxy if you need a specific exit IP. |
🔑 Which Identifier to Use?
X/Twitter accounts have two names:
| Name | Example | Unique? | Use? |
|---|---|---|---|
| @handle (screen name) | @NASA | ✅ yes | yes — always this |
| Display name | NASA | ❌ no | never |
Input accepts handle with or without @. Pasting a full profile URL works too — @handle is auto-extracted.
For numeric input (user_id), find it in any tweet URL like x.com/123456789/... where 123456789 is the user_id.
📊 Output Fields
Every data item in the dataset is a flat JSON row. Two views are pre-configured:
User Profile row (item_type=user): @handle, display name, bio, location, links, extracted email, extracted bio links, account creation date, account age (days), followers/following ratio, verified/blue/protected flags, professional type, business email, fetched timestamp.
Tweet row (item_type=tweet or media): tweet text, tweet URL, created date, language, image/video URLs, like/retweet/reply/quote/view counts, retweet/reply/pinned/quote flags, reply-to handle & id, conversation id.
Filter by item_type to slice the data: user, tweet, media, follower, following, retweeter, search_result.
💡 Common Use Cases
1. Lead generation from a KOL's followers
{"handles": "naval","getFollowers": true,"followListCount": 1000}
Then in the dataset, filter item_type=follower and sort by followers_count desc to find high-value accounts. bio_has_email=true flags leads with public contact info.
2. RAG / LLM knowledge base from a topic influencer
{"handles": "paulg, sama, sama","getRecentTweets": true,"recentTweetCount": 100}
Each tweet becomes one row with full text + media URLs + engagement metrics — ready to feed into a vector store.
3. Market research user profile dump
{"profileUrls": "https://x.com/AIresearcher1\nhttps://x.com/AIresearcher2\n...","getProfile": true,"getRecentTweets": false}
Lightweight: just bio, followers, account age. Cheap and fast.
4. Competitive tweet monitoring
{"handles": "competitor1, competitor2","getRecentTweets": true,"getRecentMedia": true}
Both text and media surface in one dataset. Use view_count to find viral posts.
5. Extract retweeters of a viral post
{"tweetIds": "2090877991228264814","getRetweeters": true,"followListCount": 500}
Who amplified this post? Perfect for influencer outreach.
❓ Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Empty dataset, no error | Invalid input — the target doesn't exist or is private | Check the handle/ID; private accounts return no public data |
code 353 — Could not authenticate you | X.com rate-limit / session expired | Wait 60s, retry; the Actor rotates proxies automatically |
code 32 — Could not authenticate you | Cookie expired/invalid | Refresh auth_token + ct0 from a logged-in browser session |
| Followers/following returns empty | Missing or invalid auth cookie | Provide fresh auth_token + ct0 in Advanced fields |
| Email field is empty | Bio doesn't contain a public email | Try alternative accounts; not all users publish email publicly |
| Tweet URLs are short (t.co) | X uses t.co redirects | This is normal — use the tweet_url field for the resolved canonical URL |
| Run takes >2 min for one profile | Network throttle or large followers list | Reduce followListCount; split into smaller batches |
| Some followers missing | Cursor boundary; X.com only returns first ~1000 per page | Reduce target count; for >1000 use pagination across multiple runs |
❓ FAQ
Do I need an X/Twitter developer account or API key?
No. This Actor scrapes public data from x.com directly. No developer portal, no API key, no OAuth approval. Just paste a URL or @handle and run.
Is there a free tier? How much does it cost?
Yes. Apify gives every new account $5 free credit. At $0.00025 per result, that's ~20,000 results free. After that, pay-per-event — no monthly subscription. See the Pricing section for cost examples.
Can I extract followers without the paid X API?
Yes. Provide a valid auth_token + ct0 cookie from your logged-in x.com browser session. The Actor uses your session to pull followers/following lists — no enterprise API tier needed. See Authentication & Proxies.
Does this work with private or protected accounts?
No. Protected accounts (locked profiles) return no public data. The Actor only scrapes publicly visible profiles, tweets, and media.
How many profiles can I scrape in one run?
There's no hard limit. For best results, keep batches under 200 profiles per run. For 1,000+ profiles, split into multiple runs or use the API for concurrent execution.
Can I use this for lead generation?
Yes. The bio_has_email and bio_has_link fields flag leads with public contact info. Combine with getFollowers to extract follower lists from a target KOL's audience, then filter by email presence and follower count.
What's the difference between @handle and user ID?
| @handle (screen_name) | User ID (rest_id) | |
|---|---|---|
| Example | @NASA | 44196397 |
| Changes? | Can be changed by user | Permanent |
| Use | Most common input | When handle is unknown |
Both work as input. The Actor auto-detects which one you provided.
Can I schedule recurring scrapes?
Yes. Use Apify Scheduler to run the Actor daily/weekly. Or use the API to trigger runs from a cron job, Airflow, or n8n.
Does the Actor respect rate limits?
The Actor rotates proxies automatically and throttles requests to avoid X.com blocks. For large jobs, spread runs across time to stay under the radar.
🔌 API Integration
Start a run
POST https://api.apify.com/v2/acts/7aVQYR4P86AUB5dFs/runs?token=YOUR_API_TOKENContent-Type: application/json{"handles": "NASA, elonmusk","getProfile": true,"getRecentTweets": true,"recentTweetCount": 50}
Wait + fetch (synchronous)
POST https://api.apify.com/v2/acts/7aVQYR4P86AUB5dFs/run-sync-get-dataset-items?token=YOUR_API_TOKENContent-Type: application/json{"handles": "NASA","getRecentTweets": true}
The response includes the full dataset inline as a JSON array.
Python SDK
from apify_client import ApifyClientclient = ApifyClient("YOUR_API_TOKEN")run = client.actor("7aVQYR4P86AUB5dFs").call({"handles": "NASA, elonmusk","getRecentTweets": True,"getRecentMedia": True,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["item_type"], item.get("screen_name"))
Node.js SDK
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });const run = await client.actor('7aVQYR4P86AUB5dFs').call({handles: 'NASA, elonmusk',getRecentTweets: true,getRecentMedia: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();items.forEach(i => console.log(i.item_type, i.screen_name));
No-code integrations
This Actor works with any tool that can call a REST API or trigger an Apify run.
Zapier — connect to 6,000+ apps:
- Create a Zap with "Apify — Run Actor" trigger
- Map your input fields (handles, getProfile, etc.)
- Use "Apify — Fetch Dataset Items" as the next step
- Send results to Google Sheets, HubSpot, Notion, Slack, etc.
n8n (self-hosted or cloud):
{"nodes": [{"type": "n8n-nodes-base.httpRequest","parameters": {"method": "POST","url": "https://api.apify.com/v2/acts/7aVQYR4P86AUB5dFs/run-sync-get-dataset-items","queryParameters": { "token": "YOUR_API_TOKEN" },"bodyParameters": { "handles": "NASA", "getRecentTweets": true }}}]}
Make (Integromat):
- Add an "HTTP" module → POST to
https://api.apify.com/v2/acts/7aVQYR4P86AUB5dFs/run-sync-get-dataset-items - Pass your API token as query parameter
- Map the JSON response to downstream modules (Google Sheets, Airtable, email, etc.)
Airflow / cron:
# Airflow PythonOperator examplefrom apify_client import ApifyClientdef scrape_twitter(handles: list[str]):client = ApifyClient("YOUR_API_TOKEN")run = client.actor("7aVQYR4P86AUB5dFs").call({"handles": ",".join(handles),"getRecentTweets": True,})return list(client.dataset(run["defaultDatasetId"]).iterate_items())
💰 Pricing Model (Pay Per Event)
This Actor uses Apify Pay-Per-Event pricing. You only pay for results — no monthly subscription.
| Event | When it fires | Cost |
|---|---|---|
| Dataset item | Each row pushed to dataset (profile, tweet, media, follower, etc.) | $0.00025 |
| Actor start | Once per run (per GB of memory) | $0.001 / GB |
Store discounts (automatic at higher usage tiers):
| Tier | Per item price | vs. base |
|---|---|---|
| No discount | $0.00025 | — |
| Bronze | $0.00020 | 20% off |
| Silver | $0.00015 | 40% off |
| Gold | $0.00010 | 60% off |
Cost examples (default 4 GB memory, no discount):
| Scenario | Items | Estimated cost |
|---|---|---|
| One profile + 20 tweets | 21 | ~$0.01 |
| 100 profiles, no tweets | 100 | ~$0.03 |
| 1,000 followers from one user | 1,000 | ~$0.25 |
| 10,000 tweets across 50 users | 10,000 | ~$2.70 |
You see the running cost in the Apify Console while the run is in progress.
🔒 Authentication & Proxies
Public data (profiles, tweets, media, search results) — no auth needed. The Actor uses Apify's built-in proxy rotation.
Authenticated data (followers, following, retweeters, bookmarks) — requires a valid auth_token + ct0 cookie pair. You can:
- Log into x.com in your browser
- Open DevTools → Application → Cookies → x.com
- Copy the values of
auth_tokenandct0 - Paste them into the Actor's Advanced fields
Cookies are encrypted in transit and discarded after the run.
📦 Output & Export
After each run, the Output tab in Apify Console shows results in a table view. Available exports:
- JSON — full structured output
- CSV — Excel/Sheets compatible
- Excel — formatted xlsx with headers
- JSONL — newline-delimited for streaming pipelines
Items are typed by item_type so you can filter in your code:
users = [i for i in items if i["item_type"] == "user"]tweets = [i for i in items if i["item_type"] == "tweet"]followers = [i for i in items if i["item_type"] == "follower"]
⚡ Performance Notes
- One profile = ~5–15 seconds with default switches
- Followers list scales linearly: 100 followers ≈ 8s, 1000 followers ≈ 60s, 5000 followers ≈ 5min
- Proxies rotate automatically for anonymous operation
- Concurrent runs supported — you can launch multiple runs in parallel for batch jobs
🆚 How It Compares
| Capability | This Actor | Typical alternatives |
|---|---|---|
| One-call profile + tweets + media | ✅ | ❌ usually separate calls |
| Multi-format input (URL/handle/user_id) | ✅ | partial |
| Bio email auto-extraction | ✅ | ❌ |
| Followers list without API approval | ✅ (with cookie) | requires paid X API tier |
| Pay-per-event pricing | ✅ | ❌ usually monthly subscription |
| Dataset with typed items | ✅ | partial |
| No OAuth approval | ✅ | ❌ |
📞 Support
- Issues: open a ticket on the Actor's Issues tab in Apify Console
- Documentation: see this README + the Actor's Input/Output tabs
- Status: run the Actor with empty input to get a health-check response