# $0.375/1000 Twitter / X API Flat & Simple (`practicaltools/cheap-simple-twitter-api`) Actor

A robust, pay-per-event Apify actor, providing simplified, flattened, noise-free tweet and user objects. Designed for easy integration, strict field filtering, and reliable automation.

- **URL**: https://apify.com/practicaltools/cheap-simple-twitter-api.md
- **Developed by:** [Practical Tools](https://apify.com/practicaltools) (community)
- **Categories:** Developer tools, Social media, Automation
- **Stats:** 206 total users, 9 monthly users, 100.0% runs succeeded, 8 bookmarks
- **User rating**: 4.98 out of 5 stars

## Pricing

from $0.38 / 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

## Cheap & Simple Twitter / X.com API – Apify Actor

A robust, dirt-cheap, affordable, pay-per-use Apify actor that wraps the raw Twitter API endpoints, providing simplified, noise-free tweet and user objects. Designed for easy integration, strict field filtering, and reliable automation.

***

### 🚀 Features

- **Pay-per-result monetization**: Only pay for successful, non-empty results. As low as *$0.000375* per result.
- **Comprehensive endpoint support** (see below)
- **Unified Twitter API access** via Apify
- **Strict field filtering** for tweet and user objects (no noise)
- **Production-ready error handling**
- **Pagination support** via `cursor` parameter for all list endpoints
- **Advanced search supports `queryType` (Latest/Top)**

***

### Getting Started Guide

I've created a detailed Getting Started Guide, available in [Markdown](https://drive.google.com/file/d/1kiba665EDGhb8YTkxjF7A-JlTEIzaWNw/view?usp=sharing) or a [PDF](https://drive.google.com/file/d/1ZWUZhcbfeY5pKXfKorh9gWGl5XRAC-oB/view?usp=sharing) file

### Complex Advanced Search Query Builder

This little tool will help you create complex API search queries:
👉 [Twitter search builder](https://www.practical.tools/twitter-search-builder)

### 💸 Pricing (Tiered Discounts)

This actor uses Apify's tiered pricing model. The more you use Apify, the less you pay per result.

| Your Apify Plan | Price per Result | Total for 1,000 Items | Savings |
|-----------------|------------------|-----------------------|---------|
| **Free** | **$0.02** | $20.00 | - |
| **Starter** | **$0.000575** | $0.575 | **97.1% Off** |
| **Scale** | **$0.000475** | $0.475 | **97.6% Off** |
| **Business** | **$0.000375** | $0.375 | **98.1% Off** |

> \[!TIP]
> **Pro Tip:** Upgrading to even the smallest Apify paid plan (Starter) reduces your costs by over 97% instantly.

- **Trial Quota**: Users on the Apify Free plan are strictly limited to a trial quota of **20 results** per run. Upgrade to any paid plan for unlimited results.
- **Platform usage is included** — you are charged per result only, with no separate compute costs on top.

***

### 🛠️ How to Use

#### 1. **Via Apify UI**

- Go to the actor page and click "Run".
- Fill in the input fields:
  - `endpoint`: (string) The endpoint to call (see list below)
  - `parameters`: (object) Parameters for the endpoint (see below)

#### 2. **Via Apify API**

Send a POST request to the actor with a JSON body:

```json
{
  "endpoint": "user/info",
  "parameters": { "userName": "NASA" }
}
```

***

### 📥 Input Schema

```json
{
  "endpoint": "string (required)",
  "parameters": "object (required)"
}
```

***

### 📤 Output Schema

- **User object:**
  ```json
  {
    "type": "user",
    "userName": "string",
    "url": "string",
    "id": "string",
    "name": "string",
    "isBlueVerified": true,
    "profilePicture": "string",
    "coverPicture": "string",
    "description": "string",
    "location": "string",
    "followers": 123,
    "following": 123
  }
  ```
- **Tweet object:**
  ```json
  {
    "type": "tweet",
    "id": "string",
    "url": "string",
    "text": "string",
    "source": "string",
    "retweetCount": 123,
    "replyCount": 123,
    "likeCount": 123,
    "quoteCount": 123,
    "viewCount": 123,
    "createdAt": "string",
    "lang": "string",
    "bookmarkCount": 123,
    "isReply": true,
    "media": "string",
    "video": {
      "duration_millis": 123,
      "variants": [
        {
          "bitrate": 123,
          "content_type": "string",
          "url": "string"
        }
      ]
    },
    "author": { ...user object... }
  }
  ```
- **Array:** Most endpoints return an array of user or tweet objects.

***

### 📚 Supported Endpoints & Usage

| Endpoint                | Description                                 | Parameters (required)         | Example Input |
|-------------------------|---------------------------------------------|-------------------------------|--------------|
| `user/info`             | Get user info by username                   | `userName` (string)           | `{ "endpoint": "user/info", "parameters": { "userName": "NASA" } }` |
| `user/last_tweets`      | Get latest tweets by user                   | `userName` (string), `cursor` (optional) | `{ "endpoint": "user/last_tweets", "parameters": { "userName": "NASA", "cursor": "NEXT_CURSOR" } }` |
| `user/followers`        | Get followers of a user                     | `userName` (string), `cursor` (optional) | `{ "endpoint": "user/followers", "parameters": { "userName": "NASA", "cursor": "NEXT_CURSOR" } }` |
| `user/followings`       | Get users followed by a user                | `userName` (string), `cursor` (optional) | `{ "endpoint": "user/followings", "parameters": { "userName": "NASA", "cursor": "NEXT_CURSOR" } }` |
| `user/mentions`         | Get tweets mentioning a user                | `userName` (string), `cursor` (optional) | `{ "endpoint": "user/mentions", "parameters": { "userName": "NASA", "cursor": "NEXT_CURSOR" } }` |
| `tweet/by_ids`          | Get tweets by IDs                           | `tweet_ids` (string, comma-separated) | `{ "endpoint": "tweet/by_ids", "parameters": { "tweet_ids": "1920130001699062027" } }` |
| `tweet/replies`         | Get replies to a tweet                      | `tweet_id` (string), `cursor` (optional) | `{ "endpoint": "tweet/replies", "parameters": { "tweet_id": "1920130001699062027", "cursor": "NEXT_CURSOR" } }` |
| `tweet/quotes`          | Get quotes of a tweet                       | `tweet_id` (string), `cursor` (optional) | `{ "endpoint": "tweet/quotes", "parameters": { "tweet_id": "1920130001699062027", "cursor": "NEXT_CURSOR" } }` |
| `tweet/retweeters`      | Get users who retweeted a tweet             | `tweetId` (string), `cursor` (optional) | `{ "endpoint": "tweet/retweeters", "parameters": { "tweetId": "1920130001699062027", "cursor": "NEXT_CURSOR" } }` |
| `tweet/advanced_search` | Advanced tweet search                       | `query` (string, required), `queryType` (enum: Latest, Top, required, default: Latest), `cursor` (optional) | `{ "endpoint": "tweet/advanced_search", "parameters": { "query": "from:NASA", "queryType": "Latest", "cursor": "NEXT_CURSOR" } }` |
| `list/tweets`           | Get tweets from a list                      | `listId` (string), `cursor` (optional) | `{ "endpoint": "list/tweets", "parameters": { "listId": "YOUR_LIST_ID", "cursor": "NEXT_CURSOR" } }` |

***

### 🧑‍💻 Example Usage

**Input JSON (Apify UI or API):**

```json
{
  "endpoint": "tweet/advanced_search",
  "parameters": { "query": "from:NASA", "queryType": "Latest", "cursor": "NEXT_CURSOR" }
}
```

**Sample Output:**

```json
{
  "type": "user",
  "userName": "NASA",
  "url": "https://twitter.com/NASA",
  "id": "123456789",
  "name": "Muzli",
  "isBlueVerified": true,
  "profilePicture": "https://...",
  "coverPicture": "https://...",
  "description": "Curated design inspiration",
  "location": "Internet",
  "followers": 100000,
  "following": 1
}
```

***

### ⚠️ Error Handling

If a call cannot be completed, the run **fails with a plain-language status message** explaining why — for example a rejected API key, a user or tweet that does not exist, or an upstream rate limit. No error object is written to the dataset, so anything you read from the dataset is always a valid result.

- **Transient failures** (rate limits, 5xx responses, network timeouts) are retried automatically up to 3 times with exponential backoff.
- **Permanent failures** (bad API key, missing user/tweet) fail fast without burning retries.
- **Partial results are kept.** If pagination fails midway, everything fetched up to that point stays in the dataset and the status message reports how many items were returned.

Check the run's status message, or the `Log` tab, to see the reason for a failure.

***

### 🙋 Support

- For questions or issues, use the Apify actor page "Issues" tab or contact the maintainer.

***

**Actor ID:** `gdN28kzr6QsU4nVh8`\
**Pricing:** Pay per result — $0.02 on the Apify Free plan, down to $0.000375 on Business. See the Pricing section above.

***

# Actor input Schema

## `endpoint` (type: `string`):

The endpoint to call (see README for options)

## `parameters` (type: `object`):

Parameters for the selected endpoint. Example values:

user/info: { "userName": "NASA" }
user/last_tweets: { "userName": "NASA", "cursor": "NEXT_CURSOR" }
user/followers: { "userName": "NASA", "cursor": "NEXT_CURSOR" }
user/followings: { "userName": "NASA", "cursor": "NEXT_CURSOR" }
user/mentions: { "userName": "NASA", "cursor": "NEXT_CURSOR" }
tweet/by_ids: { "tweet_ids": "1920130001699062027" }
tweet/replies: { "tweet_id": "1920130001699062027", "cursor": "NEXT_CURSOR" }
tweet/quotes: { "tweet_id": "1920130001699062027", "cursor": "NEXT_CURSOR" }
tweet/retweeters: { "tweetId": "1920130001699062027", "cursor": "NEXT_CURSOR" }
tweet/advanced_search: { "query": "from:NASA", "queryType": "Latest", "cursor": "NEXT_CURSOR" } // queryType: enum<string> (Latest, Top), default: Latest, required
list/tweets: { "listId": "YOUR_LIST_ID", "cursor": "NEXT_CURSOR" }

All endpoints that return a list accept an optional "cursor" parameter for pagination.

See README for full list.

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

Maximum number of items to return. Paginates automatically until the limit is reached. If not set, returns a single page (~20 items). Set to 0 for unlimited, which is capped at 50,000 items per run as a safety limit.

## Actor input object example

```json
{
  "endpoint": "user/info",
  "parameters": {
    "userName": "NASA"
  }
}
```

# 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 = {
    "parameters": {
        "userName": "NASA"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("practicaltools/cheap-simple-twitter-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 = { "parameters": { "userName": "NASA" } }

# Run the Actor and wait for it to finish
run = client.actor("practicaltools/cheap-simple-twitter-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 '{
  "parameters": {
    "userName": "NASA"
  }
}' |
apify call practicaltools/cheap-simple-twitter-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,practicaltools/cheap-simple-twitter-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/gdN28kzr6QsU4nVh8/builds/dCiFt3yCkudAgOTyw/openapi.json
