Twitter Profile Scraper - Followers and Bio, No API Key avatar

Twitter Profile Scraper - Followers and Bio, No API Key

Pricing

from $0.14 / 1,000 profile returneds

Go to Apify Store
Twitter Profile Scraper - Followers and Bio, No API Key

Twitter Profile Scraper - Followers and Bio, No API Key

Scrape X (Twitter) profiles by handle. You get one row per handle: followers, following, post count, name, bio and verification. It works without an API key or login. It reads profiles only, not search results. $0.14/1k profiles.

Pricing

from $0.14 / 1,000 profile returneds

Rating

5.0

(1)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

1

Bookmarked

46

Total users

13

Monthly active users

19 hours ago

Last modified

Share

Twitter Profile Scraper: follower counts, bio and verification for any public handle

Give it a list of X handles and you get one flat row per account: followers, following, post count, display name, bio and both verification flags. No API key, no login, nothing to sign up for.

The awkward part, said up front: this returns the profile only, not the tweets on it. And a field the account never filled in, like a location, comes back null.

InputUsernames, or x.com/handle links
OutputOne row per profile
CeilingNo cap. One row per unique handle you send
Account neededNone from you
Price$0.14 per 1,000 profiles, flat on every plan

👤 What Twitter Profile Scraper does

You hand it handles, it hands back the profile record behind each one. The @ is optional, and a profile link works just as well since the handle is read straight out of it.

The same account listed twice comes back once and is charged once, and that includes the same handle written with different capitals: NASA and nasa are one account.

A handle that does not exist, or that has been suspended, gets an uncharged row saying so and the run carries on down the list. A protected account returns the shell X shows the public, which is the name, the handle and the counts, and that row is a real result.

The field names are X's own rather than the labels in the app, because those are the names you will need if these rows go anywhere else:

FieldWhat it is
friendsCountHow many accounts this one follows. X has called it that for years.
statusesCountTotal posts, including replies and retweets.
descriptionThe bio text.
verified vs isBlueVerifiedThe old legacy tick and the paid one. They are not the same thing and an account can have either.

📥 What you give it

{
"twitterHandles": ["nasa", "apify", "elonmusk"]
}
FieldDefaultWhat it is
twitterHandlesnoneUsernames, with or without @. The form opens with nasa and elonmusk filled in as an example, which is a starting point rather than a default.
startUrlsnoneOr paste profile links like https://x.com/nasa. Mix them with twitterHandles freely.
sessionCookiesnoneOptional and not needed for a normal run. Your own X account, as auth_token=XXXX; ct0=YYYY, one per line, and the run uses it only when it needs one. Use a throwaway account: the value sits in the run input, which anyone who can open the run can read.
proxyConfigurationApify's defaultLeave it alone. It is there for people who need the run to leave through servers they already pay for.
notionConnector, notionParentIdnoneOptional. Write each profile into a Notion database as well as the dataset.

There is no limit on how many handles you can send, and no pause between them, so a very long list is bounded by the run timeout rather than by a cap. Split a list of tens of thousands across runs.

📤 What you get back

A real row from a real run, with an emoji in the bio cut short:

{
"ok": true,
"charged": true,
"url": "https://x.com/NASA",
"id": "11348282",
"userName": "NASA",
"name": "NASA",
"description": "Making the seemingly impossible, possible. ...",
"followersCount": 92373823,
"friendsCount": 117,
"statusesCount": 74312,
"verified": true,
"isBlueVerified": true,
"location": "Pale Blue Dot",
"profileImageUrl": "https://pbs.twimg.com/profile_images/1321163587679784960/0ZxKlEKB_normal.jpg",
"createdAt": "Wed Dec 19 20:20:32 +0000 2007"
}
FieldWhat it is
idX's numeric account id. It survives a handle change, so it is the one to key on.
userName, nameThe handle, and the display name shown above it.
followersCount, friendsCount, statusesCountFollowers, following and total posts, as X reported them at read time.
verified, isBlueVerifiedBoth tick types, as booleans.
urlThe canonical profile link, using X's own capitalisation of the handle.
location, profileImageUrl, createdAtWhere the account says it is, its avatar and when it joined, in X's own date format. location is null when the account never set one.

The avatar link is X's small version. Swap _normal for _400x400 in the address for a larger one.

🧾 Reading the output

Two kinds of row can land in your dataset.

RowHow to spot itBilled
A profileok: true and an idyes
A diagnosticok: false and an errorCodeno

Filter on ok == true and you have your data. The charged field separates real rows from diagnostics, and is not a receipt.

NOT_FOUND means the handle does not exist or the account is gone, so check the spelling. BLOCKED means the profile could not be read on this run, which is worth trying again rather than treating as an answer.

One quirk of the Overview table: it shows userName, name, followersCount, statusesCount, verified and url, so the bio, the following count and the paid tick are not in it at all. Open the row itself or download the JSON and everything is there.

▶️ How to run it

  1. Open Twitter Profile Scraper and click Try for free.
  2. Type handles into Usernames, one per line, or paste links into Profile URLs.
  3. Click Start.
  4. Download the dataset as JSON, CSV or Excel, or pull it from the Apify API.

💰 How much does it cost?

$0.14 per 1,000 profiles. Flat on every Apify plan, no volume tiers.

You pay per row that carries a profile. Diagnostic rows, and the second copy of a handle you listed twice, are not charged.

💡 What people use it for

  • Refreshing follower counts across a creator or prospect list on a schedule, then diffing week to week.
  • Checking a shortlist before an outreach round, so nobody writes to a dead or suspended handle.
  • Turning a spreadsheet column of handles into a table with real numbers beside it.
  • Grabbing X account ids, which survive a handle change and make a better join key than the handle.

🚧 What it does not do

  • No tweets, no replies, no follower lists. This is the profile record. The siblings below cover the rest.
  • No search. You need the handles already. It will not find accounts by topic or keyword.
  • A protected account gives you the public shell only, and that row is a real result.
  • Counts are a snapshot at the moment the row was read, not a history.
  • No pacing control and no cap on the list, so a very large batch is limited by the run timeout.

🧭 Which X scraper do you need?

If you wantUse
Follower counts and bios for handles you already haveThis one
Tweets matching a keyword or an advanced queryTwitter (X) Search Scraper
Specific tweets, or a profile's timelineTweet Scraper
Who follows an accountX Followers Scraper
Everything posted into a curated X listTwitter List Scraper

❓ Questions people ask

Do I need an X account or an API key? No. The cookie field is a fallback and most runs never touch it.

Can I get the account's tweets too? Not from here. Tweet Scraper reads timelines.

Why is location empty on some accounts? Because those accounts never set one. X leaves it blank, and so does the row.

What happens to a handle that does not exist? You get an uncharged row marked ok: false with NOT_FOUND, and the run moves on to the next handle instead of stopping.

Is scraping X legal? This reads public profiles only, never private accounts or messages. Results can still contain personal data, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.

Can I run it on a schedule? Yes. Use Apify's scheduler, or start it from the API and read the dataset when it finishes.

🆘 If something breaks

Open the Issues tab on the actor page. Include the handles you used and the run ID, and paste any errorCode you got back, since that usually says what happened straight away.