X (Twitter) Profile Posts Scraper avatar

X (Twitter) Profile Posts Scraper

Pricing

from $0.70 / 1,000 results

Go to Apify Store
X (Twitter) Profile Posts Scraper

X (Twitter) Profile Posts Scraper

Scrape posts from public X (Twitter) profiles with no login or API key. Get text, hashtags, mentions, engagement counts, media and quoted posts. Filter by post type and date. Bulk profiles, auto proxy fallback. Export JSON, CSV or Excel.

Pricing

from $0.70 / 1,000 results

Rating

0.0

(0)

Developer

Data Minds

Data Minds

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

17 hours ago

Last modified

Categories

Security

Limited permissions

Share

What is X (Twitter) Profile Posts Scraper?

X (Twitter) Profile Posts Scraper is a Twitter profile scraper that collects the public posts of one or more X profiles and returns one clean row per post. Paste profile links or @handles, choose how many posts, a start date and whether to include replies or retweets, and get text, engagement counts, hashtags, mentions, media and author details. Posts cost $0.001 each on the Free plan and $0.0007 on Gold, plus platform usage. 🚀 Try it free

Just enter the profiles you care about and click Start. No coding is needed. Use it as a tweet scraper for accounts you already know. It works as a Twitter timeline scraper that reads each profile you list. Use it to:

  • Monitor competitor accounts on X: schedule runs and see what rival brands post, how often and with which hashtags.
  • Track influencer engagement: compare likes, reposts, replies, quotes, views and bookmarks across creators.
  • Collect tweets for sentiment analysis: get post text, language and timestamps as rows ready for your own analysis.
  • Build a research dataset of posts: collect the posts of many accounts with the same fields, for studies or AI work.
  • Export tweets from a profile to CSV or Excel: download the rows in the format your team already uses.

Because it runs on the Apify platform, you also get the API, scheduling, integrations and exports to JSON, CSV, Excel, XML and HTML.

What can X (Twitter) Profile Posts Scraper do?

  • 👤 Scrape many profiles in one run: paste profile URLs, @handles or bare usernames, one per line.
  • 🔢 Set a cap per profile: max_posts limits the posts saved for each profile, and 0 removes the cap.
  • 💬 Choose the post type: all posts including replies, or tweets only without replies.
  • 📅 Filter by date: keep posts from the last 7, 30 or 90 days, or from any YYYY-MM-DD date.
  • 🔁 Skip retweets: leave reposts out when you only want what the profile wrote itself.
  • 📊 Get engagement counts: replies, reposts, likes, quotes, views and bookmarks on every post.
  • 🖼 Keep media and quotes: photo and video links, expanded links and the quoted post come with the row.

What data can X (Twitter) Profile Posts Scraper extract?

Every dataset row is one post. These are the fields saved for each post, named exactly as in the dataset.

Post

LabelFieldWhat it holds
🆔 Post IDpost_id, conversation_idPost identifier and the identifier of its conversation
🔗 Post linkpost_urlLink to the post on x.com
🏷 Post typepost_typetweet, reply, retweet or quote_tweet
💬 Textpost_textPost text, without the trailing short link
🕒 TimetimestampPosting time in ISO format, UTC
🌐 LanguagelanguageLanguage code of the post
📌 Pinnedis_pinnedWhether the post is the profile's pinned post
🔠 HashtagshashtagsList of hashtags, each starting with #
👥 MentionsmentionsList of mentioned accounts, each starting with @
🔗 Links in the postexpanded_urlsList of objects with short, expanded and display

Engagement

LabelFieldWhat it holds
💬 Repliesreply_countNumber of replies
🔁 Repostsrepost_countNumber of reposts
👍 Likeslike_countNumber of likes
🗨 Quotesquote_countNumber of quote posts
👁 Viewsview_countNumber of views
🔖 Bookmarksbookmark_countNumber of bookmarks

Post relations

LabelFieldWhat it holds
🔁 Retweet flagis_retweettrue for a retweet
💬 Reply flagis_replytrue for a reply
🗨 Quote flagis_quote_tweettrue for a quote post
🎯 Reply targetreply_to_post_id, reply_to_userPost and account being replied to
📎 Quoted postquoted_postObject with post_id, post_url, post_text and author_handle
🖼 MediamediaList of media objects: type, url, duration_ms, thumbnail_url, video_url, width, height

Author and input

LabelFieldWhat it holds
👤 AuthorauthorObject with name, screen_name, description, location, followers_count, following_count, tweet_count, like_count, created_at, verified_type, profile_image_url, profile_url
🔗 Profile linkprofile_urlLink to the profile
📥 Inputinput_urlThe entry you gave for this profile

