# Twitter Lists Scraper (`automation-lab/twitter-lists-scraper`) Actor

Extract public X/Twitter List metadata, members, and recent posts for recurring monitoring and research.

- **URL**: https://apify.com/automation-lab/twitter-lists-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Social media, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

## Twitter Lists Scraper

Extract public **Twitter Lists** metadata, members, and recent posts into structured datasets.
Use it to snapshot a curated audience, follow a topic-specific feed, or monitor changes with an Apify schedule.

The Actor accepts public `x.com/i/lists/...` URLs or numeric List IDs.
It returns canonical X URLs, member profiles, post timestamps, engagement counts, and media links without asking for an X login.

### What does Twitter Lists Scraper do?

For each public List, the Actor can collect three record types:

- `list` — List name, owner, description, banner, and canonical URL;
- `member` — username, name, bio, profile URL, avatar, verification, and protected-account signal;
- `post` — text, author, timestamp, canonical URL, engagement counts, and media URLs.

Choose one type or combine all three in a single run.
Every row includes `recordType`, `listId`, `listUrl`, and `scrapedAt`, so mixed exports remain easy to filter.

### Who is it for?

- **Market researchers** tracking voices in a curated sector.
- **Sales and partnerships teams** exporting public account lists for research.
- **Journalists and analysts** following topic or organization Lists.
- **Social media teams** comparing public membership and posting activity over time.
- **Developers** feeding normalized List records into data warehouses, agents, or dashboards.

This Actor works best when you already know the public List URL.
It does not search for Lists by keyword.

### Why use this Twitter Lists extractor?

X List pages are difficult to turn into repeatable tabular data.
This Actor provides:

- one input for metadata, members, and posts;
- stable canonical X URLs in every result;
- typed JSON suitable for CSV, Excel, and API integrations;
- strict `maxItems` control;
- pagination with duplicate suppression;
- explicit failure when public delivery routes are blocked, rather than a misleading successful empty dataset;
- direct HTTP extraction with no browser or residential proxy cost.

### What data can be extracted?

| Record | Important fields |
| --- | --- |
| List | `listId`, `listUrl`, `listName`, `ownerUsername`, `description`, `bannerUrl` |
| Member | `username`, `name`, `profileUrl`, `bio`, `avatarUrl`, `verified`, `protected` |
| Post | `postId`, `postUrl`, `text`, `createdAt`, `authorUsername`, `authorName`, engagement counts, `mediaUrls` |
| Every record | `recordType`, `listId`, `listUrl`, `listName`, `scrapedAt` |

Engagement fields are included only when visible on the public source.
Missing counts remain absent rather than being invented as zero.

### How to scrape a public X List

1. Open a public List on X.
2. Copy its URL, for example `https://x.com/i/lists/84839422`.
3. Add the URL under **X/Twitter List URLs or IDs**.
4. Select `list`, `members`, `posts`, or a combination.
5. Set **Maximum records**.
6. Click **Start**.
7. Open the dataset and export it as JSON, CSV, Excel, XML, or RSS.

The prefilled List is public and can be used for a first test.

### Input parameters

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `listUrls` | array | required | Public X List URLs or numeric List IDs. |
| `outputTypes` | array | all types | Any combination of `list`, `members`, and `posts`. |
| `maxItems` | integer | `100` | Maximum records across all Lists and selected types; range 1–5,000. |
| `requestDelayMs` | integer | `750` | Polite delay between public data requests; range 0–10,000 ms. |

When members and posts are both selected, the result budget is divided between them so both workflows produce useful rows.
List metadata uses at most one row per supplied List.

#### Example input

```json
{
  "listUrls": [
    { "url": "https://x.com/i/lists/84839422" }
  ],
  "outputTypes": ["list", "members", "posts"],
  "maxItems": 75,
  "requestDelayMs": 750
}
```

### Output example

A post record from the current implementation has this shape:

```json
{
  "recordType": "post",
  "listId": "84839422",
  "listUrl": "https://x.com/i/lists/84839422",
  "listName": "Official Twitter Accounts",
  "postId": "2083311751014354964",
  "postUrl": "https://x.com/Sports/status/2083311751014354964",
  "text": "Kate Bush will love this video",
  "createdAt": "2026-07-31T22:00:00.000Z",
  "authorUsername": "Sports",
  "authorName": "Sports",
  "authorProfileUrl": "https://x.com/Sports",
  "verified": true,
  "replyCount": 2,
  "likeCount": 21,
  "mediaUrls": [
    "https://pbs.twimg.com/amplify_video_thumb/example.jpg"
  ],
  "scrapedAt": "2026-08-01T03:20:02.114Z"
}
```

Public values change over time.
Treat this as a field example, not a guaranteed snapshot.

### How much does it cost to scrape Twitter Lists?

Pricing uses one `start` event per run and one `item` event for each saved List, member, or post record.
There is no separate charge for pagination requests or failed/duplicate rows.

The current item tiers decrease with usage:

| Tier | Price per saved record |
| --- | ---: |
| FREE | $0.0001840 |
| BRONZE | $0.0001600 |
| SILVER | $0.0001248 |
| GOLD | $0.0000960 |
| PLATINUM | $0.0000640 |
| DIAMOND | $0.0000448 |

A run also has a $0.005 start event.
At the BRONZE item rate, 25 records cost about $0.009 including start, 100 records about $0.021, and 1,000 records about $0.165.
Your active tier and maximum charge settings determine the exact billed amount.

### Monitoring Twitter List changes

Use Apify schedules to run the same input daily or hourly.
Keep `listId` plus `username` as the stable key for member snapshots.
Keep `postId` as the stable key for post snapshots.

A downstream workflow can then:

