# X-Cavator (`knowten/x-cavator`) Actor

The fastest X.com  (twitter) scraper at $0.30/1k tweets — with built-in AI Sentiment Analysis (0.0 to 1.0 scale). 600+ tweets/min, zero browser overhead, advanced filters included.

- **URL**: https://apify.com/knowten/x-cavator.md
- **Developed by:** [Knowten](https://apify.com/knowten) (community)
- **Categories:** Social media, Integrations, Developer tools
- **Features:** Limited permissions, Single-tenant, Server interface
- **Stats:** 87 total users, 6 monthly users, 100.0% runs succeeded, 20 bookmarks
- **User rating**: 4.98 out of 5 stars

## Pricing

from $0.30 / 1,000 standard tweets

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

<div align="center">
  ![X-Cavator Banner](./assets/titan_v2_banner.png)
</div>

<div align="center">
  <img src="https://img.shields.io/badge/Speed-600%2B_tweets%2Fmin-success?style=for-the-badge&logo=fastapi" />
  <img src="https://img.shields.io/badge/Stealth-Advanced_Reliability-blue?style=for-the-badge&logo=shield" />
  <img src="https://img.shields.io/badge/AI_Sentiment-Score_0.00_to_1.00-orange?style=for-the-badge&logo=google-gemini" />
  <img src="https://img.shields.io/badge/Price-From_%240.30%2F1k_tweets-purple?style=for-the-badge&logo=cash-app" />
  <br/><br/>
  <b>High-speed X.com extraction with built-in AI sentiment scoring.</b>
</div>

***

### TL;DR

**X-Cavator** scrapes X.com at 600+ tweets per minute. It can optionally enrich each tweet with a decimal **AI Sentiment Score** from **0.00 to 1.00**, where **0.50** means objective or neutral.

Quick start:

```json
{
  "searchTerms": ["from:NASA"],
  "sort": "Latest",
  "maxItems": 1000
}
```

***

### AI Sentiment Score

When Premium AI is enabled, each tweet gets a decimal `sentimentScore`.

| Score | Meaning |
|:---:|:---|
| `1.00` | Extremely positive |
| `0.75` | Positive |
| `0.50` | Neutral / objective |
| `0.25` | Negative |
| `0.00` | Extremely negative |

Implementation notes:

- Shorter sentence-level analysis improves precision.
- Objective content stays at `0.50`.
- Mixed tweets are aggregated from sentence scores.
- The prompt is kept compact to reduce token usage.

Example output:

```json
{
  "type": "tweet",
  "id": "1728108619189874825",
  "text": "This product completely changed my workflow, absolutely love it!",
  "sentimentScore": 0.91,
  "likeCount": 8400,
  "retweetCount": 1230,
  "lang": "en",
  "author": {
    "userName": "techreviewer",
    "followers": 58200,
    "isBlueVerified": true
  }
}
```

***

### Query Builder

You can pass full raw queries directly:

```text
artemis (from:NASA OR from:SpaceX OR from:elonmusk)
```

Or build the same search with structured input:

```json
{
  "searchTerms": ["artemis"],
  "tweetAuthors": ["NASA", "SpaceX", "elonmusk"],
  "sort": "Latest",
  "maxItems": 200
}
```

`twitterHandles` still scrapes profile timelines directly. `tweetAuthors` is for filtering search queries across multiple authors.

***

### Input Parameters

| Field | Type | Description | Default |
|:---|:---|:---|:---|
| `searchTerms` | `array` | Keywords, hashtags, or full advanced search queries | `[]` |
| `extractPerTerm` | `boolean` | Iterates over each search term, retrieving up to `maxTweetsPerTerm` tweets for that term | `false` |
| `maxTweetsPerTerm` | `number` | Maximum tweets per term when `extractPerTerm` is `true` | `100` |
| `twitterHandles` | `array` | Profiles to scrape directly; if there are multiple handles, the quota is split evenly between them | `[]` |
| `maxItems` | `number` | Max tweets to extract across all queries and profiles; for multiple `twitterHandles`, this total is divided evenly | `100` |
| `sort` | `string` | `Latest` or `Top` | `Latest` |
| `tweetLanguage` | `string` | ISO 639-1 language code | `all` |
| `startDate` | `string` | Only get tweets after this date | `null` |
| `endDate` | `string` | Only get tweets before this date | `null` |
| `onlyVerifiedUsers` | `boolean` | Restrict to verified accounts | `false` |
| `onlyTwitterBlue` | `boolean` | Restrict to Twitter Blue accounts | `false` |
| `onlyImage` | `boolean` | Only tweets with images | `false` |
| `onlyVideo` | `boolean` | Only tweets with video | `false` |
| `onlyQuote` | `boolean` | Only quote tweets | `false` |
| `tweetAuthor` | `string` | Filter by one author handle; comma-separated handles are also accepted | `null` |
| `tweetAuthors` | `array` | Filter search results to multiple author handles joined with `OR` | `[]` |
| `mentioning` | `string` | Only tweets mentioning this handle | `null` |
| `inReplyTo` | `string` | Only replies to this handle | `null` |
| `minimumFavorites` | `number` | Min likes threshold | `null` |
| `minimumRetweets` | `number` | Min retweets threshold | `null` |
| `minimumReplies` | `number` | Min replies threshold | `null` |
| `geotaggedNear` | `string` | Location name | `null` |
| `withinRadius` | `string` | Radius for `geotaggedNear` | `null` |
| `geocode` | `string` | Strict geo via `lat,long,radius` | `null` |
| `enablePremiumAi` | `boolean` | Add decimal AI sentiment scoring per tweet | `false` |

***

### Usage Examples

Scrape a profile:

```json
{ "twitterHandles": ["NASA"], "maxItems": 500 }
```

Scrape multiple profiles with an even split:

```json
{ "twitterHandles": ["NASA", "elonmusk", "SpaceX"], "maxItems": 100 }
```

This runs as `34 + 33 + 33`.

Search with date range:

```json
{
  "searchTerms": ["artificial intelligence since:2024-01-01 until:2024-12-31"],
  "sort": "Top",
  "maxItems": 2000
}
```

Brand sentiment monitoring:

```json
{
  "searchTerms": ["Tesla", "@Tesla"],
  "sort": "Latest",
  "maxItems": 5000,
  "enablePremiumAi": true
}
```

Search a topic across multiple authors:

```json
{
  "searchTerms": ["artemis"],
  "tweetAuthors": ["NASA", "SpaceX", "elonmusk"],
  "sort": "Latest",
  "maxItems": 200
}
```

***

### Output Schema

```json
{
  "type": "tweet",
  "id": "1728108619189874825",
  "url": "https://x.com/elonmusk/status/1728108619189874825",
  "text": "More than 10 per human on average",
  "sentimentScore": 0.34,
  "likeCount": 104121,
  "retweetCount": 11311,
  "replyCount": 6526,
  "quoteCount": 2915,
  "bookmarkCount": 702,
  "lang": "en",
  "createdAt": "Fri Nov 24 17:49:36 +0000 2023",
  "isReply": false,
  "isRetweet": false,
  "isQuote": true,
  "author": {
    "userName": "elonmusk",
    "name": "Elon Musk",
    "followers": 172669889,
    "isVerified": true,
    "isBlueVerified": true,
    "profilePicture": "https://pbs.twimg.com/profile_images/..."
  }
}
```

`sentimentScore` is only present when Premium AI is enabled. `0.50` means objective or neutral.

***

### Troubleshooting

| Problem | Solution |
|:---|:---|
| Getting 0 results | Check if your query is too restrictive. Test it on `twitter.com/search` first. |
| Fewer results than expected | Try `Top` instead of `Latest`. Some periods have lower search coverage. |
| AI not running | Make sure `enablePremiumAi` is `true`. |
| Missing tweets | X may suppress or limit some content. Try a different date range or sort mode. |

***

### Ethical Use

X-Cavator extracts publicly available data only. Users are responsible for complying with applicable privacy and data protection rules when handling results.

# Actor input Schema

## `searchTerms` (type: `array`):

Enter keywords, hashtags, or full advanced search queries. Supports Twitter/X advanced search syntax.

## `extractPerTerm` (type: `boolean`):

If enabled, iterates over each search term individually rather than combining them.

## `maxTweetsPerTerm` (type: `integer`):

Maximum number of tweets to extract for each search term when Extract Per Term is enabled.

## `twitterHandles` (type: `array`):

Extract directly from specific handles. No @ required. When multiple handles are provided, maxItems is split evenly across them.

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

Total number of tweets to extract. For multiple twitterHandles, this total is split evenly across the handles.

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

Choose between real-time data or most popular results.

## `tweetLanguage` (type: `string`):

Restrict results to a specific language.

## `onlyVerifiedUsers` (type: `boolean`):

If enabled, only tweets from verified accounts will be returned.

## `onlyImage` (type: `boolean`):

Filter results to only include tweets with images.

## `onlyVideo` (type: `boolean`):

Filter results to only include tweets with videos.

## `minimumFavorites` (type: `integer`):

Minimum number of likes for a tweet to be included.

## `minimumRetweets` (type: `integer`):

Minimum number of retweets for a tweet to be included.

## `startDate` (type: `string`):

Extract tweets posted after this date.

## `endDate` (type: `string`):

Extract tweets posted before this date.

## `onlyTwitterBlue` (type: `boolean`):

Filter results to only include tweets from Twitter Blue subscribers.

## `onlyQuote` (type: `boolean`):

Filter results to only include quote tweets.

## `tweetAuthor` (type: `string`):

Only get tweets from this specific user. You can also pass comma-separated handles.

## `tweetAuthors` (type: `array`):

Limit search results to multiple author handles. Queries are combined as (from:a OR from:b OR from:c).

## `inReplyTo` (type: `string`):

Only get tweets that are sent in reply to this user.

## `mentioning` (type: `string`):

Only get tweets mentioning this user.

## `minimumReplies` (type: `integer`):

Minimum number of replies for a tweet to be included.

## `geotaggedNear` (type: `string`):

Get tweets near this location (for example, New York, NY).

## `withinRadius` (type: `string`):

Radius for Geotagged Near (for example, 15mi or 20km).

## `geocode` (type: `string`):

Strict location via lat,long,radius (for example, 37.781157,-122.398720,1mi).

## `placeObjectId` (type: `string`):

Twitter place ID (for example, df51dec6f4ee2b2c for Washington DC).

## `enablePremiumAi` (type: `boolean`):

Adds a decimal sentiment score from 0.00 to 1.00 for each tweet, where 0.50 is objective or neutral.

## Actor input object example

```json
{
  "searchTerms": [
    "artificial intelligence"
  ],
  "extractPerTerm": false,
  "maxTweetsPerTerm": 100,
  "maxItems": 100,
  "sort": "Latest",
  "tweetLanguage": "all",
  "onlyVerifiedUsers": false,
  "onlyImage": false,
  "onlyVideo": false,
  "onlyTwitterBlue": false,
  "onlyQuote": false,
  "enablePremiumAi": false
}
```

# Actor output Schema

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

The main collection of extracted tweets with engagement metrics and AI sentiment scores.

# 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 = {
    "searchTerms": [
        "artificial intelligence"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("knowten/x-cavator").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 = { "searchTerms": ["artificial intelligence"] }

# Run the Actor and wait for it to finish
run = client.actor("knowten/x-cavator").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 '{
  "searchTerms": [
    "artificial intelligence"
  ]
}' |
apify call knowten/x-cavator --silent --output-dataset

```

## MCP server setup

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

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/A1EbjwxGaCHAUabKX/builds/vVpJhFEkBw1sroFN2/openapi.json