Note: Fields can be empty. The six engagement counts, language, timestamp, reply_to_post_id, reply_to_user and quoted_post are null when they do not apply or are not available. media is an empty list for posts without photos or videos. Photo items carry width and height, and video items carry duration_ms, thumbnail_url and video_url instead. verified_type is none, blue, gold or verified. For retweets, post_text holds the text of the original post.

What data can't X (Twitter) Profile Posts Scraper extract?

  • Searches by keyword, hashtag or topic are not supported. Only the profiles you list are read.
  • Lists of followers or accounts followed, direct messages and private or protected content are not saved.
  • Replies written by other accounts under a post are not collected.

For search, single posts, articles or profile analytics, see the scrapers in the Other X, Twitter and Reddit scrapers section.


How to scrape X (Twitter) profile posts

X (Twitter) Profile Posts Scraper is built for an easy start, even if you have never extracted data from the web.

  1. Create a free Apify account with your email.
  2. Open X (Twitter) Profile Posts Scraper.
  3. Add one or more profiles to Profile URLs or Usernames (profile_urls), one per line.
  4. Set Max Posts per Profile (max_posts), and optionally post_type, date_from and skip_retweets.
  5. Click Start and follow the status message, which shows how many posts are saved.
  6. Open the Output tab to view the posts as a table.
  7. Download the dataset as JSON, CSV, Excel, XML or HTML.

How much does it cost to scrape X (Twitter) profile posts?

X (Twitter) Profile Posts Scraper uses a pay-per-event model: you pay for each saved post, and platform usage is billed in addition. A result is one saved dataset row.

PlanPrice per resultPrice per 1,000 results
Free$0.001$1.00
Bronze$0.0009$0.90
Silver$0.0008$0.80
Gold$0.0007$0.70

Each run also charges a start event of $0.00005 per GB of memory, with a minimum of one event. The default memory is 1 GB (1024 MB), so a run starts with one event, which is $0.00005.

For example, collecting 5,000 posts on the Silver plan costs 5,000 x $0.0008 = $4.00 for results, plus platform usage and the start event. See the pricing tab for all events.

Is scraping X (Twitter) profile posts free?

You can start for free. The $5 monthly credit on the Apify Free plan covers about 5,000 results at the Free price of $0.001, before platform usage. Higher plans pay less per result, down to $0.0007 on Gold. You can also set a maximum spend per run, and the Actor stops cleanly and keeps the rows already saved.


Input

The only required field is Profile URLs or Usernames (profile_urls). Set the input in the Actor's interface or send it as JSON through the API. This example collects up to 10 posts from one profile:

{
"profile_urls": [
"https://x.com/natgeo"
],
"max_posts": 10,
"post_type": "all",
"date_from": "",
"skip_retweets": false,
"proxyConfiguration": {
"useApifyProxy": false
}
}

See the input tab for the full description of every field.

FieldTypeRequiredDefaultDescription
profile_urlsarrayYesnoneProfile URLs, @usernames or bare usernames. One per line.
max_postsintegerNo10Maximum posts to collect per profile (0 to 100000). 0 means no cap.
post_typestringNoallall for tweets and replies, or tweets_only for no replies.
date_fromstringNoemptyOnly collect posts on or after this date: 7d, 30d, 90d or YYYY-MM-DD. Empty means all time.
skip_retweetsbooleanNofalseExclude retweets from the results.
proxyConfigurationobjectNo{"useApifyProxy": false}Optional proxy settings. Leave unchanged unless you need your own.

Profile URLs or Usernames

Add one profile per line. Profile links on x.com or twitter.com, @handle and the bare username all work, and duplicate entries are read again and billed again, so list each profile once.

  • ✅ Good: https://x.com/natgeo, @natgeo or natgeo
  • ❌ Bad: https://x.com/home or https://x.com/search?q=news (these are pages, not profiles)

Warning: If one entry is not a valid profile, the run stops with an input error before any post is collected. Check the list before you start.

Max Posts per Profile

max_posts applies to each profile separately, so 3 profiles with 10 can save up to 30 posts. Any number from 0 to 100000 is accepted.

  • ✅ Good: 10 for a first test, or 200 for a deeper history
  • ❌ Bad: 0 on a very active profile without a spend limit

Warning: 0 removes the cap, so the run keeps collecting until X shows no more posts for the profile. Every saved post is billed, so set a maximum spend per run.

Date From

Use 7d, 30d or 90d (any number followed by d) for the last days, or an exact date such as 2026-01-01. Dates are read as UTC. Once the scan of a profile reaches older posts, it stops.

  • ✅ Good: 30d or 2026-01-01
  • ❌ Bad: 01/01/2026 or last month

