DRAFT tutorial. Not indexed by search engines. Not yet listed on the tutorials hub. Review + iterate in the Claude Code session, then merge the "Publish tutorial" PR to make it public.

How to Scrape Twitter/X: Profiles and Tweets Without a Login or API Key

Pass in a list of Twitter/X usernames and get back structured data for each account: full profile stats plus recent tweets with likes, retweets, view counts, replies, bookmark counts, hashtags, mentions, and expanded URLs. Up to 1,000 tweets per account. No login, no developer API key, no browser automation. The NanoScrape Twitter Scraper runs on Apify at $0.0003 per item delivered.

Apify dataset view showing Twitter profile and tweet records with fields for username, follower count, tweet text, like count, retweet count, and view count
One row per tweet, with the full author profile embedded. Export to JSON, CSV, or XLSX.
Difficulty: Beginner
Time: 5 minutes
Cost: ~$0.31 per 1,000 items ($0.01 start + $0.0003 per tweet or profile)
Tools: Apify, NanoScrape Twitter Scraper
Open the actor on Apify View on Apify Console

In this tutorial

  1. What you get
  2. Prerequisites
  3. Step 1: Open the actor
  4. Step 2: Configure the input
  5. Step 3: Run and download results
  6. Output structure
  7. Protected accounts, rate limits, and caveats
  8. Use with n8n or Make
  9. Use with AI agents via MCP
  10. What it costs
  11. FAQ

What you get

For every username you submit, the actor does two lookups behind the scenes: a profile fetch and a timeline fetch. What comes back:

If you only need profile data, set tweetsPerUser to 0 and turn on includeProfileOnlyItems. Each user produces one row where item_type is profile and the tweet field is omitted.

Prerequisites

No Twitter/X login or developer API key needed. The actor calls the same public GraphQL endpoint that x.com uses for logged-out browsing. You do not need a personal X account, a developer app, or a bearer token.
STEP 1

Open the actor on Apify

  1. Open the NanoScrape Twitter/X Profiles + Tweets Scraper on Apify.
  2. Click Try for free. Sign up with Google or email if you do not have an account. It takes about a minute.
  3. Apify redirects you to the actor's input editor in Apify Console.
NanoScrape Twitter X Profiles Tweets Scraper actor page on Apify showing the description, pricing summary, and Try for free button
The actor page on Apify. Click Try for free to open the input editor.
STEP 2

Configure the input

In the Input tab, paste your accounts in the usernames array. Mix formats freely: plain handles, @-prefixed handles, or full profile URLs. The actor normalizes them all before the first API call.

{
  "usernames": [
    "openai",
    "@AnthropicAI",
    "https://x.com/GoogleDeepMind"
  ],
  "tweetsPerUser": 20,
  "includeReplies": false,
  "includeRetweets": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}

Input fields and when to change them:

Apify Console input editor for the Twitter scraper showing the usernames array and tweetsPerUser field filled in
The input editor in Apify Console. Replace the example handles with your own list.
Tip: for competitor research, start with tweetsPerUser: 100 and includeRetweets: false. You get the last 100 original posts per account, ready for sentiment analysis or content benchmarking, without retweet noise inflating the count.
STEP 3

Run and download results

  1. Click Start at the bottom of the input page.
  2. Apify shows a live log. For a batch of 5 accounts at 20 tweets each, the run finishes in under 30 seconds.
  3. When the status changes to Succeeded, click the Results tab to open the dataset.
  4. Use the Export button to download as JSON, JSONL, CSV, or XLSX. You can also read the dataset directly via the Apify API or from an n8n, Make, or Zapier workflow.
Apify Console dataset view after a successful Twitter scraper run showing rows with tweet text, engagement metrics, and author profile fields
The dataset after the run. One row per tweet, with the author profile embedded in every row.
The output is one row per tweet, not one row per user. A run for 3 accounts at 20 tweets each produces up to 60 rows. If you also enabled includeProfileOnlyItems, 3 additional profile rows appear in the dataset.

Output structure

Each dataset row has three top-level fields: item_type, tweet, and author. The following example is taken from the actor README output schema (not a live run; field names and structure are accurate, values are illustrative):

