X Profile Scraper - No Login avatar

X Profile Scraper - No Login

Pricing

from $0.25 / 1,000 profile returneds

Go to Apify Store
X Profile Scraper - No Login

X Profile Scraper - No Login

Bulk-resolve X (Twitter) handles into full public profiles: followers, following, bio, links, location, join date, verification and pinned post. No login. Same price on every Apify plan.

Pricing

from $0.25 / 1,000 profile returneds

Rating

0.0

(0)

Developer

Renzo Madueno

Renzo Madueno

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Feed it X (Twitter) handles. Get back full public profiles: followers, following, post count, bio, bio links, website, location, join date, verification status, avatar, banner, pinned post, and professional category.

No login. No cookies. No browser. No Twitter account.

What makes this one worth using

Same price on every Apify plan. $0.25 per 1,000 profiles whether you are on the free plan or on Business. No free-tier multiplier, no reduced result cap for free users, no invoice that arrives looking nothing like the price on the listing page.

Dead handles cost nothing. Hand it a list of 10,000 handles scraped from somewhere and a good chunk of them will be suspended, renamed or deleted. Those produce a FAILURES entry naming the handle and the reason. They do not produce a dataset row and they do not produce a charge. On a real list that is often 5-15% of your input, and it is the difference between paying for data and paying for absence.

Renamed accounts are flagged, not silently swapped. X resolves an old handle to whatever the account is called now. That is useful, but you need to know it happened. Every row carries queriedHandle (what you asked for) and handleChanged (a boolean). Nothing gets quietly substituted underneath you.

Input

{
"handles": [
"nasa",
"@apify",
"https://x.com/naval",
"esa"
],
"minFollowers": 1000
}
FieldTypeDefaultWhat it does
handlesarrayHandles or profile URLs. Aliases: handle, usernames, username, urls, url, profileUrls, startUrls.
maxItemsintegernoneCeiling on delivered rows. Aliases: maxResults, limit, maxProfiles.
minFollowersintegernoneDrop accounts below this follower count. Filtered accounts are not charged.
joinedAfterstringOnly accounts created on or after this date.
joinedBeforestringOnly accounts created on or before this date.

nasa, @nasa, NASA and https://x.com/nasa all work, as do profile URLs with /with_replies, /media or query strings attached. Duplicates are collapsed case-insensitively before anything is fetched, so the same account listed three times costs once.

On date filters

A profile has exactly one timestamp: the day the account was created. So this actor supports joinedAfter and joinedBefore, and rejects post-date filters with an explicit error:

X Profile Scraper cannot filter by date on this data (postedAfter was supplied). X does not expose a usable timestamp for this surface, so honouring the filter is impossible and ignoring it would hand you rows outside your range. Supported date fields here: joinedAfter, joinedBefore.

The alternative — accepting the field and ignoring it — is how you end up with a dataset that quietly does not match what you asked for. A loud error costs you thirty seconds. A silent one costs you an analysis.

joinedAfter and joinedBefore accept YYYY-MM-DD, a full ISO timestamp, or a relative window like 2 years, 18 months, 90 days. They are genuinely useful: filtering out accounts created in the last six months is one of the cheapest bot filters available.

Output

One row per profile. Fill rates below are measured across a verification sample of six real accounts on 2026-08-22.

FieldFillNotes
id100%Numeric X user ID. Stable across handle changes.
handle, name, url100%handle is the account's current handle.
description100%The bio, as plain text.
createdAt100%Account creation date, ISO 8601 UTC.
followersCount, followingCount100%
tweetsCount, mediaCount, likesCount, listedCount100%
isBlueVerified, isVerified, isProtected100%isBlueVerified is the paid checkmark; isVerified is the retired legacy one.
isDefaultProfileImage100%A strong bot signal.
profileImageUrl, profileImageUrlLarge100%The large variant is the 400x400 original.
profileBannerUrl100%
websiteUrl~83%The link in the profile header, un-shortened from t.co.
pinnedTweetId~67%
location~50%Free text as typed by the user. Not geocoded, and not always a real place.
professionalType~50%e.g. Business, Creator.
descriptionLinks~33%Links inside the bio text, un-shortened.
affiliateLabel~33%The parent organisation on affiliated accounts.
professionalCategory~17%The self-declared business category.
queriedHandle, handleChanged, scrapedAt100%

Data integrity, not just data presence