Warning: A value in any other format stops the run with an input error.


Output

Results appear in the Output and Storage tabs of the run, as a table or JSON. Pick the fields you need and download them as JSON, CSV, Excel, XML or HTML. The dataset has two ready-made views: Overview, with the main post fields, and Engagement, with the six engagement counts. A run summary is saved to the key-value store under RUN_SUMMARY, with totalPosts, profilesOk, profilesTotal, profilesFailed, durationSecs and spendLimitHit.

JSON example

Results for the input example above, one post row:

{
"post_id": "1900000000000000001",
"post_url": "https://example.com/example_user/status/1900000000000000001",
"conversation_id": "1900000000000000001",
"post_type": "tweet",
"post_text": "Example post text with #example and @example_friend.",
"timestamp": "2026-01-01T12:00:00Z",
"language": "en",
"is_pinned": false,
"hashtags": ["#example"],
"mentions": ["@example_friend"],
"expanded_urls": [
{
"short": "https://example.com/s/abc",
"expanded": "https://example.com/article",
"display": "example.com/article"
}
],
"reply_count": 12,
"repost_count": 34,
"like_count": 560,
"quote_count": 7,
"view_count": 12000,
"bookmark_count": 21,
"is_retweet": false,
"is_reply": false,
"is_quote_tweet": false,
"reply_to_post_id": null,
"reply_to_user": null,
"quoted_post": null,
"media": [
{
"type": "photo",
"url": "https://example.com/media/photo.jpg",
"duration_ms": null,
"thumbnail_url": null,
"video_url": null,
"width": 1200,
"height": 800
}
],
"author": {
"name": "Example User",
"screen_name": "example_user",
"description": "Example profile description.",
"location": "Example City",
"followers_count": 150000,
"following_count": 120,
"tweet_count": 8200,
"like_count": 4300,
"created_at": "2010-05-20T09:30:00Z",
"verified_type": "blue",
"profile_image_url": "https://example.com/media/avatar.jpg",
"profile_url": "https://example.com/example_user"
},
"profile_url": "https://example.com/example_user",
"input_url": "https://x.com/natgeo"
}

For a quote post that carries a video, the quoted_post and media fields look like this:

{
"post_type": "quote_tweet",
"is_quote_tweet": true,
"quoted_post": {
"post_id": "1900000000000000002",
"post_url": "https://example.com/example_friend/status/1900000000000000002",
"post_text": "Example quoted post text.",
"author_handle": "example_friend"
},
"media": [
{
"type": "video",
"url": "https://example.com/media/preview.jpg",
"duration_ms": 15000,
"thumbnail_url": "https://example.com/media/preview.jpg",
"video_url": "https://example.com/media/video.mp4"
}
]
}

Notes and limitations

  • post_type is retweet, reply, quote_tweet or tweet, checked in that order, so a retweet is never labelled as a reply.
  • The same post is saved only once per profile in a run.
  • Posts that X marks as unavailable are skipped.
  • A profile that cannot be found or read adds to profilesFailed in RUN_SUMMARY and gives no rows.
  • If a run cannot start, it ends with 0 posts and a status message that points you to the log.
  • A profile can return fewer posts than max_posts when X shows no more posts for it.

Tips and advanced usage

  • Run a small test first with max_posts set to 10, then raise it.
  • Use post_type set to tweets_only together with skip_retweets to focus on what the profile wrote itself. Quote posts are still kept.
  • Schedule a run with date_from set to 7d to collect only recent posts for monitoring.
  • Open the Engagement view of the dataset to compare likes, reposts, replies, quotes, views and bookmarks side by side.
  • Scrape multiple Twitter profiles in one run, and filter tweets by date range with date_from.
  • Every row has a post link in post_url, so the Twitter post URLs are ready to open or share.

Ways to use the posts

  • Twitter brand monitoring: schedule runs on your own and rival accounts and review new posts each week.
  • Twitter competitor analysis: compare posting pace, hashtags and Twitter engagement metrics across accounts.
  • Twitter influencer research: rank creators by the likes and retweets count of their posts.
  • Twitter sentiment analysis: feed post text and language codes into your own models.
  • Social media monitoring: keep a running archive of public posts as social listening data.
  • Twitter content research: see which hashtags and mentions come with the most views.
  • Twitter dataset for AI: collect posts from many accounts with the same fields for model training or studies.
  • Account checks: read the Twitter follower count in the author object. Its verified type separates Twitter verified accounts from the rest, and is_pinned marks a pinned tweet.
  • Twitter data export: download the rows as CSV or Excel, with tweet text and timestamps in plain columns.
  • Twitter analytics data: combine the profile links in profile_url with the counts in your own sheets. Compare the tweet view count with the quote tweets and replies.
  • Scrape Twitter posts for a profile: the posts of each account arrive as one row per post.
  • Twitter user tweets: hashtags and mentions are saved as lists on every row.