{
  "item_type": "tweet",
  "tweet": {
    "id": "1900000000000000000",
    "text": "Full tweet text here.",
    "lang": "en",
    "created_at": "2026-01-15T16:00:24Z",
    "is_reply": false,
    "is_retweet": false,
    "is_quote": false,
    "is_pinned": false,
    "url": "https://x.com/example_handle/status/1900000000000000000",
    "engagement": {
      "reply_count": 186,
      "retweet_count": 638,
      "like_count": 2444,
      "quote_count": 12,
      "bookmark_count": 89,
      "view_count": 484164
    },
    "entities": {
      "hashtags": [],
      "mentions": [{"username": "another_handle", "user_id": "999999999"}],
      "urls": [
        {
          "url": "https://t.co/exampleShort",
          "expanded_url": "https://example.com/blog/post",
          "display_url": "example.com/blog/post"
        }
      ],
      "cashtags": [],
      "media": [{"type": "photo", "url": "https://pbs.twimg.com/media/..."}]
    }
  },
  "author": {
    "username": "example_handle",
    "display_name": "Example Company",
    "bio": "Example bio for the account.",
    "location": "Example City",
    "website_expanded": "https://example.com",
    "verified": false,
    "blue_verified": true,
    "followers_count": 12345,
    "following_count": 188,
    "tweet_count": 4200,
    "created_at": "Tue Sep 01 08:38:01 +0000 2015",
    "profile_url": "https://x.com/example_handle"
  },
  "scraped_at": "2026-07-27T09:00:00Z"
}

A few fields worth calling out:

Protected accounts, rate limits, and caveats

Use with n8n or Make

The actor runs on Apify's public API, so any tool that can make an HTTP POST can trigger it. The simplest path in n8n or Make is the Apify run-sync endpoint, which blocks until the run finishes and returns the dataset as a JSON array.

n8n

Install the Apify n8n node (pre-installed on n8n Cloud; add via Community Nodes on self-hosted). Use the Run an Actor and get dataset operation. Set Actor ID to santamaria-automations/twitter-x-profiles-tweets-scraper, paste your input JSON, and wire the output to a Google Sheets Append node, a database node, or wherever you want the data to land.

For a scheduled monitor: replace the Manual Trigger with a Schedule Trigger, and use a Set node before the Apify node to build the usernames array dynamically from a Google Sheet, Airtable, or any other source. Use an n8n Cloud account if you want a managed instance with no maintenance.

Make (formerly Integromat)

Use the HTTP module to POST to the Apify run-sync endpoint. The URL pattern is:

https://api.apify.com/v2/acts/santamaria-automations~twitter-x-profiles-tweets-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN

Set the content type to application/json and pass your input in the request body. Make returns the full dataset as a parsed JSON array in one step.

Use with AI agents via MCP

The actor is available as an MCP tool for any AI client that supports the Model Context Protocol: Claude Desktop, Claude.ai, Cursor, VS Code, LangChain, LlamaIndex, and others. Add the server to your MCP configuration:

https://mcp.apify.com?tools=santamaria-automations/twitter-x-profiles-tweets-scraper

Once connected, you can give your AI agent instructions like:

Clients that support dynamic tool discovery (Claude.ai, VS Code) load the full input schema automatically via add-actor. You do not need to configure the tool parameters manually.

What it costs

Some quick calculations:

Pricing source: these figures come from the actor's live pay-per-event pricing configuration (effective 2026-06-10). Check the actor page for current rates before budgeting a large run.

FAQ

Do I need a Twitter/X login, developer app, or API key?

No. The actor calls the same public GraphQL endpoint that x.com uses for logged-out browsing. You do not need a personal X account, a Meta developer app, or any X-issued credentials. A free Apify account is all you need.

Can I scrape private (protected) Twitter accounts?

No. Protected accounts are visible only to approved followers. The actor returns the public profile metadata for protected accounts (username, bio, follower count) but cannot retrieve their tweets. The author.is_protected field in the output will be true.

How many tweets can I get per account?

Up to 1,000 tweets per account, controlled by the tweetsPerUser input field. Set it to 0 and enable includeProfileOnlyItems if you only need profile-level data.

Does this work for both twitter.com and x.com handles?

Yes. The actor accepts bare handles, @-prefixed handles, and full URLs on both twitter.com and x.com domains. It normalizes all of them to the same username before making the API calls.

What if X rate-limits the scraper mid-run?

If X returns a rate-limit response, the actor automatically rotates to a fresh residential proxy session and retries. It repeats this up to maxIPRotations times (default 5). If all retry attempts are exhausted, the actor logs an escalation message and stops the run. Splitting a very large batch into multiple smaller runs reduces the chance of hitting rate limits.

How do I get only original tweets and not retweets or replies?

Set "includeReplies": false (the default) and "includeRetweets": false in the input. You will get only original tweets and quote-tweets from the user's timeline.

Is scraping public Twitter/X data legal?

Scraping publicly visible data is generally permitted in most jurisdictions. The hiQ Labs v. LinkedIn ruling in the US established that scraping public profiles does not violate the Computer Fraud and Abuse Act. X's Terms of Service restrict automated access, but ToS violations are a contractual matter, not a criminal one. The legal picture also varies by country and intended use. Consult a lawyer if you have specific compliance questions.

Can I run this on a schedule and track follower growth over time?

Yes. In Apify Console, open the actor and use the Schedules tab to configure a recurring run. In n8n, replace the Manual Trigger with a Schedule Trigger. Each run appends a new batch to the dataset, so you can plot follower count or engagement metrics as a time series by including the scraped_at timestamp in your analysis.

Related resources

Open the actor on Apify View on Apify Console