The fill rates above say a field arrived. These rules make sure what arrived is usable:

  • Follower and post counts are normalised to integers, including abbreviated display values like "1.5M".
  • Negative counts become null. On very large accounts a 32-bit overflow can surface as something like -576135159. That is not a follower count, and silently passing it through would wreck any ranking built on the column.
  • createdAt is parsed from X's own format (Wed Oct 10 20:19:24 +0000 2018) into ISO 8601. A value that cannot be read becomes null, never a 1970 epoch date that would quietly pass a joinedAfter filter it should have failed.
  • websiteUrl and descriptionLinks are resolved past t.co, so you get the real destination rather than a shortlink you would have to expand yourself.

What is deliberately absent

Email addresses and phone numbers. X does not publish them. No scraper of X can produce them honestly, and any that claims to is either guessing or enriching from somewhere else without telling you.

Follower and following lists. Those need a logged-in session. This actor does not use one.

How it works

A single GraphQL call per handle — UserByScreenName, the same request x.com makes when a logged-out visitor loads a profile page. Authentication is a guest token from POST /1.1/guest/activate.json: free, tied to no account, and refreshed automatically inside the run whenever X rotates or rejects it. Retired GraphQL query IDs are rotated automatically as well.

No browser, no proxy required, 512 MB of memory. Platform compute cost is negligible next to the per-result price.

Roughly 150 ms of spacing between lookups keeps runs well inside what the public endpoint tolerates. A 10,000-handle run takes about half an hour and costs $2.50.

Errors go where you can act on them

Nothing that failed appears in the dataset. It all goes into the FAILURES key-value record:

{
"actor": "X Profile Scraper",
"targetsRequested": 4,
"resultsDelivered": 3,
"resultsCharged": 3,
"emptyRowsSuppressed": 0,
"failureCount": 1,
"failures": [
{
"target": "someaccountthatisgone",
"error": "Account does not exist, is suspended, or was renamed - X returns nothing for it"
}
],
"notes": [
"1 handle(s) no longer resolve to a public account. They are listed in this record and were not charged."
]
}

That record doubles as a cleaning report. Diff it against your input list and you have your list hygiene for free.

A run that delivers nothing is marked FAILED. If every handle in your list is dead, the run does not finish green over an empty dataset. It fails, and names the reason.

Pricing

$0.25 per 1,000 profiles. Pay per result. No subscription. Same price on every Apify plan.

ProfilesCost
100$0.025
1,000$0.25
10,000$2.50
100,000$25.00

Suspended handles, deleted accounts, unparseable inputs and filtered-out profiles all cost $0.00.

Typical uses

  • Lead qualification. You have a list of handles from a conference, a newsletter, a GitHub org or a set of replies. Resolve them into follower counts, bios and websites and decide who is worth contacting.
  • List hygiene. Run your CRM's stored handles through it quarterly. The FAILURES record tells you which contacts have gone dark and handleChanged tells you who renamed.
  • Influencer shortlisting. Followers, post count, listed count and account age in one table, then filter with minFollowers.
  • Bot and authenticity screening. The audit dataset view puts account age, default-avatar status, follower/following ratio and post count side by side. Accounts created recently, with a default avatar and a lopsided ratio, are the classic pattern.
  • Enrichment for another dataset. Chain it after any actor that emits X handles — the replies scraper in this fleet is a natural upstream.
  • Competitive tracking. Re-run weekly against a fixed list and diff follower counts to get real growth curves rather than screenshots.

Limits worth knowing before you start

  • Protected accounts return almost nothing. X publishes only minimal metadata about them to logged-out clients. They are reported honestly rather than padded out.
  • location is free text. Users type whatever they want in it, including jokes and fictional places. It is not geocoded and should not be treated as a reliable geographic field.
  • isVerified is the retired legacy checkmark, not the current paid one. isBlueVerified is the one that means something today. Both are returned so you can tell them apart.
  • No follower or following lists. Those require a logged-in session, which this actor deliberately does not use.

Verified

Every endpoint, field name and fill rate in this README was tested live against X on 2026-08-22 from a datacenter IP with no cookies and no account. The fill rates come from actual measurement across a sample of real accounts, not from documentation.

  • Tweet Scraper by URL or ID — individual tweets, $0.20/1k.
  • X Profile Posts Scraper - No Cookies — an account's timeline, with a real per-account cap, $0.30/1k.
  • Tweet Replies Scraper - No Login — publicly visible replies, $0.30/1k.
  • X Trends Scraper by Country — 62 countries and 400+ cities, $0.40/1k.

Same rules across all of them: one price on every plan, and nothing charged for nothing.