Twitter (X) Scraper
Pricing
from $0.15 / 1,000 public data
Twitter (X) Scraper
Collect public X posts, profile matches, network members, and regional trends. Filter posts by source, date, language, media, 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
267
Total users
79
Monthly active users
2.7 hours
Issues response
11 days 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.
- Send a collection request and read saved rows from code with the Twitter scraper API.
- Build a small public-data workflow with Twitter scraper Python.
- Collect image posts with the Twitter image scraper task.
- Check current topics by region with the Twitter trends scraper task.
- Find public accounts by query with Twitter profile search.
📦 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, search link, and reported post volume when X gives it.
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. Network mode collects followers or followed accounts. 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 posts, profile search, network members, or trends. |
directPostUrls | string[] | Collects the exact public posts at these URLs. |
directPostIds | string[] | Collects the exact public posts with these numeric IDs. |
conversationIds | string[] | Finds public posts in these conversations. |
quotedPostIds | string[] | Finds public posts that quote these post IDs. |
postSearchUrls | string[] | Searches from Twitter/X search, profile, list, or post URLs. A post URL here finds quotes. |
searchQuery | string | Uses plain text or advanced Twitter/X search syntax. |
hashtags | string[] | Requires hashtags, without #. |
fromUsers | string[] | Requires authors, without @. |
mentions | string[] | Requires mentioned handles, without @. |
toUsers | string[] | Requires posts addressed to handles, without @. |
searchMode | string | Uses latest, top, or both. Each post is saved 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 | Requires a language code such as en. |
near | string | Sets a place name for location search. |
geocode | string | Sets latitude, longitude, and radius. |
placeId | string | Requires a Twitter/X 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 selected original posts, quotes, replies, and reposts. |
minLikes | integer | Sets the least number of likes. |
minReplies | integer | Sets the least number of replies. |
minRetweets | integer | Sets the least number of reposts. |
sinceId | string | Keeps posts after this post ID. |
maxId | string | Keeps posts at or before this post ID. |
profileSearchQueries | string[] | Finds public profiles with X or Twitter People search. |
networkProfileHandles | string[] | Sets profiles whose followers or following accounts to collect. |
networkType | string | Chooses followers or following accounts. |
trendRegionId | string | Chooses one supported region for trends. |
maxNbItemsToScrape | integer | Stops after this many rows. Leave it empty to return 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","searchQuery": "OpenAI","searchMode": "latest","links": "include","media": "include","postKinds": ["originalPosts","quotePosts","replies"],"networkType": "followers","trendRegionId": "1","maxNbItemsToScrape": 10}
Post searches need at least one positive selector. Profile searches need a query. Network runs need a profile handle. Trends use only the chosen region.
🧾 Output
Each run returns rows for one chosen target shape. Network-member runs use the profile shape. Fields that X does not provide can be null.
Post row
| Field | Type | What it does |
|---|---|---|
rowType | string | Is post. |
postId | string or null | Gives the X post ID, when available. |
postUrl | string or null | Gives the link to the X post, when available. |
postText | string or null | Gives the full post text, when available. |
postDateTime | string or null | Gives the time the post was published, when available. |
language | string or null | Gives the post language code, when available. |
postKind | string or null | 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 | number or null | Gives the author's follower count, when available. |
authorFollowingCount | number or null | Gives the author's following count, when available. |
authorCreatedAt | string or null | Gives the time the author account was created, 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 | number or null | Gives the number of likes, when available. |
nbReposts | number or null | Gives the number of reposts, when available. |
nbReplies | number or null | Gives the number of replies, when available. |
quoteCount | number or null | Gives the number of quotes, when available. |
nbViews | number or null | Gives the number of views, when available. |
nbBookmarks | number or null | Gives the number of bookmarks, when available. |
mediaDetails | object[] | Gives 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 or null | Gives the media kind, when available. |
mediaDetails.url | string or null | Gives the main media file link, when available. |
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[] | Gives other video file choices, when available. |
mediaDetails.variants.url | string or null | Gives a video choice link, when available. |
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[] | Gives hashtags without #. |
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. |
searchQuery | string or null | Gives the search query that first found the post, when available. |
sourceUrl | string or null | Gives the submitted URL that first found the post, when available. |
sourceType | string or null | Gives the kind of input that first found the post, when available. |
resultPosition | number or null | Gives the post's 1-based place in its source, when available. |
{"rowType": "post","postKind": "quote","postId": "2088561319947493797","postUrl": "https://x.com/antisadh/status/2088561319947493797","postText": "OPENAI CHARGES $200/MO FOR GPT-5.6 ANTHROPIC CHARGES $200/MO FOR OPUS 5 GOOGLE CHARGES $200/MO GEMINI HE WIRED 5 FREE GITHUB REPOS INTO KIMI K3 AND HIS ENTIRE 5-AGENT WORKFLOW COSTS $40/MO IN API CALLS\n\nwhy pay openai $200 to talk to one gpt-5 -> kimi k3 is #3 on the ai index, openai-compatible, $3 in / $15 out per 1M tokens -> wire it into kimi code, agents sdk (5 specialists in parallel), openhands (autonomous jobs), graphrag (memory) -> your \"ai team\" is 5 free repos + one $40/mo api key.\n\nthat loop is why every serious solo dev is quietly cancelling $200 subscriptions and the article below is the exact stack that replaces all 3.\n\nkimi code + agent sdk + agents sdk + openhands + graphrag = 5 hires, one api key, same output as your $600/mo subscription stack - that's the swap from the article below.\n\nread the article below. that's how you stop paying $200/mo for one seat and start paying $40 for a whole team.","postDateTime": "2026-08-15T09:39:56.000Z","authorHandle": "antisadh","authorDisplayName": "Antid","authorAvatarUrl": "https://pbs.twimg.com/profile_images/2050597482061578240/zWQ8MKWq_normal.jpg","authorProfileUrl": "https://x.com/antisadh","authorBio": "studying AI daily | helping you save & make money with it","authorLocation": "Miami","authorCreatedAt": "2023-02-08T19:56:38.000Z","nbLikes": 0,"nbReposts": 0,"nbReplies": 0,"nbViews": 10,"nbBookmarks": 0,"mediaDetails": [{"id": "2088553927557988352","altText": null,"type": "video","url": "https://video.twimg.com/amplify_video/2088553927557988352/vid/avc1/1596x2160/ebtGn2R3GGPbBgtY.mp4?tag=29","thumbnailUrl": "https://pbs.twimg.com/amplify_video_thumb/2088553927557988352/img/DUVTFwq1dY69ezk1.jpg","width": 1596,"height": 2160,"durationMs": 24633,"aspectRatio": "133:180","contentType": "video/mp4","variants": [{"url": "https://video.twimg.com/amplify_video/2088553927557988352/vid/avc1/1596x2160/ebtGn2R3GGPbBgtY.mp4?tag=29","bitrate": 25128000,"contentType": "video/mp4"},{"url": "https://video.twimg.com/amplify_video/2088553927557988352/vid/avc1/1080x1460/GdS3vo2ryMd3rHM8.mp4?tag=29","bitrate": 10368000,"contentType": "video/mp4"},{"url": "https://video.twimg.com/amplify_video/2088553927557988352/vid/avc1/720x974/QoIEEp7q7A0MIFS5.mp4?tag=29","bitrate": 2176000,"contentType": "video/mp4"},{"url": "https://video.twimg.com/amplify_video/2088553927557988352/vid/avc1/480x648/6o3W6N_u81xU1yQL.mp4?tag=29","bitrate": 950000,"contentType": "video/mp4"},{"url": "https://video.twimg.com/amplify_video/2088553927557988352/vid/avc1/320x432/mPED0tFwvxSYB7ZQ.mp4?tag=29","bitrate": 632000,"contentType": "video/mp4"}]}],"hashtags": [],"quotedPostId": "2087485542359245274","quotedPostText": "https://t.co/f4AhI3wNpy","quotedAuthorHandle": "noisyb0y1","replyToHandle": null,"replyToPostId": null,"quoteCount": 0,"language": "en","source": null,"conversationId": "2088561319947493797","inReplyToUserId": null,"isPinned": null,"authorId": "1623410404150898691","authorFollowersCount": 2038,"authorFollowingCount": 86,"authorIsVerified": true,"authorIsBlueVerified": true,"authorVerifiedType": null,"searchQuery": "OpenAI","sourceUrl": null,"sourceType": "searchQuery","resultPosition": 1}
Profile or network-member row
Profile search and network-member runs use this same shape. Network fields are filled for network runs, while searchQuery describes a profile search when used.
| Field | Type | What it does |
|---|---|---|
rowType | string | Is profile. |
profileId | string or null | Gives the profile ID, when available. |
profileUrl | string or null | Gives the link to the X profile, when available. |
handle | string or null | Gives the profile handle without @, when available. |
displayName | string or null | Gives the profile display name, when available. |
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 | number or null | Gives the public follower count, when available. |
followingCount | number or null | Gives the public following count, when available. |
postsCount | number or null | Gives the public post count, when available. |
likesCount | number 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. |
searchQuery | string or null | Gives the query or network source that first found the profile. |
networkOwnerHandle | string or null | Gives the submitted profile whose network contained this account, when used. |
networkType | string or null | Gives whether the network source was followers or following, when used. |
resultPosition | number or null | Gives the profile's 1-based place in the source, when available. |
{"rowType": "profile","profileId": "891077171673931776","profileUrl": "https://x.com/berkeley_ai","handle": "berkeley_ai","displayName": "Berkeley AI Research","bio": "We're graduate students, postdocs, faculty and scientists at the cutting edge of artificial intelligence research.","createdAt": null,"location": "Berkeley, CA","avatarUrl": "https://pbs.twimg.com/profile_images/891079469594587138/c_bnAh4o_normal.jpg","bannerUrl": "https://pbs.twimg.com/profile_banners/891077171673931776/1501285360","followersCount": 286026,"followingCount": 468,"postsCount": 1578,"likesCount": 652,"isVerified": true,"pinnedPostIds": [],"searchQuery": "AI researcher","resultPosition": 1}
Example network-member row
{"rowType": "profile","profileId": "33836629","profileUrl": "https://x.com/karpathy","handle": "karpathy","displayName": "Andrej Karpathy","bio": "deep learning","createdAt": null,"location": "Earth","avatarUrl": "https://pbs.twimg.com/profile_images/1296667294148382721/9Pr6XrPB_normal.jpg","bannerUrl": "https://pbs.twimg.com/profile_banners/33836629/1407117611","followersCount": 3799461,"followingCount": 1124,"postsCount": 10141,"likesCount": 24385,"isVerified": true,"pinnedPostIds": [],"searchQuery": "@openai followers","resultPosition": 1,"networkOwnerHandle": "openai","networkType": "followers"}
Trend row
| Field | Type | What it does |
|---|---|---|
rowType | string | Is trend. |
trendName | string or null | Gives the topic name. |
trendRank | number or null | 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. |
tweetVolume | number or null | Gives the post volume reported by X. |
regionId | string or null | Gives the selected trend region ID. |
regionName | string or null | 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. |
{"rowType": "trend","trendName": "Rogue","trendRank": 1,"trendQuery": "Rogue","trendSearchUrl": "https://x.com/search?q=Rogue","tweetVolume": null,"regionId": "23424977","regionName": "United States","regionCountry": "United States","regionCountryCode": "US"}
💳 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 original source fields.
How do I fetch one post without fetching its thread?
Use directPostUrls or directPostIds for an exact public post. 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 to find public accounts. Choose networkMembers, add networkProfileHandles, and set networkType to followers or following to collect public network members.
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
1.0: Refined public X collection inputs and results
- 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 X Media Scraper helps extract direct image, video, and GIF links from public X posts.
- Twitter Retweet Checker checks whether known usernames reposted public posts.
- Twitter Screenshot Generator captures images of known public X posts.
- Twitter Organization Affiliates Scraper maps public affiliate accounts connected to X organizations.
- Social Media Stats Checker compares public profile stats across X and other platforms.
Made with ❤️ by Maxime Dupré