# Twitter (X) Comments Scraper (`outspoken_strategy/twitter-comments-scraper`) Actor

Scrape replies (comments) of Twitter/X posts from their URLs — many posts in one run. Returns text, author, favorites, retweets, replies and the source tweet each reply belongs to. Compatible with api-ninja/x-twitter-replies-retweets-scraper.

- **URL**: https://apify.com/outspoken\_strategy/twitter-comments-scraper.md
- **Developed by:** [code craker](https://apify.com/outspoken_strategy) (community)
- **Categories:** Social media, E-commerce, Other
- **Stats:** 7 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 results

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 (X) Comments Scraper

Scrape the **replies (comments) of Twitter/X posts** without the official API. Give the actor one or **many post URLs** and it opens each conversation, auto-scrolls it (expanding the hidden "Show more replies" sections), and exports every reply as structured JSON — text, author, likes, retweets, reply counts, timestamps and the source post each reply belongs to. Results can be downloaded as JSON, CSV, Excel or accessed via the Apify API.

The output is built for pipelines: flat items with `tweet_id` and `user_info.*` author keys, and `metadata.sourceTweetId` + `inputUrl` on every reply, so multi-post runs stay cleanly attributed to their source posts.

### Features

- 🔗 **Scrape by post URL** — paste any `https://x.com/user/status/...` (or twitter.com) links.
- 📚 **Many posts per run** — all URLs are scraped in a single browser session; every item carries `metadata.sourceTweetId` + `inputUrl` so replies never get mixed up between posts.
- ♾ **Auto-pagination** — scrolls the conversation and clicks "Show more replies" / "Show probable spam" until the per-post limit is reached or the thread runs dry (up to 1,000 replies per post).
- 🧵 **Thread-aware** — replies-to-replies are included, with `in_reply_to_status_id_str` so you can rebuild the tree; the source post itself is emitted once and flagged `is_source_tweet`.
- 🚮 **No junk** — the unrelated "Discover more" tweets X injects below conversations are filtered out via the conversation id.
- 💾 **Incremental results** — replies are pushed to the dataset as each post finishes, so long runs never lose collected data to a timeout.
- 🔐 **Flexible authentication** — session cookies, secret env vars, or fully automated login with session caching.
- 🛠 **Debuggable failures** — on empty runs the actor saves a screenshot and the page HTML to the run's key-value store.

### Use cases

- Sentiment analysis of audience reactions to specific posts
- Brand, campaign and influencer monitoring
- Community management and social listening pipelines
- Market and academic research

### Quick start

1. Enter one or more post URLs.
2. Provide a session (see **Authentication** below) — a throwaway X account's cookies or credentials.
3. Run. Replies appear in the dataset as each post completes.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `urls` | array | Post URLs (`https://x.com/user/status/<id>`), one or many. De-duplicated by tweet id. |
| `startUrls` | array | Same URLs as request-list `{ "url": ... }` objects — merged with `urls`. |
| `category` | string | What to scrape for each post — currently `replies` (the comments under the post). |
| `resultsPerCategory` | integer | Target replies PER post (max 1000). Default 100. The source post itself doesn't count. |
| `parseAllResults` | boolean | Accepted for backwards compatibility; items are always fully parsed. |
| `scrapeAll` | boolean | Auto-paginate until the per-post target is reached. When `false` only the initial page load is returned. Default `true`. |
| `includeSourceTweet` | boolean | Also emit one item for the post itself, flagged `is_source_tweet: true`. Set `false` to get replies only. Default `true`. |
| `cookies` | array | Cookies of a logged-in X session (Cookie-Editor/EditThisCookie JSON export). The `auth_token` + `ct0` cookies carry the session. |
| `twUsername` / `twPassword` / `twEmail` | string | Credentials for automated login (2FA must be disabled). The email answers X's occasional identity check. |
| `proxyConfiguration` | object | Proxy settings. Residential proxies strongly recommended. |
| `headless` | boolean | Uncheck only for local debugging. |

#### Authentication

X hides conversation replies from anonymous visitors, so the actor needs a session. It resolves one in this priority order:

1. the `cookies` input (per-run),
2. the `TW_COOKIES` secret env var (JSON cookie array or a `name=value; name2=value2` header string),
3. the session cached in the `twitter-session` key-value store by a previous automated login,
4. automated login with `twUsername`/`twPassword` (or the `TW_USERNAME`/`TW_PASSWORD`/`TW_EMAIL` secret env vars) — the fresh session is cached for future runs.

**Always use a throwaway account, never a personal one.** Accounts used for scraping can be restricted by X.

### Output

One dataset item per reply (plus one for the source post, flagged `is_source_tweet: true`):

```json
{
    "tweet_id": "1234567890123456790",
    "id": "1234567890123456790",
    "url": "https://x.com/someuser/status/1234567890123456790",
    "text": "Reply text...",
    "full_text": "Reply text...",
    "lang": "en",
    "created_at": "2026-05-01T10:02:00.000Z",
    "createdTime": "2026-05-01T10:02:00.000Z",
    "favorites": 5,
    "retweets": 0,
    "replies": 1,
    "quotes": 0,
    "views": 321,
    "screen_name": "someuser",
    "user_info": {
        "rest_id": "44196397",
        "name": "Some User",
        "screen_name": "someuser",
        "url": "https://x.com/someuser",
        "avatar": "https://pbs.twimg.com/profile_images/....jpg",
        "followers": 1200,
        "verified": false,
        "blue_verified": true
    },
    "user_info.name": "Some User",
    "user_info.screen_name": "someuser",
    "user_info.rest_id": "44196397",
    "user_info.avatar": "https://pbs.twimg.com/profile_images/....jpg",
    "is_reply": true,
    "in_reply_to_status_id_str": "1234567890123456789",
    "conversation_id_str": "1234567890123456789",
    "is_source_tweet": false,
    "category": "replies",
    "inputUrl": "https://x.com/author/status/1234567890123456789",
    "metadata": {
        "sourceTweetId": "1234567890123456789",
        "sourceTweetUrl": "https://x.com/author/status/1234567890123456789",
        "category": "replies"
    },
    "metadata.sourceTweetId": "1234567890123456789",
    "hashtags": [],
    "mentions": ["author"],
    "urls": [],
    "media": [],
    "scrapedAt": "2026-07-03T12:00:00.000Z"
}
````

Notes for consumers:

- **Attribution in multi-post runs:** use `metadata.sourceTweetId` (emitted both as a nested object and a flat dotted key, so both access styles work) or `inputUrl`.
- **Dropping the source post:** filter out items where `tweet_id` equals the source id, or simply where `is_source_tweet` is `true`.
- **Top-level comment vs reply-to-reply:** a reply whose `in_reply_to_status_id_str` equals the source id is a top-level comment; any other value points at the parent reply.

### Usage via API

Run the actor from your own code and read the replies from the default dataset — for example with the JavaScript client:

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('<username>/twitter-comments-scraper').call({
    urls: [
        'https://x.com/user/status/1234567890123456789',
        'https://x.com/other/status/9876543210987654321',
    ],
    resultsPerCategory: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
const replies = items.filter((item) => !item.is_source_tweet);
```

Or with plain HTTP:

```bash
curl -X POST "https://api.apify.com/v2/acts/<username>~twitter-comments-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://x.com/user/status/1234567890123456789"], "resultsPerCategory": 50}'
```

### FAQ

**How many posts can I scrape in one run?**
There is no fixed limit — all URLs are processed sequentially in one browser session. For very large batches, split the URLs across a few runs so a single run stays well under its timeout; replies are pushed per post, so partial runs still keep everything scraped so far.

**Why do I need cookies or an account?**
X hides conversation replies from anonymous visitors. Any active session of a (throwaway) account is enough — the actor never posts, likes or follows.

**Are replies-to-replies included?**
Yes. Use `in_reply_to_status_id_str` to rebuild the thread: when it equals the source post id the item is a top-level comment, otherwise it points at the parent reply.

**Does it also return retweets or quotes?**
No — this actor is focused on replies (comments). The `category` field is reserved for possible future categories.

### Troubleshooting

| Symptom | Likely cause & fix |
| --- | --- |
| Run fails with "Could not load the X post page" | The proxy exit IP can't reach X. Use Apify Proxy with the **RESIDENTIAL** group (datacenter IPs are widely blocked). |
| Run fails with "X blocked the conversation" | No/expired session. Refresh the `cookies` input or `TW_COOKIES`, or provide `twUsername`/`twPassword` for automated login. |
| 0 results but the run succeeded | Post deleted/protected/age-restricted, or the session expired mid-run. Check `DEBUG_SCREENSHOT` and `DEBUG_HTML` in the run's key-value store. |
| Fewer replies than expected | X often hides part of a conversation ("Show more replies" is capped for low-quality/spam replies) — the actor expands what X exposes to a logged-in browser. |

### Running locally

```bash
npm install
APIFY_LOCAL_STORAGE_DIR=./storage node src/main.js
```

Put the run input into `./storage/key_value_stores/default/INPUT.json`.

### Support & feedback

If a run misbehaves, open an issue on the actor's **Issues** tab in Apify Console with the run URL — the debug screenshot and HTML saved by failed runs usually pinpoint the cause quickly. Feature requests are welcome there too.

### Disclaimer

Scraping publicly available data is generally legal, but you are responsible for complying with X's Terms of Service, applicable data-protection laws (GDPR, CCPA) and the rights of the platform's users. Use throwaway accounts and residential proxies, and scrape responsibly.

# Actor input Schema

## `urls` (type: `array`):

URLs of the X/Twitter posts whose replies (comments) you want to scrape, e.g. https://x.com/user/status/1234567890123456789 — one or MANY posts per run. Both x.com and twitter.com URLs work.

## `startUrls` (type: `array`):

Alternative way to provide the post URLs as a request list of { "url": ... } objects. Merged with "urls" and de-duplicated by tweet id.

## `category` (type: `string`):

What to scrape for each post. Currently "replies" (the comments under the post).

## `resultsPerCategory` (type: `integer`):

Maximum number of replies to fetch PER post URL. The source post itself is also emitted (flagged is\_source\_tweet) and does not count towards this limit.

## `parseAllResults` (type: `boolean`):

Accepted for backwards compatibility with older pipelines. This actor always emits fully parsed items, so the flag has no effect.

## `scrapeAll` (type: `boolean`):

Keep scrolling the conversation (and expanding "Show more replies") until the per-post limit is reached or the thread runs dry. When unchecked only the replies on the initial page load are returned.

## `includeSourceTweet` (type: `boolean`):

Also emit one dataset item for the post itself (flagged is\_source\_tweet: true). Uncheck to get replies only.

## `cookies` (type: `array`):

Cookies of a logged-in X session, exported with a browser extension such as Cookie-Editor or EditThisCookie (JSON array of {name, value, domain, ...}). REQUIRED in practice: X hides replies from anonymous visitors. The "auth\_token" and "ct0" cookies carry the session. Alternatively set the TW\_COOKIES secret environment variable on the actor (same JSON, or a 'name=value; name2=value2' string) to avoid passing cookies in every run. Use a throwaway account, never your personal one.

## `twUsername` (type: `string`):

Username/email/phone of a throwaway X account. If set together with twPassword (or via the TW\_USERNAME/TW\_PASSWORD secret env vars), the actor logs in itself and caches the session, so you don't need to paste cookies. The account must have 2FA disabled. Prefer setting these as secret environment variables on the actor rather than per run.

## `twPassword` (type: `string`):

Password for the account in twUsername. Stored encrypted. Prefer the TW\_PASSWORD secret environment variable instead of putting it in run input.

## `twEmail` (type: `string`):

Email of the account, used only when X asks to confirm the identity during automated login ("Enter your phone number or email"). Also settable via the TW\_EMAIL env var.

## `proxyConfiguration` (type: `object`):

Proxy to route traffic through. Residential proxies with a country set are strongly recommended for X — the random global residential pool often hands out dead exit IPs, so the actor defaults RESIDENTIAL to US exits when no country is chosen.

## `headless` (type: `boolean`):

Uncheck to run a headed browser (useful only for local debugging).

## Actor input object example

```json
{
  "urls": [
    "https://x.com/elonmusk/status/1585841080431321088"
  ],
  "startUrls": [],
  "category": "replies",
  "resultsPerCategory": 100,
  "parseAllResults": false,
  "scrapeAll": true,
  "includeSourceTweet": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "headless": true
}
```

# 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 = {
    "urls": [
        "https://x.com/elonmusk/status/1585841080431321088"
    ],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("outspoken_strategy/twitter-comments-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 = {
    "urls": ["https://x.com/elonmusk/status/1585841080431321088"],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("outspoken_strategy/twitter-comments-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 '{
  "urls": [
    "https://x.com/elonmusk/status/1585841080431321088"
  ],
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call outspoken_strategy/twitter-comments-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Twitter (X) Comments Scraper",
        "description": "Scrape replies (comments) of Twitter/X posts from their URLs — many posts in one run. Returns text, author, favorites, retweets, replies and the source tweet each reply belongs to. Compatible with api-ninja/x-twitter-replies-retweets-scraper.",
        "version": "1.0",
        "x-build-id": "kV3CxlvtFxq6kgOsX"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/outspoken_strategy~twitter-comments-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-outspoken_strategy-twitter-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/outspoken_strategy~twitter-comments-scraper/runs": {
            "post": {
                "operationId": "runs-sync-outspoken_strategy-twitter-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/outspoken_strategy~twitter-comments-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-outspoken_strategy-twitter-comments-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "urls": {
                        "title": "Post URLs",
                        "type": "array",
                        "description": "URLs of the X/Twitter posts whose replies (comments) you want to scrape, e.g. https://x.com/user/status/1234567890123456789 — one or MANY posts per run. Both x.com and twitter.com URLs work.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "startUrls": {
                        "title": "Post URLs (request list)",
                        "type": "array",
                        "description": "Alternative way to provide the post URLs as a request list of { \"url\": ... } objects. Merged with \"urls\" and de-duplicated by tweet id.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "category": {
                        "title": "Category",
                        "enum": [
                            "replies"
                        ],
                        "type": "string",
                        "description": "What to scrape for each post. Currently \"replies\" (the comments under the post).",
                        "default": "replies"
                    },
                    "resultsPerCategory": {
                        "title": "Max replies per post",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum number of replies to fetch PER post URL. The source post itself is also emitted (flagged is_source_tweet) and does not count towards this limit.",
                        "default": 100
                    },
                    "parseAllResults": {
                        "title": "Parse all results",
                        "type": "boolean",
                        "description": "Accepted for backwards compatibility with older pipelines. This actor always emits fully parsed items, so the flag has no effect.",
                        "default": false
                    },
                    "scrapeAll": {
                        "title": "Scrape all (auto-paginate)",
                        "type": "boolean",
                        "description": "Keep scrolling the conversation (and expanding \"Show more replies\") until the per-post limit is reached or the thread runs dry. When unchecked only the replies on the initial page load are returned.",
                        "default": true
                    },
                    "includeSourceTweet": {
                        "title": "Include the source post",
                        "type": "boolean",
                        "description": "Also emit one dataset item for the post itself (flagged is_source_tweet: true). Uncheck to get replies only.",
                        "default": true
                    },
                    "cookies": {
                        "title": "Twitter/X session cookies",
                        "type": "array",
                        "description": "Cookies of a logged-in X session, exported with a browser extension such as Cookie-Editor or EditThisCookie (JSON array of {name, value, domain, ...}). REQUIRED in practice: X hides replies from anonymous visitors. The \"auth_token\" and \"ct0\" cookies carry the session. Alternatively set the TW_COOKIES secret environment variable on the actor (same JSON, or a 'name=value; name2=value2' string) to avoid passing cookies in every run. Use a throwaway account, never your personal one."
                    },
                    "twUsername": {
                        "title": "X username (automated login)",
                        "type": "string",
                        "description": "Username/email/phone of a throwaway X account. If set together with twPassword (or via the TW_USERNAME/TW_PASSWORD secret env vars), the actor logs in itself and caches the session, so you don't need to paste cookies. The account must have 2FA disabled. Prefer setting these as secret environment variables on the actor rather than per run."
                    },
                    "twPassword": {
                        "title": "X password (automated login)",
                        "type": "string",
                        "description": "Password for the account in twUsername. Stored encrypted. Prefer the TW_PASSWORD secret environment variable instead of putting it in run input."
                    },
                    "twEmail": {
                        "title": "X email (login identity check)",
                        "type": "string",
                        "description": "Email of the account, used only when X asks to confirm the identity during automated login (\"Enter your phone number or email\"). Also settable via the TW_EMAIL env var."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Proxy to route traffic through. Residential proxies with a country set are strongly recommended for X — the random global residential pool often hands out dead exit IPs, so the actor defaults RESIDENTIAL to US exits when no country is chosen.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "US"
                        }
                    },
                    "headless": {
                        "title": "Run browser headless",
                        "type": "boolean",
                        "description": "Uncheck to run a headed browser (useful only for local debugging).",
                        "default": true
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