1. compare today's member usernames with yesterday's dataset;
2. identify added or removed public members;
3. filter posts by `createdAt`;
4. rank posts by `likeCount`, `repostCount`, or `replyCount`;
5. notify a Slack channel, webhook, or database only when something changed.

The Actor produces snapshots; it does not maintain historical state or send alerts itself.

### Integrations and exports

Apify can connect the dataset to:

- Google Sheets;
- Make;
- Zapier;
- Slack and webhooks;
- Amazon S3;
- Google Drive;
- PostgreSQL or another warehouse through the API.

Filter mixed rows by `recordType` before sending them to type-specific tables.
Canonical X URLs make it straightforward to join results with another public social-data workflow.

### Run through the Apify API

Replace `YOUR_TOKEN` with an Apify API token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~twitter-lists-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "listUrls": [{"url": "https://x.com/i/lists/84839422"}],
    "outputTypes": ["list", "posts"],
    "maxItems": 25
  }'
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/twitter-lists-scraper').call({
  listUrls: [{ url: 'https://x.com/i/lists/84839422' }],
  outputTypes: ['list', 'members', 'posts'],
  maxItems: 75,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation-lab/twitter-lists-scraper").call(run_input={
    "listUrls": [{"url": "https://x.com/i/lists/84839422"}],
    "outputTypes": ["list", "members"],
    "maxItems": 21,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with Apify MCP and AI agents

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/twitter-lists-scraper"
```

Claude Desktop, Cursor, and VS Code clients can use this MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/twitter-lists-scraper"
    }
  }
}
```

Example prompts:

- “Extract the latest 50 posts from this public X List and rank them by likes.”
- “Export the public member usernames and bios from this Twitter List.”
- “Run a complete 75-record snapshot and separate List, member, and post rows.”

### Is it legal to scrape public Twitter Lists?

Scraping public data can be lawful, but the rules depend on your jurisdiction, purpose, and how you use the results.
Only collect data you have a legitimate reason to process, minimize personal data, and honor deletion or access obligations that apply to you.
This is general information, not legal advice.

### Limits and responsible use

- Only public Lists are supported.
- Private, deleted, invalid, or login-only Lists fail clearly.
- The Actor does not log in to X and does not accept X credentials.
- Public upstream delivery routes can change or rate-limit requests.
- Very large runs may take longer because requests are intentionally paced.
- Engagement counts reflect what the public source exposes at extraction time.
- Protected members can appear in List membership, but protected posts are not bypassed.
- Media URLs are returned as links; the Actor does not download media files.

Scrape only data you are legally permitted to use.
Respect privacy, intellectual property, applicable laws, and the source platform's terms.
Do not use the output for harassment, surveillance, spam, or discriminatory profiling.

### Troubleshooting

#### Why did the run report that public List data is unavailable?

The configured public delivery routes may be rate-limited or showing an anti-bot page.
Keep the default delay and retry later.
The Actor fails instead of returning an incorrect empty dataset.

#### Why is my List rejected?

Use a URL containing `/i/lists/` and a numeric ID, or provide the numeric ID directly.
Profile URLs, search URLs, and private Lists are not supported inputs.

#### Why are some engagement fields missing?

A missing field means the public page did not expose that metric.
It does not mean the count is zero.

#### Why did I receive fewer than `maxItems`?

`maxItems` is a ceiling, not a promised quantity.
A List may contain fewer visible members or recent posts, duplicate rows may be removed, or pagination may be exhausted.

### FAQ

#### Can I scrape more than one List?

Yes.
Add multiple entries to `listUrls`; the global `maxItems` limit applies across them.

#### Can I extract only members?

Yes.
Set `outputTypes` to `["members"]`.

#### Can I extract only posts?

Yes.
Set `outputTypes` to `["posts"]`.

#### Does this Actor search for Twitter Lists?

No.
It extracts known public List URLs or IDs.

#### Does it require a proxy or X account?

No.
The current route uses public HTTP data and no paid proxy.

#### Can I schedule recurring snapshots?

Yes.
Create an Apify schedule with the same input and compare datasets downstream.

### Related Actors

- [Twitter Scraper](https://apify.com/automation-lab/twitter-scraper) for broader public Twitter/X extraction workflows.

Use related Actors only when their output and source fit your workflow.

# Actor input Schema

## `listUrls` (type: `array`):

Public List URLs such as https://x.com/i/lists/84839422. Numeric List IDs are also accepted.

## `outputTypes` (type: `array`):

Choose List metadata, members, posts, or any combination.

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

Maximum total records saved across all requested Lists and record types.

## `requestDelayMs` (type: `integer`):

Polite delay between public data requests. Increase it if the source is temporarily rate-limiting requests.

## Actor input object example

```json
{
  "listUrls": [
    {
      "url": "https://x.com/i/lists/84839422"
    }
  ],
  "outputTypes": [
    "list",
    "members",
    "posts"
  ],
  "maxItems": 20,
  "requestDelayMs": 750
}
```

# Actor output Schema

## `dataset` (type: `string`):

All extracted records in the overview dataset view.

# 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 = {
    "listUrls": [
        {
            "url": "https://x.com/i/lists/84839422"
        }
    ],
    "outputTypes": [
        "list",
        "members",
        "posts"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/twitter-lists-scraper").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 = {
    "listUrls": [{ "url": "https://x.com/i/lists/84839422" }],
    "outputTypes": [
        "list",
        "members",
        "posts",
    ],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/twitter-lists-scraper").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 '{
  "listUrls": [
    {
      "url": "https://x.com/i/lists/84839422"
    }
  ],
  "outputTypes": [
    "list",
    "members",
    "posts"
  ],
  "maxItems": 20
}' |
apify call automation-lab/twitter-lists-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/68druszBEA5HMuA90/builds/dfzl7lkCzGQf8ssgn/openapi.json
