Twitter Scraper
Pricing
from $0.15 / 1,000 public data
Twitter Scraper
Collect public X posts, profiles, network members, and regional trends. Filter posts by date, language, media, links, and engagement, then save structured rows to an Apify dataset without X credentials.
Pricing
from $0.15 / 1,000 public data
Rating
5.0
(1)
Developer
Maxime Dupré
Maintained by CommunityActor stats
1
Bookmarked
283
Total users
90
Monthly active users
2.7 hours
Issues response
16 hours ago
Last modified
Categories
Share
🔎 Twitter (X) scraper for public data
Twitter Scraper helps researchers, marketers, and developers collect public Twitter/X posts, profile matches, profile network members, and regional trends. Get text, links, authors, media, engagement counts, and source details as structured dataset rows without giving the Actor your Twitter/X login.
- Find public posts with the Twitter API task.
- Collect public posts for a topic with an Apify Twitter scraper task.
- Build a small public-data workflow with the Twitter scraper Python task.
- Collect image posts with the Twitter image scraper task.
- Read saved public rows in code with the Twitter scraper API task.
📦 Public posts, profiles, networks, and trends
Post rows can include text, links, time, language, post kind, author details, engagement counts, media, quotes, replies, and conversation links. Profile rows can include identity, bio, images, public counts, verification, and source context. Trend rows include rank, region, and a search link.
The Actor saves each eligible public item on its first match. If another query, URL, handle, ID, or source finds it later, that later match is ignored. Source fields describe only the first saved match.
▶️ Run one Twitter/X collection
- Choose one
targetfor the run. - Add the matching search, profile, network, or trend input.
- Set any filters and
maxNbItemsToScrape. - Run the Actor and open its dataset.
Post searches can use plain text, X search syntax, public source URLs, post URLs or IDs, conversation IDs, quoted post IDs, filters, or date and location limits. Profile search finds public accounts by search phrase or direct target. Network mode collects followers, followed accounts, or public post retweeters. Trends mode returns topics for one supported region. Leave the work limit empty to return all available results until the source is exhausted.
⚙️ Input
Input fields
Only fields for the chosen target affect that run.
| Field | Type | What it does |
|---|---|---|
target | string | Chooses one result type: public posts, public profiles, profile network members, or trends. |
postDiscoveryMethod | string | Chooses one way to find public posts. Other post-finding inputs are ignored. |
searchQuery | string | Uses plain text or advanced X search syntax. |
directPostUrls | string[] | Fetches the exact public posts at the submitted X or Twitter URLs or numeric IDs. |
conversationIds | string[] | Finds public posts that belong to the submitted conversations. |
quotedPostIds | string[] | Finds public posts that quote the submitted post IDs. |
postSearchUrls | string[] | Uses public search, profile, list, post, or conversation URLs as post sources. A post URL finds posts that quote it, not that post or its full thread. |
hashtags | string[] | Keeps posts that contain the submitted hashtags. Enter each tag without #. |
fromUsers | string[] | Keeps posts written by the submitted handles. Enter each handle without @. |
authorVerification | string | Includes authors with any status, only verified authors, or authors not marked verified. |
mentions | string[] | Keeps posts that mention the submitted handles. Enter each handle without @. |
toUsers | string[] | Keeps posts addressed to the submitted handles. Enter each handle without @. |
searchMode | string | Orders searches as Latest, Top, or Latest + Top. The combined mode saves each post once. |
startDate | string | Keeps posts on or after this date. Empty uses the last 30 days. |
endDate | string | Keeps posts on or before this date. |
language | string | Keeps posts with this language code, such as en, es, fr, or ja. |
near | string | Sets a place name for location search. |
geocode | string | Sets a latitude, longitude, and radius, such as 37.776,-122.417,10km. |
placeId | string | Sets an X or Twitter place ID. |
links | string | Includes all posts, only posts with links, or only posts without links. |
media | string | Includes all posts or requires media, images, or videos. |
postKinds | string[] | Keeps one or more original posts, quotes, replies, or reposts. |
minLikes | integer | Keeps posts with at least this many likes. |
minReplies | integer | Keeps posts with at least this many replies. |
minRetweets | integer | Keeps posts with at least this many reposts. |
sinceId | string | Keeps posts after this X post ID. |
maxId | string | Keeps posts at or before this X post ID. |
profileDiscoveryMethod | string | Finds profiles by search phrases or by direct handles, URLs, or IDs. |
profileSearchQueries | string[] | Uses X or Twitter People search phrases to find matching public profiles. |
profileLookupTargets | string[] | Looks up public profiles from handles, URLs, or IDs. Enter handles without @. |
networkType | string | Chooses Followers, Following, or Post retweeters. |
networkProfileHandles | string[] | Sets public profile handles, IDs, or URLs whose followers or following accounts to collect. |
retweeterPostUrlsOrIds | string[] | Sets public post URLs or IDs whose public retweeter profiles to collect. |
trendRegionId | string | Chooses one supported region for current trend topics. |
maxNbItemsToScrape | integer | Stops after this many rows. Leave it empty to collect all available results until the source is exhausted. |
Example input
This is the public input from a successful current-beta default search run:
{"target": "searchPosts","postDiscoveryMethod": "searchQuery","searchQuery": "OpenAI","authorVerification": "any","searchMode": "latest","links": "include","media": "include","postKinds": ["originalPosts","quotePosts","replies"],"profileDiscoveryMethod": "searchPhrases","networkType": "followers","trendRegionId": "1","maxNbItemsToScrape": 10}
Post searches need at least one positive selector. Profile searches need a search phrase or direct target. Network runs need profile targets for Followers or Following, or post URLs or IDs for Post retweeters. Trends use only the chosen region.
🧾 Output
Each run returns rows for one chosen target shape. Network-member runs use the profile shape. Optional fields can be null when X does not provide them.
Post row
| Field | Type | What it does |
|---|---|---|
rowType | string | Marks this row as a post. |
postId | string | Gives the X post ID. |
postUrl | string | Gives the public link to the X post. |
postText | string | Gives the full post text. |
postDateTime | string | Gives the publication time as a date-time string. |
language | string | Gives the post language code. |
postKind | string | Says whether the post is original, a reply, a quote, or a repost. |
authorId | string or null | Gives the author profile ID, when available. |
authorHandle | string or null | Gives the author handle without @, when available. |
authorDisplayName | string or null | Gives the author's display name, when available. |
authorProfileUrl | string or null | Gives the link to the author's X profile, when available. |
authorBio | string or null | Gives the author's public profile bio, when available. |
authorLocation | string or null | Gives the author's public profile location, when available. |
authorAvatarUrl | string or null | Gives the author's avatar image link, when available. |
authorFollowersCount | integer or null | Gives the author's follower count, when available. |
authorFollowingCount | integer or null | Gives the author's following count, when available. |
authorCreatedAt | string or null | Gives the author account creation time, when available. |
authorIsVerified | boolean or null | Says whether the author is verified, when available. |
authorIsBlueVerified | boolean or null | Says whether the author has X Premium verification, when available. |
authorVerifiedType | string or null | Gives the author's verification type, when available. |
nbLikes | integer or null | Gives the number of likes, when available. |
nbReposts | integer or null | Gives the number of reposts, when available. |
nbReplies | integer or null | Gives the number of replies, when available. |
quoteCount | integer or null | Gives the number of quotes, when available. |
nbViews | integer or null | Gives the number of views, when available. |
nbBookmarks | integer or null | Gives the number of bookmarks, when available. |
mediaDetails | object[] | Lists each media file and its available details. |
mediaDetails.id | string or null | Gives the media ID, when available. |
mediaDetails.altText | string or null | Gives the media alt text, when available. |
mediaDetails.type | string | Gives the media kind. |
mediaDetails.url | string | Gives the main media file link. |
mediaDetails.thumbnailUrl | string or null | Gives a preview image link, when available. |
mediaDetails.width | integer or null | Gives the media width in pixels, when available. |
mediaDetails.height | integer or null | Gives the media height in pixels, when available. |
mediaDetails.durationMs | integer or null | Gives the media length in milliseconds, when available. |
mediaDetails.aspectRatio | string or null | Gives the media shape, when available. |
mediaDetails.contentType | string or null | Gives the media file type, when available. |
mediaDetails.variants | object[] | Lists other video file choices, when available. |
mediaDetails.variants.url | string | Gives a video choice link. |
mediaDetails.variants.contentType | string or null | Gives a video choice file type, when available. |
mediaDetails.variants.bitrate | integer or null | Gives a video choice bitrate, when available. |
hashtags | string[] | Lists hashtags without #. |
linkEntities | string[] | Lists usable destination links found in the post. |
quotedPostId | string or null | Gives the quoted post ID, when available. |
quotedPostText | string or null | Gives the quoted post text, when available. |
quotedAuthorHandle | string or null | Gives the quoted post author's handle, when available. |
replyToHandle | string or null | Gives the handle this post replies to, when available. |
replyToPostId | string or null | Gives the post ID this post replies to, when available. |
conversationId | string or null | Gives the conversation ID, when available. |
inReplyToUserId | string or null | Gives the replied-to user ID, when available. |
isPinned | boolean or null | Says whether X marks the post as pinned, when available. |
source | string or null | Gives the posting client label, when available. |
sourceInput | string or null | Gives the submitted query, URL, ID, or similar value that first found the post. |
resultPosition | integer or null | Gives the post's place in its source results, when available. |
Example post row from a successful current-beta run
{"rowType": "post","postKind": "reply","postId": "2094857571173818383","postUrl": "https://x.com/jonasleupe/status/2094857571173818383","postText": "@browsercompany @arcinternet @OpenAI @Anthropic @grok @raycast Settling down for today, building starts tomorrow.\nThanks for following along! It's so nice to meet y'all 🫶🏻\n\nThis is fun! ✨ https://t.co/I9laEpmn2n","postDateTime": "2026-09-01T18:39:00.000Z","authorHandle": "jonasleupe","authorDisplayName": "Jonas","authorAvatarUrl": "https://pbs.twimg.com/profile_images/1760769023153786880/Xtnmsj_3_normal.jpg","authorProfileUrl": "https://x.com/jonasleupe","authorBio": "Designer & Maker. Elevating voices in a crowded world.","authorLocation": "Operating globally","authorCreatedAt": "2013-03-06T21:05:48.000Z","nbLikes": 0,"nbReposts": 0,"nbReplies": 0,"nbViews": null,"nbBookmarks": 0,"mediaDetails": [{"id": "2094842417434222592","altText": null,"type": "image","url": "https://pbs.twimg.com/media/HRJgFGeWYAAa5AS.jpg","thumbnailUrl": "https://pbs.twimg.com/media/HRJgFGeWYAAa5AS.jpg","width": 2688,"height": 2150,"durationMs": null,"aspectRatio": null,"contentType": null,"variants": []}],"hashtags": [],"linkEntities": [],"quotedPostId": null,"quotedPostText": null,"quotedAuthorHandle": null,"replyToHandle": "jonasleupe","replyToPostId": "2094838599552315403","quoteCount": 0,"language": "en","source": "Twitter Web App","conversationId": "2094707380084715579","inReplyToUserId": "1247151224","isPinned": false,"authorId": "1247151224","authorFollowersCount": 1739,"authorFollowingCount": 791,"authorIsVerified": true,"authorIsBlueVerified": true,"authorVerifiedType": null,"resultPosition": 6,"sourceInput": "OpenAI"}
Profile and network-member row
Profile search and network-member runs use this same shape. Network rows add networkType, while sourceInput gives the first query, handle, URL, ID, or similar source value.
| Field | Type | What it does |
|---|---|---|
rowType | string | Marks this row as a profile. |
profileId | string | Gives the profile ID. |
profileUrl | string | Gives the public link to the X profile. |
handle | string | Gives the profile handle without @. |
displayName | string | Gives the profile display name. |
bio | string or null | Gives the public profile bio, when available. |
createdAt | string or null | Gives the account creation time, when available. |
location | string or null | Gives the public profile location, when available. |
avatarUrl | string or null | Gives the profile avatar image link, when available. |
bannerUrl | string or null | Gives the profile banner image link, when available. |
followersCount | integer or null | Gives the public follower count, when available. |
followingCount | integer or null | Gives the public following count, when available. |
postsCount | integer or null | Gives the public post count, when available. |
likesCount | integer or null | Gives the public like count, when available. |
isVerified | boolean or null | Says whether X marks the profile as verified. |
pinnedPostIds | string[] | Gives the shown pinned post IDs. |
sourceInput | string or null | Gives the submitted query, handle, URL, ID, or similar value that first found the profile. |
networkType | string or null | Gives followers, following, or retweeters when a network run found the profile. |
resultPosition | integer or null | Gives the profile's place in the source results, when available. |
Example profile row from a successful current-beta run
{"rowType": "profile","profileId": "4398626122","profileUrl": "https://x.com/OpenAI","handle": "OpenAI","displayName": "OpenAI","bio": "OpenAI’s mission is to ensure that artificial general intelligence benefits all of humanity. We’re hiring: https://t.co/dJGr6LgzPA","createdAt": "2015-12-06T22:51:08.000Z","location": null,"avatarUrl": "https://pbs.twimg.com/profile_images/1885410181409820672/ztsaR0JW_normal.jpg","bannerUrl": "https://pbs.twimg.com/profile_banners/4398626122/1777662919","followersCount": 5142713,"followingCount": 4,"postsCount": 2091,"likesCount": 2458,"isVerified": true,"pinnedPostIds": ["2092300846675505602"],"resultPosition": 1,"sourceInput": "OpenAI"}
Example network-member row from a successful current-beta run
{"rowType": "profile","profileId": "33836629","profileUrl": "https://x.com/karpathy","handle": "karpathy","displayName": "Andrej Karpathy","bio": "deep learning","createdAt": "2009-04-21T06:49:15.000Z","location": "Earth","avatarUrl": "https://pbs.twimg.com/profile_images/1296667294148382721/9Pr6XrPB_normal.jpg","bannerUrl": "https://pbs.twimg.com/profile_banners/33836629/1407117611","followersCount": 4065882,"followingCount": 1133,"postsCount": 10143,"likesCount": 24542,"isVerified": true,"pinnedPostIds": [],"resultPosition": 1,"networkType": "followers","sourceInput": "@openai followers"}
Trend row
| Field | Type | What it does |
|---|---|---|
rowType | string | Marks this row as a trend. |
trendName | string | Gives the topic name. |
trendRank | integer | Gives its rank in the region. |
trendQuery | string or null | Gives the search query, when available. |
trendSearchUrl | string or null | Gives an X search link for the trend, when available. |
regionId | string | Gives the selected trend region ID. |
regionName | string | Gives the selected trend region name. |
regionCountry | string or null | Gives the country or global label for the region. |
regionCountryCode | string or null | Gives the ISO country code, or null for Worldwide. |
Example trend row from a successful current-beta run
{"rowType": "trend","trendName": "#الهلال_الاهلي","trendRank": 1,"trendQuery": "%23%D8%A7%D9%84%D9%87%D9%84%D8%A7%D9%84_%D8%A7%D9%84%D8%A7%D9%87%D9%84%D9%8A","trendSearchUrl": "https://x.com/search?q=%23%D8%A7%D9%84%D9%87%D9%84%D8%A7%D9%84_%D8%A7%D9%84%D8%A7%D9%87%D9%84%D9%8A","regionId": "1","regionName": "Worldwide","regionCountry": "Worldwide","regionCountryCode": null}
💳 Pricing
This Actor uses pay-per-event pricing. The public data event covers one saved post, profile, network member, or trend. Use a small work limit for a first test, then raise it when the output fits your work.
🔌 Integrations
Use the Apify API, schedules, webhooks, and dataset exports such as JSON, CSV, Excel, XML, or RSS.
❓ FAQ
What happens when the same post or profile matches twice?
The Actor saves the first eligible match. It ignores later matches and keeps the first sourceInput value for that row.
Can one run use more than one result type?
No. Choose posts, profiles, network members, or trends for each run. Inputs for other result types are ignored.
What happens if X stops returning pages during a run?
The run can finish with rows already saved and a degraded-result reason. Invalid input remains a separate error.
How do I fetch one post without fetching its thread?
Use directPostUrls for an exact public post URL or numeric ID. A post URL in postSearchUrls instead finds posts that quote it. Use conversationIds when you want posts from a conversation.
How do I search profiles or collect a network?
Choose searchProfiles with profileSearchQueries or profileLookupTargets to find public accounts. Choose networkMembers with networkProfileHandles for Followers or Following, or retweeterPostUrlsOrIds for Post retweeters.
Can I collect a full historical archive?
No. The Actor returns public data that X exposes for the selected source. It does not promise complete historical coverage.
Why is a field null?
The source may not provide that value for the post, profile, network member, or trend. Private, protected, deleted, suspended, and otherwise unavailable data is outside the product boundary.
Does leaving the work limit empty return everything?
It returns all available results until the source is exhausted. It does not promise every historical post or every profile that X does not expose.
Do I need a Twitter/X login or API key?
No. You do not provide Twitter/X cookies, sessions, credentials, or an API key.
Is this the official Twitter/X API?
No. This is an Apify Actor for public X data and structured dataset rows. Use the official API when you need its own contract.
📝 Changelog
v2.0 (01-09-2026)
- Added direct public profile lookup by handle, profile URL, or ID.
- Added public post retweeter collection as a profile network option.
- Added author-verification filters for post searches.
- Standardized result provenance as
sourceInputand simplified the public result fields. - Recoverable X source failures now finish successfully with preserved rows and a truthful degraded-result warning.
v1.0
- Made each run explicitly choose posts, profiles, network members, or trending topics.
- Added author locations and structured media details to post rows, with clearer profile and trend result views.
- Improved recovery when public X posts or responses are unavailable.
v0.4
- Added direct post collection by URL or ID.
- Added conversation and quote discovery.
- Added follower and following network collection.
- Improved handling when Twitter/X returns incomplete responses.
v0.3
- Added post search URLs and advanced search syntax.
- Added Latest + Top search and link, media, and location filters.
- Added richer flat post fields.
- Added clearer handling for unsupported X URLs.
v0.2
- Added Search Profiles for query-based Twitter/X profile discovery with flat profile rows and search provenance.
v0.1
- Added Trending Topics and supported trend regions.
- Added grouped target inputs and pay-per-event pricing.
🆘 Support
For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡
🔗 Related Actors
- Twitter Media Scraper gets source-hosted image, video, and GIF links from public X posts.
- Twitter Organization Affiliates Scraper maps public affiliate accounts connected to X organizations.
- X (Twitter) Community Top Posts Scraper collects public posts with X Community context.
- Tweet Scraper V2 - X / Twitter Scraper offers a tweet-focused Actor for public post searches.
- Fast Twitter (X) User Scraper API | Extract Profiles, Followers focuses on public profile and follower data.
Made with ❤️ by Maxime Dupré