{
  "openapi": "3.0.1",
  "info": {
    "title": "Twitter X Tweets Scraper & Post Replies",
    "description": "Collect public tweets from X Twitter at scale. Extract text, dates, likes, retweets, replies, hashtags, mentions, and user details. Supports keyword, profile, and time-based filtering for research, analytics, trend tracking, and competitive intelligence.",
    "version": "0.1",
    "x-build-id": "fLbOizLHCbNHjaYvE"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapier~Twitter-X-Tweets-Scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapier-Twitter-X-Tweets-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/scrapier~Twitter-X-Tweets-Scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapier-Twitter-X-Tweets-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/scrapier~Twitter-X-Tweets-Scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapier-Twitter-X-Tweets-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",
        "required": [
          "startUrls"
        ],
        "properties": {
          "startUrls": {
            "title": "🔗 Profiles or post URLs to open",
            "type": "array",
            "description": "One target per line. Accepted forms:\n\n• https://x.com/NASA  or  https://twitter.com/NASA\n• NASA  or  @NASA\n• a numeric user ID, e.g. 11348282\n• a single post: https://x.com/NASA/status/2082511887757881648\n\nA post URL returns exactly one row for that post — with its replies — and ignores the post limit. Pasting a post URL is the fastest way to read one conversation.",
            "items": {
              "type": "string"
            }
          },
          "maxTweets": {
            "title": "🔢 Posts per profile",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "How many posts to collect from each PROFILE (1–1000). The pinned post counts towards this limit, and duplicates are removed before anything is charged, so you never get more rows than you asked for.\n\nSingle post URLs are not affected by this setting. Default: 10.\n\nCost note: reply collection costs one or more extra requests PER POST, so this number is the real cost driver here — 10 posts at 20 replies each is roughly 10–20 extra requests.",
            "default": 10
          },
          "sortOrder": {
            "title": "↕️ Row order",
            "enum": [
              "recent",
              "oldest",
              "popular"
            ],
            "type": "string",
            "description": "Re-orders the posts collected in this run. X always serves a timeline newest-first; this setting does not search further back than the posts already fetched.",
            "default": "recent"
          },
          "collectPostReplies": {
            "title": "💬 Collect the replies written under each post",
            "type": "boolean",
            "description": "On (default): each post's conversation is opened and the replies are attached to that post's row as `post_replies` — the reply text, who wrote it, how big their account is, and how the reply itself performed.\n\nOff: this actor behaves exactly like the base X posts scraper and needs no login at all.\n\nThis is NOT the same option as “Include the profile's own replies” below: that one changes WHICH POSTS are collected (the profile's Posts-and-replies tab). This one collects what OTHER people wrote back under the posts you already have.",
            "default": true
          },
          "maxRepliesPerPost": {
            "title": "🔢 Replies to keep per post",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Caps the replies attached to each post (1–200). Every reply beyond the cap is reported through `replies_truncated: true` rather than silently dropped, and `replies_declared` always shows X's own count for comparison.\n\n20 is enough to read the tone of a thread on one screen. Raise it for a serious conversation audit; each extra ~20 replies is one more request against a 150-per-15-minutes budget.",
            "default": 20
          },
          "replyRanking": {
            "title": "🏅 Which replies X should serve first",
            "enum": [
              "Likes",
              "Relevance",
              "Recency"
            ],
            "type": "string",
            "description": "X ranks a conversation and never serves all of it. The ranking you pick changes both WHICH replies you get and HOW MANY — and no single ranking wins on every post.\n\nMeasured 2026-08-03 on one post X declares 337 replies for, pagination run to natural termination: Relevance served 228 unique replies over 7 requests, Likes 182 over 12, Recency 34 over 8 — a 6.7x spread on the same post. On a larger post the order flipped entirely (Likes 581, Recency 503, Relevance 375). Likes is the default as an engagement-weighted starting point; when recovery matters more than requests, turn on the deep sweep below instead of guessing. Reply sets drift between runs, so treat these as magnitudes, not constants.",
            "default": "Likes"
          },
          "deepReplySweep": {
            "title": "🔁 Deep sweep — union all three rankings",
            "type": "boolean",
            "description": "Off (default): one ranking, one pass.\n\nOn: the post is swept under Likes, Relevance AND Recency and the results are merged by reply id, each ranking getting its own page budget. Because no single ranking dominates, the union is the only setting that does not depend on guessing the right one: on the 337-reply post above it reached 228 unique replies where Likes alone reached 182 (+25%), and on a larger post a direct probe of the surface gave 822 against 581 for the best single ranking (+42%).\n\nCosts up to three times the requests (21 against 12 on the measured post), and pagination stops early per ranking once one stops adding new replies. Worth it for a one-post audit; wasteful across a whole timeline.",
            "default": false
          },
          "minReplierFollowers": {
            "title": "👥 Skip replies from accounts under this follower count",
            "minimum": 0,
            "type": "integer",
            "description": "0 (default) keeps every reply. Above 0, a reply is kept only if X published a follower count for its author and that count meets the floor.\n\nThis screens the conversation by the AUDIENCE that wrote it. X Premium made the blue badge purchasable, so a follower floor separates real accounts from reply-guys where the badge no longer does. Every removed reply is counted in `replies_dropped_by_filter`, so the deletion is visible rather than silent.\n\nThe default is 0 on purpose: small accounts are where genuine customer complaints live.",
            "default": 0
          },
          "onlyRepliedPosts": {
            "title": "🗣️ Keep only posts that got replies",
            "type": "boolean",
            "description": "Off (default): every post is a row, whether anyone answered or not.\n\nOn: posts whose conversation returned no replies are dropped before anything is charged. A run over a busy account that returns nine rows is the answer — those nine are where the conversation happened. If every post is dropped the run ends with an accounting row and a non-zero exit, never a silent empty dataset.",
            "default": false
          },
          "includeReplies": {
            "title": "↩️ Also collect the profile's OWN replies as posts",
            "type": "boolean",
            "description": "Off: the profile's posts, reposts and quotes (the “Posts” tab).\n\nOn: also the replies that profile wrote to other people (the “Posts and replies” tab) — as POSTS in their own right, each with its own conversation. This surface is available only to a logged-in caller, so it needs the X session below.\n\nThis is the base actor's own option and behaves exactly as it does there.",
            "default": false
          },
          "auth_token": {
            "title": "🔑 X session — auth_token cookie",
            "type": "string",
            "description": "REQUIRED whenever “Collect the replies written under each post” is on (it is on by default). Copy the value of the `auth_token` cookie from an x.com browser session (DevTools → Application → Cookies → x.com).\n\nX returns HTTP 404 with a 0-byte body to logged-out callers on the TweetDetail conversation surface, on both GET and POST — there is no keyless way to read replies.\n\nStored encrypted, sent only to api.x.com, and never written to the dataset or the run log."
          },
          "ct0": {
            "title": "🔑 X session — ct0 cookie",
            "type": "string",
            "description": "Required together with `auth_token`. Copy the value of the `ct0` cookie from the same x.com browser session; it is the CSRF token X checks on every authenticated request.\n\nStored encrypted, sent only to api.x.com, and never written to the dataset or the run log."
          },
          "proxyConfiguration": {
            "title": "🌐 Proxy",
            "type": "object",
            "description": "Off by default. X was measured serving this data to a bare Apify datacenter exit, so a proxy is optional. Turn Apify Proxy on if you want a different exit or run at high volume; the actor rotates to a fresh exit once if a request fails before any row was saved.\n\nA proxy does NOT raise the X rate limit — the TweetDetail budget of 150 requests per 15 minutes is tied to your session, not to your IP.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}