# X (Twitter) Scraper API – Tweets, Search & User Posts (`lance_api/x-tweet-scraper-api`) Actor

Scrape public X/Twitter tweets, search results, and user posts into structured JSON with text, authors, media, timestamps, and engagement data for analytics, monitoring, AI, and automation.

- **URL**: https://apify.com/lance\_api/x-tweet-scraper-api.md
- **Developed by:** [LanceAPI](https://apify.com/lance_api) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.20 / 1,000 successful tweet results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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

## X (Twitter) Tweet Scraper API

Search X posts, retrieve individual Tweets, and collect Tweets from public profiles in one batch-friendly Apify Actor. Every successful Tweet is stored as one Dataset item with normalized text, author details, engagement metrics, media URLs, and input attribution.

### Overview

The Actor supports three ways to discover the same business object—a Tweet:

- **Search mode:** keywords, hashtags, or native X search queries
- **Tweet detail mode:** `x.com`/`twitter.com` status URLs or numeric Tweet IDs
- **User Tweets mode:** usernames, `@usernames`, or profile URLs

Inputs can be mixed in a single run. A failed input produces a structured error item and does not stop other inputs.

### Features

- X search with Top, Latest, or Media results
- Cursor-based search and profile pagination
- Batch inputs across all three modes
- Complete Tweet text, including Note Tweet/long-form text when exposed by X
- Author metadata and engagement counts
- All photos and video variants, including highest-bitrate MP4 selection
- Quote, retweet, and reply metadata
- Tweet and cursor deduplication
- Per-input errors that distinguish invalid input, not found, private, suspended, blocked, rate limited, no data, timeout, proxy, and parsing failures
- One Dataset item per successful Tweet
- Pay-per-result charging only after a successful Tweet item is stored

### Use cases

- Brand and topic research
- News and trend collection
- Public profile content analysis
- Social datasets for analytics and AI pipelines
- Tweet URL enrichment
- Scheduled research and Dataset exports

### Input

At least one of `searchQueries`, `tweetUrls`, or `profiles` must contain a value. All three may be provided together.

| Field           | Type     | Default | Description                                                |
| --------------- | -------- | ------- | ---------------------------------------------------------- |
| `searchQueries` | string\[] | —       | Keywords, hashtags, or search expressions; up to 1,000     |
| `sort`          | enum     | `top`   | `top`, `latest`, or `media` for Search inputs              |
| `profiles`      | string\[] | —       | Usernames, `@usernames`, or profile URLs; up to 1,000      |
| `tweetUrls`     | string\[] | —       | X/Twitter Tweet URLs or numeric Tweet IDs; up to 1,000     |
| `maxResults`    | integer  | `15`    | Maximum Tweets per Search or profile input; schema max 190 |

`maxResults` applies per Search query or profile. Free users receive up to 15 results per input. Starter, Scale, and Business users receive up to 190. Every Tweet URL/ID returns at most one Tweet.

### Search mode

Add one or more values to `searchQueries`. Simple keywords and hashtags work directly. Search type is a selectable field:

- `top`: relevant Tweet results
- `latest`: recent Tweet results
- `media`: Tweet results containing media

People and Lists search are intentionally outside this Tweet-only Actor. Their labels describe non-Tweet search categories, while the upstream endpoint returned Tweet-shaped timeline items in live validation rather than People/List objects, so exposing them would give users misleading semantics.

```json
{
  "searchQueries": ["OpenAI", "#AI"],
  "sort": "latest",
  "maxResults": 15
}
```

### Tweet detail mode

Supported forms include:

- `https://x.com/status_is_down/status/2034694288651473335`
- `https://twitter.com/status_is_down/status/2034694288651473335`
- `2034694288651473335`

URLs are normalized to `https://x.com/{username}/status/{tweetId}`. For an ID-only input, the canonical URL is built from the returned author when available.

```json
{
  "tweetUrls": ["https://x.com/status_is_down/status/2034694288651473335", "2034694288651473335"]
}
```

### User Tweets mode

Supported profile forms include `OpenAI`, `@OpenAI`, `https://x.com/OpenAI`, and `https://twitter.com/OpenAI`.

The Actor normalizes every supported form to a screen name and automatically paginates the public post timeline. Pinned posts are excluded so the results remain chronological.

```json
{
  "profiles": ["@OpenAI", "https://x.com/OpenAIDevs"],
  "maxResults": 15
}
```

### Mixed input example

```json
{
  "searchQueries": ["OpenAI"],
  "tweetUrls": ["2034694288651473335"],
  "profiles": ["@OpenAI"],
  "maxResults": 15,
  "sort": "latest"
}
```

### Output

Each successful Tweet is one Dataset item. Top-level convenience fields make the Dataset, CSV, and Excel exports useful immediately; nested objects preserve structured API data.

#### Success example

```json
{
  "inputType": "search",
  "inputValue": "OpenAI",
  "normalizedInput": "OpenAI",
  "success": true,
  "status": "success",
  "tweetId": "1234567890123456789",
  "url": "https://x.com/example/status/1234567890123456789",
  "text": "Tweet text...",
  "createdAt": "2026-09-02T10:00:00.000Z",
  "language": "en",
  "authorId": "12345",
  "authorUsername": "example",
  "authorName": "Example",
  "authorVerified": false,
  "likesCount": 100,
  "repliesCount": 10,
  "retweetsCount": 20,
  "quotesCount": 5,
  "bookmarksCount": 3,
  "viewsCount": 10000,
  "conversationId": "1234567890123456789",
  "isReply": false,
  "isRetweet": false,
  "isQuote": false,
  "inReplyToTweetId": null,
  "inReplyToUsername": null,
  "author": {
    "id": "12345",
    "username": "example",
    "name": "Example",
    "followersCount": 10000,
    "followingCount": 200
  },
  "engagement": {
    "likes": 100,
    "replies": 10,
    "retweets": 20,
    "quotes": 5,
    "bookmarks": 3,
    "views": 10000
  },
  "media": {
    "photos": [],
    "videos": []
  },
  "hashtags": [],
  "mentions": [],
  "urls": [],
  "quotedTweet": null,
  "retweetedTweet": null,
  "scrapedAt": "2026-09-02T10:01:00.000Z"
}
```

Fields not exposed by X are returned as `null` or empty arrays; values are not invented.

#### Error example

```json
{
  "inputType": "profile",
  "inputValue": "@missing_example",
  "normalizedInput": "missing_example",
  "success": false,
  "status": "not_found",
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested X profile could not be found.",
    "retryable": false
  },
  "scrapedAt": "2026-09-02T10:01:00.000Z"
}
```

Error items are not charged.

### Pricing

You pay only for successfully returned Tweets. There is no query fee and no start fee. Empty results, failed inputs, errors, duplicates, and non-Tweet search objects are not charged.

| Apify plan | Price per 1,000 successful Tweets |
| ---------- | --------------------------------: |
| Free       |                             $0.30 |
| Starter    |                             $0.25 |
| Scale      |                             $0.22 |
| Business   |                             $0.20 |

Prices start from **$0.20 per 1,000 successfully returned Tweets**.

### Limits

- Free: up to 15 Tweets per Search or profile input.
- Starter, Scale, and Business: up to 190 Tweets per Search or profile input.
- Tweet detail inputs return at most one Tweet each.
- The Actor stops as soon as the requested result limit is reached. Missing or repeated pagination cursors also stop collection safely.

### API usage

Start a run with the Apify API:

```bash
curl -X POST "https://api.apify.com/v2/acts/USERNAME~x-tweet-scraper-api/runs?token=APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["OpenAI"],"sort":"top","maxResults":15}'
```

Replace `USERNAME` and `APIFY_TOKEN` with your own values. You can also call the Actor from the Apify JavaScript/Python clients, schedules, webhooks, or integrations.

### Dataset

The default Dataset overview prioritizes status, input attribution, Tweet text, author, creation time, engagement, views, and canonical Tweet URL. JSON exports also contain nested author, engagement, media, quote, and retweet objects.

### Automation

Use Apify schedules to run recurring searches or profile collection. Use webhooks to notify downstream systems, and export Dataset items as JSON, CSV, Excel, XML, RSS, or JSONL using Apify storage APIs.

### Limitations

- X and upstream response structures can change without notice.
- Public profiles and public Tweets are the intended scope. Private, suspended, deleted, age-gated, region-restricted, or otherwise unavailable content may not be retrievable.
- Historical search depth and result ordering are controlled by X and are not guaranteed.
- Engagement and view counts reflect the values X returns at scrape time.

### Legal and compliance

Use this Actor only for lawful purposes. Respect applicable laws, privacy rights, intellectual-property rights, contractual obligations, and X's terms and policies. Collect only data you are authorized to process, avoid sensitive-personal-data misuse, and configure retention and access controls appropriate to your use case.

### Support

When reporting a problem, include the Actor run ID, input type, status/error code, and approximate time. Do not send X cookies, authentication tokens, proxy passwords, or other secrets in support messages.

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords, hashtags, or a search expression.

## `sort` (type: `string`):

Choose Top, Latest, or Media Tweet results.

## `profiles` (type: `array`):

Usernames, @usernames, or X/Twitter profile URLs.

## `tweetUrls` (type: `array`):

X/Twitter status URLs or numeric Tweet IDs.

## `maxResults` (type: `integer`):

Maximum Tweets per search or profile: up to 15 on Free and 190 on paid plans. Tweet detail inputs return one each.

## Actor input object example

```json
{
  "searchQueries": [
    "OpenAI"
  ],
  "sort": "top",
  "profiles": [
    "https://x.com/elonmusk"
  ],
  "maxResults": 15
}
```

# 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 = {
    "searchQueries": [
        "OpenAI"
    ],
    "profiles": [
        "https://x.com/elonmusk"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lance_api/x-tweet-scraper-api").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 = {
    "searchQueries": ["OpenAI"],
    "profiles": ["https://x.com/elonmusk"],
}

# Run the Actor and wait for it to finish
run = client.actor("lance_api/x-tweet-scraper-api").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 '{
  "searchQueries": [
    "OpenAI"
  ],
  "profiles": [
    "https://x.com/elonmusk"
  ]
}' |
apify call lance_api/x-tweet-scraper-api --silent --output-dataset

```

## MCP server setup

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

```

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/dYOm3ceq9e9PBnyJA/builds/6lWa3fSevwVpey2kY/openapi.json
