Twitter Scraper - X Profile and Tweets, All in One avatar

Twitter Scraper - X Profile and Tweets, All in One

Pricing

from $5.00 / 1,000 profiles

Go to Apify Store
Twitter Scraper - X Profile and Tweets, All in One

Twitter Scraper - X Profile and Tweets, All in One

All-in-one Twitter scraper for X: one run returns profile metadata, recent tweets, media URLs and engagement counts for every handle, with no API key and no login. Use it for lead lists, competitor and audience research, or social monitoring. Clean structured output, ready for Sheets or a CRM.

Pricing

from $5.00 / 1,000 profiles

Rating

5.0

(1)

Developer

Goutam Soni

Goutam Soni

Maintained by Community

Actor stats

0

Bookmarked

15

Total users

3

Monthly active users

15 hours ago

Last modified

Share

The all-in-one Twitter scraper for X. Pass a list of usernames; get one clean record per user containing full profile metadata, recent tweets, media URLs, and engagement counts. No Twitter / X API key, no login, no per-run start fee. Built for spreadsheets, CRMs, dashboards, and AI / NLP pipelines.

What this Twitter scraper does

For each username, the actor returns one normalised record containing the full profile object plus recent tweets with media and engagement counts. All records share a single ordered schema.

Perfect for lead generation, audience research, influencer outreach, content / sentiment pipelines, brand monitoring, archive projects, and competitor analysis.

Why use this all-in-one Twitter scraper

  • One actor, one run, one record per user with both profile + tweets.
  • No Twitter / X API key required.
  • No login. Public profiles only.
  • Multi-tier resilient fetch so a single upstream blip never breaks your run.
  • Media URLs included for every tweet that has media (photos, video, animated GIF).
  • Exact engagement counts - likes, retweets, replies, quotes, views.
  • Residential proxy rotation built in.

What data you get per user

{
"ok": true,
"username": "exampleco",
"profile": {
"id": "1234567890",
"username": "exampleco",
"name": "Example User",
"description": "Example bio text",
"location": "Example City",
"url": "https://example.com",
"created_at": "2015-03-14T09:30:00.000Z",
"verified": true,
"verified_type": "business",
"protected": false,
"profile_image_url": "https://pbs.twimg.com/profile_images/.../avatar.jpg",
"profile_banner_url": "https://pbs.twimg.com/profile_banners/.../1500x500",
"metrics": {
"followers": 48200,
"following": 312,
"tweets": 5310,
"listed": 210,
"likes": 1840,
"media": 420
}
},
"tweets": [
{
"id": "1900000000000000001",
"url": "https://twitter.com/exampleco/status/1900000000000000001",
"text": "Our new release is out today. Full notes on the blog.",
"created_at": "2026-06-02T01:47:00.000Z",
"lang": "en",
"is_reply": false,
"is_retweet": false,
"metrics": { "likes": 1240, "retweets": 85, "replies": 32, "quotes": 6, "views": 48100 },
"media": [{ "type": "photo", "url": "https://pbs.twimg.com/media/EXAMPLE.jpg", "preview_url": "...", "alt": null }]
}
],
"timelineNewestAt": "2026-06-02T01:47:00.000Z",
"timelineAgeDays": 0,
"timelineStale": false,
"timelineRescue": "not_needed",
"scrapedAt": "2026-06-02T11:30:00.000Z"
}

Freshness fields

Every record carries the age of the tweets it returns, so old data is never mistaken for current data.

FieldMeaning
timelineNewestAtTimestamp of the newest tweet returned for this handle
timelineAgeDaysHow many days old that newest tweet is
timelineStaletrue when the newest tweet is more than 30 days old
timelineRescueOutcome of the freshness re-check (below)

When a handle's tweets look more than 30 days old, or none come back, the actor re-checks the profile once. timelineRescue tells you why a timeline looks old, which the age alone cannot:

  • not_needed - the tweets were already inside the freshness window
  • fresher - the re-check found newer tweets and they replaced the older ones. Only tweets confirmed as current are returned, so a handle whose timeline was out of date can come back with fewer tweets than requested (usually its 4 or 5 newest)
  • no_fresher - the re-check completed and found nothing newer, so the account is genuinely quiet
  • unavailable - the re-check could not complete, so treat the age as unverified

The practical difference is between a quiet account (no_fresher, the data is correct) and one whose age could not be confirmed (unavailable, worth retrying).

How to use the Twitter Scraper

  1. Click Try for free on the actor page.
  2. Enter the usernames to scrape.
  3. Set Max tweets per user (default 20). Set to 0 if you only want the profile.
  4. Click Save & Start. Download in JSON, CSV, Excel, XML, or HTML.

Top use cases

  • Lead generation + content audit in one pass - enrich a list of handles with bios, follower counts, and last 20 tweets.
  • Influencer outreach - filter by follower count + post recency for outreach lists.
  • Sentiment / brand monitoring - feed downstream NLP with both profile and tweets per account.
  • Competitor analysis - track what your competitors are saying alongside their audience size.
  • CRM enrichment - one row per contact handle with Twitter footprint.
  • AI / NLP training data - clean structured input for fine-tuning or classification.

Pricing

Pay-per-event. No per-run start fee. Failed lookups are never billed.

EventPrice
Per profile returned$0.005
Per tweet returned$0.001

Example: 50 handles with 20 tweets each = $0.005 × 50 + $0.001 × 1000 = $1.25. Apify's $5 platform free credit applies on first use.

Integrations

Apify API

$curl "https://api.apify.com/v2/datasets/{DATASET_ID}/items?format=json"

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("goat255/twitter-scraper-goat").call(run_input={
"usernames": ["exampleco", "acmecompany"],
"maxTweetsPerUser": 20,
})
for r in client.dataset(run["defaultDatasetId"]).iterate_items():
p = r["profile"]
print(f"@{p['username']:15} {p['metrics']['followers']:>12,} tweets={len(r['tweets'])}")

JavaScript / Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('goat255/twitter-scraper-goat').call({
usernames: ['exampleco'],
maxTweetsPerUser: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach(r => console.log(`@${r.username}: ${r.profile.metrics.followers} followers, ${r.tweets.length} tweets`));

No-code

Send results to Google Sheets, Slack, Zapier, Make, Amazon S3, HubSpot, or any webhook via Apify Integrations.

FAQ

Do I need a Twitter / X API key?

No. Public profiles only, no developer account required.

How many tweets per user?

Set any cap up to 5000 and you get as many recent tweets as are available for the handle. If a handle's timeline turns out to be out of date, you get the newest tweets that can be confirmed as current (usually 4 or 5) instead of older tweets that would look current. The profile is always returned in full.

Why use this instead of the separate profile and tweet actors?

This actor is the right choice when you need both in one place per handle - one Apify run, one dataset row per account, paired profile + tweets. If you only need one or the other, the dedicated Twitter / X Profile Scraper or Twitter / X Tweet Scraper are cheaper per result.

What if a profile is private or suspended?

A private account still returns its public profile, with protected: true and no tweets. A suspended or non-existent account returns ok: false with no profile and no tweets. You are billed only for the profiles and tweets actually returned, so a failed lookup costs nothing.

Are the follower counts exact?

Yes - exact integer follower / following / tweet / listed / favourites / media counts.

Can I export to CSV / Google Sheets / Excel?

Yes - JSON / CSV / Excel / XML / HTML all supported, plus native integrations.

Support

Found a missing field or a bug? Open an issue on the actor page. Reviews are read and replied to.

Privacy

To improve our actors we collect anonymized usage telemetry (run stats and input patterns). No personal account data is collected.