# Twitter/X Search Scraper · Small Jobs & Advanced Queries (`data-slayer/twitter-search`) Actor

Search public Twitter/X posts and profiles by keyword, hashtag, mention, or documented advanced operator. Export unique results with bounded pagination, clear empty and partial outcomes, and no login or cookies.

- **URL**: https://apify.com/data-slayer/twitter-search.md
- **Developed by:** [Data Slayer](https://apify.com/data-slayer) (community)
- **Categories:** Social media, Automation, Lead generation
- **Features:** Limited permissions
- **Stats:** 630 total users, 82 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.50 / 1,000 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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Twitter/X Search Scraper · Small Jobs & Advanced Queries

Search public Twitter/X results by keyword, phrase, hashtag, mention, or documented advanced operator. Export unique posts or profiles with bounded pagination and clear empty or partial outcomes—without providing a Twitter/X login or cookies.

### Watch the demo

[![Watch the Twitter/X Search Scraper demo](https://img.youtube.com/vi/TPMUFKPdXiE/hqdefault.jpg)](https://www.youtube.com/watch?v=TPMUFKPdXiE)

### What this Actor does

Use this Actor for one-off research, small searches, repeatable automations, or larger bounded exports. It supports the existing **Top**, **Latest**, **People**, **Photos**, and **Videos** sections. Each run stops at your page or row limit, removes duplicate result IDs within the run, and stores a run summary separately from the billable Dataset.

Search availability and result volume vary by query, section, time, account visibility, and what Twitter/X exposes publicly. A successful empty search is reported honestly; it is not presented as complete historical coverage.

### Input

| Field | Type | Required | Default | Purpose |
| --- | --- | --- | --- | --- |
| `query` | string | Yes | `new york` | Keyword, phrase, hashtag, mention, or advanced query, up to 512 characters. |
| `section` | enum | No | `top` | One of `top`, `latest`, `people`, `photos`, or `videos`. |
| `maxPages` | integer | No | `1` | Maximum pages to request, from 1 to 100. The legacy key and default are preserved. |
| `maxItems` | integer | No | unset | Optional cap of 1–10,000 unique Dataset rows. |
| `fromUser` | string | No | unset | Convenience field that appends the documented `from:` operator. |
| `verifiedOnly` | boolean | No | `false` | Convenience field that appends the documented `filter:verified` operator. |

The convenience fields do not add undocumented filters. You can still place supported operators directly in `query`. If `query` already contains the same operator, the Actor does not append it again.

#### Example input

```json
{
  "query": "product launch",
  "section": "latest",
  "maxPages": 3,
  "maxItems": 100,
  "fromUser": "nasa",
  "verifiedOnly": true
}
```

The effective query is `product launch from:nasa filter:verified`.

### Output

The default Dataset contains one unique search result per row. Existing tweet/profile keys are preserved for compatibility. Fields vary by section and public availability; missing data may be absent or null.

Common tweet fields include:

- `tweet_id`, `text`, `created_at`, `lang`, and `conversation_id`
- `screen_name` and nested `user_info`
- `favorites`, `retweets`, `bookmarks`, `views`, `replies`, and `quotes`
- nested `entities` such as hashtags, mentions, and media

The **People** section may return profile-shaped rows instead of tweet-shaped rows. The schema therefore remains open to existing section-specific fields. Internal routing, authentication, quota, request, and raw-response metadata are removed from customer rows.

#### Example JSON row

```json
{
  "type": "tweet",
  "tweet_id": "1734567890123456789",
  "screen_name": "tech_innovator",
  "text": "A public product launch update #AI",
  "created_at": "Mon Dec 16 14:23:15 +0000 2025",
  "favorites": 2847,
  "retweets": 456,
  "bookmarks": 189,
  "views": "87432",
  "replies": 34,
  "quotes": 12,
  "conversation_id": "1734567890123456789",
  "lang": "en",
  "entities": {
    "hashtags": [{"text": "AI", "indices": [31, 34]}],
    "user_mentions": [],
    "media": []
  },
  "user_info": {
    "screen_name": "tech_innovator",
    "name": "Tech Innovator",
    "followers_count": 45678,
    "verified": true
  }
}
```

#### Example CSV columns

```csv
type,tweet_id,screen_name,text,created_at,favorites,retweets,views,lang
tweet,1734567890123456789,tech_innovator,A public product launch update #AI,Mon Dec 16 14:23:15 +0000 2025,2847,456,87432,en
```

Nested objects are represented according to Apify's Dataset CSV export behavior. JSON is the canonical format for nested data.

### Empty, partial, and failed runs

The Dataset contains customer results only—never status rows. The key-value store record named `OUTPUT` reports:

- `complete`: the Actor reached the end of available pages or a configured bound.
- `empty`: the request completed but returned no matching rows.
- `partial`: some rows were accepted before a later page, time, request, customer-budget, cancellation, or output boundary stopped the run.
- `failed`: no rows were accepted and the request could not complete.

The summary includes pages fetched, request attempts, accepted rows, observed automatic-charge receipts, duplicates skipped, termination reason, and expected billable Dataset rows. It distinguishes matched billing, customer-budget termination, and a reconciliation mismatch that needs review. Pagination tokens are represented only by a short fingerprint.

### Reliability and limits

- Transient rate limits, timeouts, and server errors use bounded retries with jitter and `Retry-After` when available.
- Pagination stops on the page limit, unique-row limit, request budget, time budget, missing cursor, or repeated cursor.
- Duplicate rows are removed by stable result ID within one run.
- A customer max-total-charge limit stops further Dataset delivery when the Apify SDK reports that the event budget is exhausted.
- An uncertain Dataset write is not retried automatically; the run stops to avoid duplicating a possibly accepted and charged row.
- Public, deleted, restricted, private, region-limited, or unavailable content may be missing.
- Search results—especially **Latest** and date-bounded queries—may be sparse. The Actor does not promise complete history or a fixed number of matches.
- This Actor is not affiliated with or endorsed by Twitter/X.

### Automation and export

Run the Actor in Apify Console, through the Apify API, on a schedule, or from a webhook-enabled workflow. Download the Dataset as JSON, CSV, or Excel. For repeated monitoring, set a narrow result bound and keep your own durable cross-run deduplication key based on the returned result ID.

### Pricing semantics

The primary billable event is one accepted row in the default Dataset. The small Actor-start event covers bounded retrieval work even when a query is sparse or empty. The `OUTPUT` summary is stored outside the Dataset and is not a result event.

### Other Twitter/X Actors by Data Slayer

- [Twitter Tweets Scraper](https://apify.com/data-slayer/twitter-user-tweets)
- [Twitter Comments Scraper](https://apify.com/data-slayer/twitter-comments)
- [Twitter Followers Scraper](https://apify.com/data-slayer/twitter-followers)
- [Twitter Following Scraper](https://apify.com/data-slayer/twitter-followings)
- [Twitter Profile Scraper](https://apify.com/data-slayer/twitter-user)
- [Twitter List Members Scraper](https://apify.com/data-slayer/twitter-list-members)
- [Twitter Community Members Scraper](https://apify.com/data-slayer/twitter-community-members)
- [Twitter Trends Scraper](https://apify.com/data-slayer/twitter-trends-by-location)

### Support

Create an issue in the Actor's **Issues** tab with the section, a redacted query example, and the `OUTPUT` termination reason. Do not include account credentials or private data.

### FAQ

**How much does it cost to run this Actor?**
Pricing is listed in the Pricing section above, charged per row returned. You only pay for the rows
the Actor actually produces, so a small test run costs cents.

**Do I need cookies or a login?**
No. This Actor reads public data only - no cookies, no account, no browser automation.

**Can I schedule it?**
Yes. Run it from the Apify API, on a schedule, or via a webhook, and export results as JSON, CSV or Excel.

**What if I need a slightly different output?**
Open an issue on the Actor's Issues tab describing the shape you need.

### Related actors

More Twitter actors from the same portfolio. Apify only auto-recommends actors in the same category, so here are the rest of ours:

| Actor |
|---|
| [Twitter/X Comments Scraper · No Cookies](https://apify.com/data-slayer/twitter-comments) |
| [Twitter/X Community Members Scraper · No Cookies](https://apify.com/data-slayer/twitter-community-members) |
| [Twitter/X Engaged Audience Exporter · Replies + Retweeters](https://apify.com/data-slayer/twitter-engaged-audience-exporter) |
| [Twitter/X Followers Scraper · No Cookies](https://apify.com/data-slayer/twitter-followers) |
| [Twitter/X Following Scraper · Public Profiles](https://apify.com/data-slayer/twitter-followings) |
| [Twitter/X List Members Scraper · No Cookies](https://apify.com/data-slayer/twitter-list-members) |
| [Twitter/X Profile Scraper · Bulk Handles, URLs & IDs](https://apify.com/data-slayer/twitter-user) |
| [Twitter/X Trends Scraper · No Cookies](https://apify.com/data-slayer/twitter-trends-by-location) |
| [Twitter/X Tweet Details Scraper · URL or ID](https://apify.com/data-slayer/twitter-tweet-details) |
| [Twitter/X Tweets Scraper · No Cookies](https://apify.com/data-slayer/twitter-user-tweets) |

# Actor input Schema

## `query` (type: `string`):

Keyword, phrase, hashtag, mention, or advanced query. Example: #AI or mission update from:nasa.

## `section` (type: `string`):

Choose the Twitter/X search section. The default preserves the existing Top mode.

## `maxPages` (type: `integer`):

Maximum pages to request. The legacy default remains one page.

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

Stop after this many unique rows. Leave empty to use only the page limit.

## `fromUser` (type: `string`):

Adds the documented from: operator. Enter a handle with or without @.

## `verifiedOnly` (type: `boolean`):

Adds the documented filter:verified operator.

## Actor input object example

```json
{
  "query": "new york",
  "section": "top",
  "maxPages": 1,
  "verifiedOnly": false
}
```

# Actor output Schema

## `results` (type: `string`):

One dataset item per unique public search result. Existing tweet/profile keys are preserved; fields may be null or absent by section and public availability.

## `runSummary` (type: `string`):

Status, termination reason, pages fetched, accepted rows, duplicates skipped, and observed automatic-charge reconciliation.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("data-slayer/twitter-search").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("data-slayer/twitter-search").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 '{}' |
apify call data-slayer/twitter-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,data-slayer/twitter-search"
        }
    }
}
```

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/otNcBrfxlRjT9FGqf/builds/qrAvVVJtkuqYi95Ol/openapi.json