Integrations and API

Can I use X (Twitter) Profile Posts Scraper as an API?

Yes. The Apify API lets you start runs, schedule them and fetch results programmatically. Use the apify-client package for Node.js or Python, and see the API tab for ready-to-use code.

How to scrape X (Twitter) profile posts with Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("data_minds/x-twitter-profile-posts-scraper").call(run_input={
"profile_urls": ["https://x.com/natgeo"],
"max_posts": 10,
"post_type": "all",
"date_from": "",
"skip_retweets": False,
"proxyConfiguration": {"useApifyProxy": False},
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

Can I integrate X (Twitter) Profile Posts Scraper with other apps?

Yes. Connect it to Make, Zapier, Google Sheets, Slack and more through Apify integrations, or use webhooks to trigger an action when a run finishes. Schedule runs to keep your data fresh.

Can I use X (Twitter) Profile Posts Scraper with AI agents (MCP)?

Yes. Connect it to Claude and other MCP clients through the Apify MCP server. Open the MCP tab for the setup steps.


Other X, Twitter and Reddit scrapers

ActorWhat it does
🔗 X (Twitter) Scraper Unlimited – No LimitsScrape X (Twitter) posts, profiles, articles, threads and analytics from links, handles or search terms.
💬 Reddit Post Comments ScraperScrape every comment from any Reddit post or thread, with nested replies, scores, authors and timestamps.
👽 Reddit Scraper - Posts, Comments, Search & SubredditsBulk Reddit scraping of post, subreddit, user or search URLs, with nested comment threads.

FAQ

Web scraping is generally legal when you collect publicly available data, but you must respect personal data rules such as GDPR, the terms of X and copyright. Only collect personal data for a legitimate reason. Read Is web scraping legal? for background. This is not legal advice.

How does the Twitter profile scraper work?

You give it profile links, @handles or usernames, plus optional settings for the number of posts, post type, start date and retweets. It reads the public posts of each profile, applies your settings, and saves one row per post to the dataset with text, engagement counts, media and author details.

Why scrape X (Twitter) profile posts?

Profiles hold public statements, campaigns and reactions that change daily. Teams collect posts for competitor monitoring, influencer comparison, sentiment analysis and research datasets. Structured rows with engagement counts, hashtags and timestamps are easier to sort, filter and compare than copying posts by hand, and a schedule keeps the data current.

Why does the Twitter profile scraper return fewer posts than expected?

Several settings reduce the rows saved. Check max_posts, date_from, post_type and skip_retweets first, because each can leave posts out. A profile can also show fewer posts than you asked for. Read the status message and the RUN_SUMMARY record to see how many profiles worked.

Do I need an X account or API key to use the Twitter profile scraper?

No. The input has no field for an X login, cookies or API key, and you only need an Apify account to run it. Enter the profiles, start the run, and download the dataset when it finishes. Private or protected accounts are not covered.

Can I scrape several X profiles at once?

Yes. Add as many profiles as you like to profile_urls, one per line, and they are read in the same run. The max_posts limit applies to each profile separately, and every row carries input_url and the author fields, so you can tell the accounts apart in one dataset.

Can I export tweets from a profile to CSV or Excel?

Yes. Every run stores the posts in a dataset that you can download as JSON, CSV, Excel, XML or HTML from the Output tab or the API. Nested fields such as author, media and quoted_post are easiest to use in JSON, while the Overview and Engagement views suit spreadsheets.

Use X (Twitter) Profile Posts Scraper when you already know the accounts and want the posts of each profile with engagement counts. If you start from links, handles, search terms or post ids, or need profiles, X Articles, threads and profile analytics, try X (Twitter) Scraper Unlimited – No Limits instead.

Twitter profile scraper not working?

Start with the run log and the status message, which explain most problems in plain words. Check that every entry is a valid public profile and that date_from uses the right format. If a run still fails or looks wrong, open the Issues tab with your run link and we will look into it.


Support and feedback

Found a bug or have a feature request? Please create an issue on the Issues tab.

Need a custom solution or more data? Contact us at hello.dataminds@gmail.com.

Built and maintained by the data_minds team on Apify.

X (Twitter) Profile Posts Scraper is an independent tool and is not affiliated with or endorsed by X Corp. You are responsible for using the data in line with the terms of X and applicable laws.