# Tweet Scraper - Tweets by URL or ID, No Login (`vonsensey/tweet-scraper`) Actor

Paste tweet URLs or ids and get each tweet in full: text, exact like and reply counts, author with verification flags, hashtags, mentions, expanded links, photos and the highest-bitrate MP4, plus the quoted tweet. No login, no cookies, no proxy.

- **URL**: https://apify.com/vonsensey/tweet-scraper.md
- **Developed by:** [Blackcube](https://apify.com/vonsensey) (community)
- **Categories:** Social media, Developer tools, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 tweet delivereds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Tweet Scraper — Tweets by URL or ID, No Login

**More from this account:** [YouTube Transcript Suite](https://apify.com/vonsensey/youtube-transcript-scraper) · [Website Contact & Email Suite](https://apify.com/vonsensey/website-contact-email-extractor) · [Career Site & ATS Jobs Suite](https://apify.com/vonsensey/career-page-job-postings-scraper-api) · [Google News Suite](https://apify.com/vonsensey/google-news-scraper-api) · [Keyword Research Suite](https://apify.com/vonsensey/google-keyword-ideas-scraper) · [Shopify Store Intelligence Suite](https://apify.com/vonsensey/shopify-store-leads-scraper) · [eBay Data Suite](https://apify.com/vonsensey/ebay-scraper-api) · [Amazon Reviews Suite](https://apify.com/vonsensey/amazon-reviews-scraper-api) · [Reddit](https://apify.com/vonsensey/reddit-scraper-posts-comments-api) · [Meta Ad Library](https://apify.com/vonsensey/facebook-ads-library-scraper-meta-ad-api) · [Vinted](https://apify.com/vonsensey/vinted-scraper-api) · [Trustpilot Review Intelligence Suite](https://apify.com/vonsensey/trustpilot-reviews-scraper) · [App Store & Google Play Reviews Suite](https://apify.com/vonsensey/app-store-google-play-reviews-scraper) · [Etsy Research Suite](https://apify.com/vonsensey/etsy-scraper) · [YouTube Comments Intelligence Suite](https://apify.com/vonsensey/youtube-comments-scraper) · [Telegram Channel Intelligence Suite](https://apify.com/vonsensey/telegram-channel-scraper-api) · [Business Reviews Suite](https://apify.com/vonsensey/business-reviews-aggregator-scraper-api) · [Google Trends Suite](https://apify.com/vonsensey/google-trends-scraper) · [Amazon Product Data Suite](https://apify.com/vonsensey/amazon-product-scraper-api) · [Google Sheets Suite](https://apify.com/vonsensey/google-sheets-scraper-api) · [TikTok Suite](https://apify.com/vonsensey/tiktok-scraper-api) · [Snapchat Suite](https://apify.com/vonsensey/snapchat-scraper-api) · [LinkedIn Public Data Suite](https://apify.com/vonsensey/linkedin-scraper-api) · [Instagram Suite](https://apify.com/vonsensey/instagram-posts-scraper-api) · [Contact Validation Suite](https://apify.com/vonsensey/email-verifier-validator-api) · [Google Maps Suite](https://apify.com/vonsensey/google-maps-reviews-scraper-api)

Paste tweet URLs or numeric ids and get each tweet back in full, one flat row each. Reads X's own
public embed endpoint — the same one an embedded tweet on a news site calls — so there is **no
account, no cookie, no API key and no proxy** anywhere in the path.

**What you get per tweet:** text, language, posted time, exact like and reply counts, the author
with verification flags, hashtags, mentions, expanded links (not `t.co` stubs), every photo, the
**highest-bitrate MP4** for video and GIFs, and the quoted tweet when there is one.

### What this does and does not do

It resolves **tweets you already have references to**. That is the honest scope, and it is stated
here rather than discovered after you have paid:

| | |
|---|---|
| ✅ Tweet URL or id → the full tweet | x.com, twitter.com, mobile and vx/fx mirror links, with or without a query string |
| ✅ Bulk, on a schedule | send ten or ten thousand; built to be called from a pipeline in a loop |
| ✅ Quoted tweets, media, expanded links | including the MP4 ladder picked at highest bitrate |
| ❌ Keyword or hashtag **search** | X's search surface needs an authenticated account; this Actor will not pretend otherwise |
| ❌ Profile timelines / follower lists | the syndication timeline route answered HTTP 429 from plain exits when measured 2026-09-11 |
| ❌ Retweet and view counts | X's public payload does not carry them, so there is no column that can never fill |

### What you pay for

**$0.40 per 1,000 tweets** at the GOLD tier, charged per tweet actually delivered. No run-start
fee, no monthly minimum.

Free, every time:

- a tweet that is **deleted, protected or age-restricted** — you get a row saying which, at no charge
- a string that is **not a tweet URL or id** — a free `invalid` row naming the reason
- the **same tweet twice** in one run — deduplicated before it can be billed twice
- the **coverage and summary** rows, so you can always reconcile what you asked for against what arrived

A run that resolves nothing costs nothing.

### Input

```json
{
  "tweets": [
    "https://x.com/jack/status/20",
    "https://x.com/elonmusk/status/1585841080431321088",
    "1349129669258448897"
  ],
  "maxItems": 1000
}
```

Feeding it from n8n, Make or a CSV? Send `records` instead: the tweet reference is found in
whichever field is named `tweet`, `url`, `id`, `link` or `status`, and **every other field comes
back on the row as `passthrough`** — so your own record ids ride along and you can join the
result straight back onto your table.

```json
{ "records": [{ "tweet_url": "https://x.com/jack/status/20", "crm_id": "A-1042", "owner": "ana" }] }
```

### Output

One row per tweet, plus free bookkeeping rows. `type` tells them apart: `tweet`, `unavailable`,
`invalid`, `coverage`, `summary`.

```json
{
  "type": "tweet",
  "id": "20",
  "url": "https://x.com/jack/status/20",
  "text": "just setting up my twttr",
  "lang": "en",
  "createdAt": "2006-03-21T20:50:14.000Z",
  "likeCount": 308074,
  "replyCount": 18017,
  "author": { "screenName": "jack", "name": "jack", "verified": false, "blueVerified": true },
  "hashtags": [], "mentions": [], "links": [], "media": [],
  "quotedTweetId": null,
  "passthrough": null
}
```

### Reliability

Every run ends with a `coverage` row: how many tweets you asked for, how many arrived, how many
were unavailable and why, and whether the run finished or stopped early. Inputs the run never
reached get a free row each rather than vanishing — silence about missing rows is the most common
complaint on rival listings in this cluster, so it is designed out.

Each tweet carries its own wall-clock budget, clamped on the HTTP request itself rather than
merely checked between retries, so one slow fetch cannot consume the run.

### Live endpoint: one tweet per call, ~170 ms

If you are enriching a list rather than running a batch, call the Actor as an HTTP endpoint instead
of starting a run per tweet. It stays warm between calls, so a request costs you a fraction of a
container start and answers in **about 170 ms** instead of about three seconds.

```bash
curl "https://vonsensey--tweet-scraper.apify.actor/?id=1349129669258448897&token=$APIFY_TOKEN"
```

`id` takes a tweet URL or a bare id (`url=` and `tweet=` work too). The reply is the same tweet
object the dataset would hold:

```json
{ "ok": true, "charged": true, "tweet": { "id": "...", "text": "...", "likeCount": 507849, "...": "..." } }
```

```python
import os, requests
BASE = "https://vonsensey--tweet-scraper.apify.actor/"
tok = os.environ["APIFY_TOKEN"]
for tweet_id in my_list:                      # your CRM rows, your spreadsheet, your queue
    r = requests.get(BASE, params={"id": tweet_id, "token": tok}).json()
    if r["ok"]:
        print(r["tweet"]["likeCount"], r["tweet"]["text"])
```

Same billing as a batch run, per tweet delivered. **A tweet that is deleted, protected or
age-restricted answers `{"ok": false, "charged": false}` and costs nothing**, and input that is not
a tweet reference returns 400 and costs nothing. Each call is billed on its own, so asking for the
same tweet twice is two deliveries — unlike a batch run, which de-duplicates its input list.

Use the batch input above when you have the whole list up front: one run over 1,000 ids is cheaper
than 1,000 calls.

### Use it from n8n, MCP, the API or a schedule

Built to be called by a workflow, not only from the Store form. The Actor is `vonsensey/tweet-scraper`; every snippet below sends `{}`, which runs the defaults shown on the form — replace it with your own input.

#### n8n

Install the **Apify** community node (`@apify/n8n-nodes-apify` under *Settings → Community Nodes*, or search "Apify" on n8n Cloud). Add **Apify → Run Actor** with Actor `vonsensey/tweet-scraper` and your input JSON, then **Apify → Get Dataset Items** on the run's `defaultDatasetId` and pipe the rows anywhere. For scheduled runs, the **On new Apify Event** trigger fires when a run of this Actor finishes.

#### MCP (Claude, Cursor, VS Code, any MCP client)

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=vonsensey/tweet-scraper",
      "headers": {
        "Authorization": "Bearer <YOUR_APIFY_TOKEN>"
      }
    }
  }
}
```

Your agent then calls `vonsensey/tweet-scraper` as a tool with the same input the form takes and reads the dataset back.

#### REST API (one call, rows in the response)

```bash
curl -X POST "https://api.apify.com/v2/acts/vonsensey~tweet-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" -d '{}'
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("vonsensey/tweet-scraper").call(run_input={})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row)
```

#### JavaScript

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('vonsensey/tweet-scraper').call({});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

#### Make, Zapier, LangChain, CrewAI

The Apify app in **Make** and **Zapier** has a *Run an Actor* module: pick `vonsensey/tweet-scraper`. In **LangChain** and **CrewAI** the Apify tool wrappers take the same Actor id. A daily **schedule** needs nothing but the Console: *Schedules → Create → this Actor → cron*, and the dataset fills on its own.

> **Run it without configuring anything** — [Scrape tweets by URL or ID: text, likes, author, media](https://apify.com/vonsensey/tweet-scraper/examples/tweets-by-url-or-id-text-likes-author-media), a ready-made example you can start as-is or copy.

### Use cases

- **Enrich a list of tweet links.** Tweet URLs or ids from a CRM, a spreadsheet or a monitoring tool come back as one flat row each: text, language, posted time, exact like and reply counts, the author with verification flags, hashtags, mentions and expanded links.
- **Archive media before it disappears.** Every photo URL and the highest-bitrate MP4 for video and GIFs, so a tweet you cite in a report or a dataset still exists tomorrow.
- **Track engagement on tweets you already know.** Re-run the same ids on a schedule and diff the like and reply counts; each run bills only the tweets it delivers.
- **Resolve quoted tweets in one hop.** The quoted tweet rides along on the row, so a chain of quote-tweets does not need a second run.
- **Feed it from n8n, Make or a CSV.** Send `records` and every extra field comes back on the row as `passthrough`, or call it as a warm HTTP endpoint (Standby) that answers one tweet per call.

### Run it on a schedule

A one-off pull answers a question; a schedule answers it every day without you. Open **Schedules** in the Apify Console, point a cron at this Actor, and the dataset keeps filling on its own — no server, no cron box, no babysitting. Everything here is built to be re-run: you are billed per tweet delivered, and a run that resolves nothing costs nothing — there is no start fee.

### FAQ

#### Do I need an X/Twitter API key, a login or a proxy?

No. It reads X’s public embed endpoint — the one an embedded tweet on any news site calls — from Apify’s own exit. No account, no cookie, no API key, no proxy, nothing to configure.

#### Can it search by keyword or hashtag, or read a profile timeline?

No, and the listing says so up front. X’s search surface needs an authenticated account, and the public timeline route answered HTTP 429 from plain exits when measured (2026-09-11). This Actor resolves tweets you already have references to: URLs or ids from x.com, twitter.com, mobile and vx/fx mirror links.

#### What does a deleted or protected tweet cost?

Nothing. A tweet that is deleted, protected or age-restricted comes back as a free `unavailable` row that says which; a string that is not a tweet reference is a free `invalid` row naming the reason; the same tweet twice in one run is de-duplicated before it can be billed twice.

#### Are retweet and view counts included?

No. X’s public payload does not carry them, so there is no column for them rather than a column that never fills. Like and reply counts are exact.

#### What do I pay for a run that finds nothing?

Nothing. There is no start fee and no monthly minimum: $0.40 per 1,000 tweets at the GOLD tier, charged per tweet actually delivered, so a run that resolves nothing costs nothing.

#### Is this an official X product?

No. Unofficial — not affiliated with, endorsed by, or sponsored by X Corp. It reads only the public embed data X serves to any website and never signs in.

***

Something wrong, or a field you need that is missing? Open an issue on the **Issues** tab — it is read and it gets fixed. If this saved you time, a rating on the Store page helps the next person find it.

# Actor input Schema

## `tweets` (type: `array`):

One tweet URL or numeric id per line. x.com and twitter.com links both work, with or without a query string. Leave empty to run the built-in example.

## `records` (type: `array`):

Objects from n8n, Make or a CSV. The tweet URL or id is found in whichever field is named tweet, url, id, link or status; every other field rides along and comes back on the row as `passthrough`.

## `maxItems` (type: `integer`):

Stop after this many tweets have been delivered. Free rows do not count.

## `maxCostUsd` (type: `integer`):

Optional hard ceiling. The run stops before the charge that would cross it.

## Actor input object example

```json
{
  "tweets": [
    "https://x.com/jack/status/20",
    "https://x.com/elonmusk/status/1585841080431321088"
  ],
  "maxItems": 1000
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "tweets": [
        "https://x.com/jack/status/20",
        "https://x.com/elonmusk/status/1585841080431321088"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vonsensey/tweet-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "tweets": [
        "https://x.com/jack/status/20",
        "https://x.com/elonmusk/status/1585841080431321088",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("vonsensey/tweet-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "tweets": [
    "https://x.com/jack/status/20",
    "https://x.com/elonmusk/status/1585841080431321088"
  ]
}' |
apify call vonsensey/tweet-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vonsensey/tweet-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/LqQoqfH1A8hLYkjsQ/builds/epFXwPPVlI9eK9Plz/openapi.json
