# Scweet Twitter/X Scraper (`altimis/scweet`) Actor

Scrape Twitter (X) tweets from search + profiles. Filter keywords/hashtags/users/dates. Export JSON/CSV/XLSX. Fast. $0.30/1k. Free plan.

- **URL**: https://apify.com/altimis/scweet.md
- **Developed by:** [JEB](https://apify.com/altimis) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 1,867 total users, 184 monthly users, 95.6% runs succeeded, 28 bookmarks
- **User rating**: 4.79 out of 5 stars

## Pricing

from $0.25 / 1,000 tweets

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/platform/actors/running/actors-in-store#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

## Scweet — Twitter/X Scraper

Extract tweets from search results and profile timelines into JSON, CSV, and XLSX. No API key, no cookies, no account setup — just configure your query and Scweet handles the rest.

[Run on Apify](https://console.apify.com/actors/EvFXOhwR6wsOWmdSK?addFromActorId=EvFXOhwR6wsOWmdSK) | [Open-Source Library](https://github.com/Altimis/scweet)

***

### What Scweet Does

- **Search and profile scraping** — query X/Twitter by keywords, hashtags, users, engagement, date range, location, and more, or scrape profile timelines. Run both in a single job.
- **Zero configuration** — no cookies, no proxies, nothing to manage. Just set your query and Scweet handles the rest.
- **Deduplicated billing** — you only pay for unique tweets. Every item is deduplicated before it reaches your dataset.
- **Production-grade reliability** — automatic retries, adaptive rate limiting, and built-in resilience keep runs stable at scale.

#### Use cases

Brand monitoring, lead generation, market research, academic datasets, OSINT, content strategy.

#### Pricing

| Plan | Per 1,000 tweets | Run-start fee |
|---|---:|---:|
| Free | $3.00 | $0.006 |
| Starter | $0.30 | $0.0006 |
| Scale | $0.28 | $0.0006 |
| Business | $0.25 | $0.0006 |

Apify provides monthly free platform credit (commonly $5/month). You only pay for unique, deduplicated tweets.

> Free tier is for evaluation, not production. Higher free pricing reduces abuse and keeps paid tiers low.

***

### Quick Start

1. Open [Scweet on Apify](https://console.apify.com/actors/EvFXOhwR6wsOWmdSK?addFromActorId=EvFXOhwR6wsOWmdSK).
2. Paste one of the inputs below.
3. Run the Actor.
4. Export your dataset (JSON, CSV, or XLSX).

#### Search

```json
{
  "source_mode": "search",
  "search_query": "bitcoin lang:en from:elonmusk -filter:replies min_faves:100",
  "since": "2025-02-17",
  "until": "2026-02-19",
  "max_items": 1000
}
```

#### Profile timeline

```json
{
  "source_mode": "profiles",
  "profile_urls": [
    "https://x.com/elonmusk",
    "@apify"
  ],
  "max_items": 1000
}
```

#### Combined (search + profiles)

```json
{
  "source_mode": "auto",
  "all_words": ["ai", "agent"],
  "since": "2025-02-17",
  "profile_urls": ["https://x.com/apify"],
  "search_sort": "Top",
  "max_items": 500
}
```

> Input can be partial — omitted fields use defaults. The Apify Console opens with sample prefill values (`search_query="from:elonmusk"`, `profile_urls=["@elonmusk"]`). Replace or remove them before running your own job.

***

### Input Reference

#### Source modes

| Mode | Behavior |
|---|---|
| `auto` (default) | Runs whichever paths have input. If both search and profile inputs are present, both run. |
| `search` | Search path only. Profile input is ignored. |
| `profiles` | Profile timeline path only. Search input is ignored. |

#### Core fields

| Field | Type | Description |
|---|---|---|
| `source_mode` | string | `auto`, `search`, or `profiles` (default: `auto`) |
| `search_query` | string | Raw advanced query string. [Operator reference](https://github.com/igorbrigadir/twitter-advanced-search) |
| `profile_urls` | array | Handles or profile URLs (`@handle`, `x.com/<handle>`, `twitter.com/<handle>`) |
| `max_items` | integer | Global tweet target per run (default: `1000`) |
| `since` | string | Start date or UTC timestamp |
| `until` | string | End date or UTC timestamp |
| `search_sort` | string | `Top` or `Latest` (default: `Top`) |

#### Search builder fields

Instead of writing a raw `search_query`, you can use structured fields that Scweet combines into a query automatically:

| Category | Fields |
|---|---|
| Keywords | `all_words`, `any_words`, `exact_phrases`, `exclude_words` |
| Users | `from_users`, `to_users`, `mentioning_users` |
| Hashtags | `hashtags_any`, `hashtags_exclude` |
| Language | `lang` (e.g. `en`, `fr`, `ar`) |
| Tweet type | `tweet_type`: `all`, `originals_only`, `replies_only`, `retweets_only`, `exclude_replies`, `exclude_retweets` |
| Filters | `verified_only`, `blue_verified_only`, `has_images`, `has_videos`, `has_links`, `has_mentions`, `has_hashtags` |
| Engagement | `min_likes`, `min_replies`, `min_retweets` |
| Location | `place`, `geocode` (`lat,lon,radius`), `near`, `within` |

#### Defaults and limits

- `max_items` is global per run, not per profile.
- Minimum run size: if `max_items < 100`, it is auto-adjusted to `100`.
- Unknown input keys are rejected.
- If both `since` and `until` are missing, lookback defaults to 4 years (`Top`) or 180 days (`Latest`).
- Location filters depend on X/Twitter metadata and can be approximate.
- Free plan guardrails: `1000` tweets/day, `10` runs/day, minimum `60s` between runs.

***

### Output

Results are stored in the Apify dataset, deduplicated by tweet ID. Export as JSON, CSV, or XLSX.

#### Fields

| Field | Description |
|---|---|
| `id` | Tweet ID |
| `text` | Tweet text |
| `handle` | Author handle |
| `tweet_url` | Direct link to tweet |
| `favorite_count`, `retweet_count`, `reply_count`, `quote_count`, `bookmark_count`, `view_count` | Engagement metrics |
| `created_at` | Tweet creation time |
| `collected_at_utc` | Collection timestamp (UTC) |
| `lang` | Language |
| `conversation_id` | Thread/conversation ID |
| `in_reply_to_status_id`, `in_reply_to_user_id`, `in_reply_to_screen_name` | Reply references |
| `quoted_status_id` | Quoted tweet ID |
| `is_quote`, `is_reply` | Convenience flags |
| `source_root` | `search` or `profile_url` |
| `source_value` | Effective query or normalized profile URL |
| `user` | Nested author object (handle, name, followers, bio, etc.) |
| `tweet` | Nested tweet details (media, entities, edit history, etc.) |

#### Example (top-level fields)

```json
{
  "id": "1996300676012376299",
  "handle": "FTB_Team",
  "text": "We dug through the first month of StoneBlock 4...",
  "favorite_count": 71,
  "retweet_count": 5,
  "reply_count": 10,
  "view_count": "9695",
  "tweet_url": "https://x.com/FTB_Team/status/1996300676012376299",
  "created_at": "Wed Dec 03 19:29:05 +0000 2025",
  "collected_at_utc": "2026-04-07T15:58:33.539740+00:00",
  "lang": "en",
  "source_root": "search",
  "source_value": "(sample OR query) lang:en",
  "is_quote": false,
  "is_reply": false,
  "user": { "handle": "FTB_Team", "name": "Feed The Beast", "followers_count": 43367, "..." : "..." },
  "tweet": { "media": ["..."], "entities": { "..." : "..." }, "..." : "..." }
}
```

***

### Tips

- **Use `Top` sort (default).** `Top` consistently returns more tweets than `Latest` for the same query and time range. `Latest` is useful when you need strict reverse-chronological order, but tends to return fewer total results because X's search index is less exhaustive in that mode.
- **Use wider time ranges.** The wider the `since`/`until` window, the more tweets X will surface. Scweet automatically splits wide ranges into parallel sub-intervals, so a large window does not slow down the run.
- **Start broad, then narrow.** If you get fewer tweets than expected, try removing restrictive filters (`min_likes`, `tweet_type`, `lang`) one at a time to see which one is limiting results.
- **For large volumes from a single profile, use `search` instead of `profile` mode.** Profile mode (`source_mode=profiles`) is best for recent activity. For thousands of tweets from a specific user, use `source_mode=search` with `from_users: ["handle"]` (or `search_query: "from:handle"`), a wide `since`/`until` range, and `search_sort: "Latest"` for more complete results.
- **Date filters are handled internally.** Scweet converts `since` and `until` to precise Unix-timestamp operators under the hood. You can keep using human-readable dates (e.g. `"since": "2025-01-01"`).
- **Combine structured fields with `search_query`.** You can use `search_query` for advanced operators not covered by the builder fields (e.g. `filter:media`, `-filter:replies`) and add structured fields like `from_users` or `min_likes` on top — Scweet merges them into a single query.

***

### How It Works

Scweet uses X's internal GraphQL API — the same endpoints the X website uses. No official Twitter API key or developer account is needed.

You configure a query and a target. Scweet handles everything else — authentication, proxies, pacing, retries, and deduplication. If something fails mid-run, work is automatically retried so you get complete results without manual intervention.

***

### FAQ

**Do I need a Twitter API key?**
No. Scweet uses X's internal GraphQL API — no developer account or API key required.

**Do I need to provide cookies or an account?**
No. Account management, proxies, and rate limiting are all handled automatically.

**Can I scrape private accounts?**
No. Only publicly visible content is accessible.

**What export formats are supported?**
JSON, CSV, and XLSX — download directly from the Apify dataset tab.

**Is there a free tier?**
Yes — Apify provides monthly free platform credit. The actor's free plan allows up to 1,000 tweets/day and 10 runs/day.

**Power users:** the full open-source Python library is at [github.com/Altimis/Scweet](https://github.com/Altimis/Scweet) — `pip install Scweet` for programmatic access, async support, resume, and full control over accounts and proxies.

***

### Support

For help with query tuning, limits, or workflow design, contact us on the [Actor page](https://console.apify.com/actors/EvFXOhwR6wsOWmdSK) or open an issue in the [open-source repository](https://github.com/Altimis/scweet).

**Responsible usage:** Use this Actor lawfully and ethically. Comply with applicable platform terms and local regulations. Scweet applies adaptive rate limiting — repeatedly running queries that return zero results will trigger progressively longer cooldowns.

**Privacy:** Run metadata (user ID, timestamps, input payload, counters) may be stored for rate limiting, support, and stability. This data is used internally and is not shared with third parties.

# Actor input Schema

## `source_mode` (type: `string`):

Choose the data path. In Auto, both paths run when both search input and profile URLs are provided.

## `search_query` (type: `string`):

Search path input. Raw advanced query string. Ignored in Profiles mode.

## `profile_urls` (type: `array`):

Profile path only. Supports @handle, handle, x.com/handle, twitter.com/handle, and full profile URLs. Ignored in Search mode.

## `max_items` (type: `integer`):

Global cap for the run.

## `since` (type: `string`):

Date or timestamp. Date-only values are normalized to 00:00:00 UTC. If missing, defaults are computed automatically.

## `until` (type: `string`):

Date or timestamp. Date-only values are normalized to 23:59:59 UTC. If missing, defaults are computed automatically.

## `search_sort` (type: `string`):

Search product mode.

## `lang` (type: `string`):

Language code filter.

## `all_words` (type: `array`):

Every listed term must appear.

## `any_words` (type: `array`):

At least one listed term must appear.

## `exact_phrases` (type: `array`):

Exact phrases to include.

## `exclude_words` (type: `array`):

Terms to exclude.

## `hashtags_any` (type: `array`):

Include tweets containing any listed hashtag.

## `hashtags_exclude` (type: `array`):

Exclude tweets containing these hashtags.

## `from_users` (type: `array`):

Search tweets authored by these users.

## `to_users` (type: `array`):

Search tweets replying to or directed at these users.

## `mentioning_users` (type: `array`):

Search tweets mentioning these users.

## `tweet_type` (type: `string`):

Maps to filter:/-filter: operators.

## `verified_only` (type: `boolean`):

Only verified users.

## `blue_verified_only` (type: `boolean`):

Only blue-verified users.

## `has_images` (type: `boolean`):

Must contain images.

## `has_videos` (type: `boolean`):

Must contain videos.

## `has_links` (type: `boolean`):

Must contain links.

## `has_mentions` (type: `boolean`):

Must contain mentions.

## `has_hashtags` (type: `boolean`):

Must contain hashtags.

## `min_likes` (type: `integer`):

Minimum likes threshold.

## `min_replies` (type: `integer`):

Minimum replies threshold.

## `min_retweets` (type: `integer`):

Minimum retweets threshold.

## `place` (type: `string`):

Place operator value.

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

Format: lat,lon,radius (for example: 39.8283,-98.5795,2500km).

## `near` (type: `string`):

City or location text.

## `within` (type: `string`):

Radius used with near (for example: 10km).

## Actor input object example

```json
{
  "source_mode": "auto",
  "search_query": "from:elonmusk",
  "profile_urls": [
    "@elonmusk"
  ],
  "max_items": 1000,
  "since": "",
  "until": "",
  "search_sort": "Top",
  "lang": "",
  "all_words": [],
  "any_words": [],
  "exact_phrases": [],
  "exclude_words": [],
  "hashtags_any": [],
  "hashtags_exclude": [],
  "from_users": [],
  "to_users": [],
  "mentioning_users": [],
  "tweet_type": "all",
  "verified_only": false,
  "blue_verified_only": false,
  "has_images": false,
  "has_videos": false,
  "has_links": false,
  "has_mentions": false,
  "has_hashtags": false,
  "min_likes": 0,
  "min_replies": 0,
  "min_retweets": 0,
  "place": "",
  "geocode": "",
  "near": "",
  "within": ""
}
```

# Actor output Schema

## `tweets` (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 = {
    "source_mode": "auto",
    "search_query": "from:elonmusk",
    "profile_urls": [
        "@elonmusk"
    ],
    "max_items": 1000,
    "since": "",
    "until": "",
    "search_sort": "Top",
    "lang": "",
    "all_words": [],
    "any_words": [],
    "exact_phrases": [],
    "exclude_words": [],
    "hashtags_any": [],
    "hashtags_exclude": [],
    "from_users": [],
    "to_users": [],
    "mentioning_users": [],
    "tweet_type": "all",
    "verified_only": false,
    "blue_verified_only": false,
    "has_images": false,
    "has_videos": false,
    "has_links": false,
    "has_mentions": false,
    "has_hashtags": false,
    "min_likes": 0,
    "min_replies": 0,
    "min_retweets": 0,
    "place": "",
    "geocode": "",
    "near": "",
    "within": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("altimis/scweet").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 = {
    "source_mode": "auto",
    "search_query": "from:elonmusk",
    "profile_urls": ["@elonmusk"],
    "max_items": 1000,
    "since": "",
    "until": "",
    "search_sort": "Top",
    "lang": "",
    "all_words": [],
    "any_words": [],
    "exact_phrases": [],
    "exclude_words": [],
    "hashtags_any": [],
    "hashtags_exclude": [],
    "from_users": [],
    "to_users": [],
    "mentioning_users": [],
    "tweet_type": "all",
    "verified_only": False,
    "blue_verified_only": False,
    "has_images": False,
    "has_videos": False,
    "has_links": False,
    "has_mentions": False,
    "has_hashtags": False,
    "min_likes": 0,
    "min_replies": 0,
    "min_retweets": 0,
    "place": "",
    "geocode": "",
    "near": "",
    "within": "",
}

# Run the Actor and wait for it to finish
run = client.actor("altimis/scweet").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "source_mode": "auto",
  "search_query": "from:elonmusk",
  "profile_urls": [
    "@elonmusk"
  ],
  "max_items": 1000,
  "since": "",
  "until": "",
  "search_sort": "Top",
  "lang": "",
  "all_words": [],
  "any_words": [],
  "exact_phrases": [],
  "exclude_words": [],
  "hashtags_any": [],
  "hashtags_exclude": [],
  "from_users": [],
  "to_users": [],
  "mentioning_users": [],
  "tweet_type": "all",
  "verified_only": false,
  "blue_verified_only": false,
  "has_images": false,
  "has_videos": false,
  "has_links": false,
  "has_mentions": false,
  "has_hashtags": false,
  "min_likes": 0,
  "min_replies": 0,
  "min_retweets": 0,
  "place": "",
  "geocode": "",
  "near": "",
  "within": ""
}' |
apify call altimis/scweet --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=altimis/scweet",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/EvFXOhwR6wsOWmdSK/builds/aszxDRrX78ZlrTFLS/openapi.json
