{
  "openapi": "3.0.1",
  "info": {
    "title": "X (Twitter) Post & Tweet Scraper-MCP & API for AI Agents, LLM's",
    "description": "Scrape posts and tweets from X (Twitter): search, timelines, URLs, and threads, no official API key. Structured JSON for apps, AI agents, and LLM/RAG. You pay per unique tweet delivered, no duplicates; empty runs cost nothing, with no mock or placeholder data. Unofficial, not affiliated with X Corp.",
    "version": "1.0",
    "x-build-id": "EvK0V1jwxxlNiolpS"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/codeperfection~x-twitter-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-codeperfection-x-twitter-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/codeperfection~x-twitter-scraper/runs": {
      "post": {
        "operationId": "runs-sync-codeperfection-x-twitter-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/codeperfection~x-twitter-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-codeperfection-x-twitter-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": {
          "searchTerms": {
            "title": "Search terms",
            "type": "array",
            "description": "One or more searches to run. Each term supports full X advanced-search syntax (for example \"web scraping\", \"#ai\", \"apify lang:en\"). Terms are paginated independently, and results are deduplicated by tweet ID across all terms, so you are not charged for the same tweet twice in a run. Provide at least one of: searchTerms, twitterHandles, startUrls, or conversationIds.",
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          "twitterHandles": {
            "title": "Twitter/X handles",
            "type": "array",
            "description": "Scrape tweets authored by these accounts (handle without the @). Each handle runs as a from: search, so your date, engagement, and language filters still apply. Deduplicated with everything else in the run.",
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          "startUrls": {
            "title": "Start URLs",
            "type": "array",
            "description": "Scrape directly from X URLs. Supported: a tweet URL (x.com/user/status/ID for that exact tweet), a profile URL (x.com/user for that user's tweets), a search URL (x.com/search?q=... for that query), a list URL (x.com/i/lists/ID), or a hashtag URL (x.com/hashtag/tag). An unrecognized URL is recorded in the run's SKIPPED_SEEDS record and not charged.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "conversationIds": {
            "title": "Conversation IDs (threads)",
            "type": "array",
            "description": "Expand one or more X threads. Give a conversation ID (the thread root tweet's ID) to get the replies in that conversation. Your filters still apply, and replies are deduplicated across the run like everything else.",
            "items": {
              "type": "string"
            }
          },
          "sort": {
            "title": "Sort by",
            "enum": [
              "Latest",
              "Top"
            ],
            "type": "string",
            "description": "\"Latest\" is reverse-chronological (newest first). \"Top\" is X's relevance ranking.",
            "default": "Latest"
          },
          "maxTweets": {
            "title": "Maximum tweets per search term",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Hard cap on real tweets returned per search term. You are charged only for the real tweets delivered, so a search that finds fewer than this (or none) costs proportionally less (or nothing).",
            "default": 100
          },
          "maxTotalTweets": {
            "title": "Maximum tweets total (across all terms)",
            "minimum": 1,
            "type": "integer",
            "description": "Optional global cap on real tweets delivered across all search terms combined (maxTweets is the per-term cap). The run stops once this total is reached. Leave empty for no global cap."
          },
          "startDate": {
            "title": "From date",
            "type": "string",
            "description": "Only tweets at or after this date (UTC). Accepts an absolute date (YYYY-MM-DD or ISO-8601 timestamp) or a relative value like \"7 days\" or \"1 month\". Applied server-side and re-checked on every returned tweet."
          },
          "endDate": {
            "title": "To date",
            "type": "string",
            "description": "Only tweets strictly before this date (UTC). Accepts an absolute date (YYYY-MM-DD or ISO-8601 timestamp) or a relative value like \"1 day\"."
          },
          "fromUser": {
            "title": "From this @handle",
            "type": "string",
            "description": "Only tweets authored by this account (handle without the @). Applied server-side (from:) and re-checked against the tweet author."
          },
          "toUser": {
            "title": "Replying to this @handle",
            "type": "string",
            "description": "Only tweets that are a direct reply to this account (handle without the @). Matches the reply target, not arbitrary mentions."
          },
          "minFaves": {
            "title": "Minimum likes",
            "minimum": 0,
            "type": "integer",
            "description": "Only tweets with at least this many likes."
          },
          "minRetweets": {
            "title": "Minimum retweets",
            "minimum": 0,
            "type": "integer",
            "description": "Only tweets with at least this many retweets."
          },
          "minReplies": {
            "title": "Minimum replies",
            "minimum": 0,
            "type": "integer",
            "description": "Only tweets with at least this many replies."
          },
          "language": {
            "title": "Language",
            "type": "string",
            "description": "Only tweets in this language, as an ISO 639-1 code (for example en, ru, es, de). A tweet with no detected language is dropped rather than returned."
          },
          "media": {
            "title": "Media",
            "enum": [
              "",
              "any",
              "images",
              "videos"
            ],
            "type": "string",
            "description": "Restrict to tweets that carry media of the chosen kind.",
            "default": ""
          },
          "onlyVerified": {
            "title": "Verified authors only",
            "type": "boolean",
            "description": "Only tweets from verified accounts (legacy verified or X Premium/blue).",
            "default": false
          },
          "onlyBlueVerified": {
            "title": "Blue-verified authors only",
            "type": "boolean",
            "description": "Only tweets from X Premium (blue) accounts. Stricter than 'Verified authors only'.",
            "default": false
          },
          "onlyQuote": {
            "title": "Quote tweets only",
            "type": "boolean",
            "description": "Only quote tweets (a tweet that embeds another tweet). Applied with filter:quote and re-checked on every returned tweet.",
            "default": false
          },
          "mentioning": {
            "title": "Mentioning this @handle",
            "type": "string",
            "description": "Only tweets that mention this account (handle without the @). Applied server-side and re-checked against each tweet's mentions."
          },
          "includeSearchTerms": {
            "title": "Tag each tweet with its search term",
            "type": "boolean",
            "description": "Add a `search_term` field to every tweet recording which of your search terms found it. Useful when running several terms in one run.",
            "default": false
          },
          "outputPreset": {
            "title": "Output preset",
            "enum": [
              "full",
              "compact",
              "csvFlat"
            ],
            "type": "string",
            "description": "The base shape of every delivered tweet, before any advanced transform. \"Full\" is the complete nested JSON (all fields). \"Compact\" is a lean high-value JSON subset (author kept nested). \"CSV flat\" is flat scalar columns for CSV and spreadsheet tools (author flattened, arrays joined; structurally flat, but not formula-injection-sanitized, so see the docs if you import into a formula-evaluating app). One item out per tweet: the preset never changes how many tweets you get or what you are charged.",
            "default": "full"
          },
          "flattenAuthor": {
            "title": "Flatten author into columns (for CSV/Excel)",
            "type": "boolean",
            "description": "Legacy shortcut: replace the nested `author` object with flat `author_*` columns (author_followers, author_verified, ...). Applies to the Full and Compact presets; the CSV flat preset already flattens the author. Leave off to keep the nested JSON shape.",
            "default": false
          },
          "transformMode": {
            "title": "Transform mode",
            "enum": [
              "none",
              "projection",
              "jq"
            ],
            "type": "string",
            "description": "Optional advanced step applied on top of the format. \"None\" delivers the format unchanged. \"Pick the fields you want\" lets you choose, order, rename, and flatten fields and add constant columns without code. \"Custom formula (jq)\" runs an advanced jq program for calculated and derived fields (sums, ratios, conditionals). None of them can change the number of items: every accepted tweet still produces exactly one output item. Settings for the inactive modes are checked for validity but not applied.",
            "default": "none"
          },
          "projection": {
            "title": "Field-picker settings -- used only when Transform mode is 'Pick the fields you want'",
            "type": "object",
            "description": "Choose, order, rename, flatten, and add string constants without changing the number of output items. Ignored unless Transform mode is 'Pick the fields you want'.",
            "properties": {
              "selection": {
                "title": "Field selection",
                "type": "string",
                "description": "Output only the listed fields (plus constants), or keep all preset fields while applying the listed renames and promotions.",
                "editor": "select",
                "enum": [
                  "onlyListed",
                  "allFields"
                ],
                "enumTitles": [
                  "Only listed fields",
                  "All fields, with listed overrides"
                ],
                "default": "onlyListed"
              },
              "fields": {
                "title": "Fields",
                "type": "array",
                "description": "Ordered source paths to select or rename, as JSON: a list of {\"from\",\"to\"} objects. `from` is a documented field or dotted object path (for example author.username); a blank or omitted `to` uses the final path segment. Example: [{\"from\":\"author.username\",\"to\":\"handle\"}]",
                "editor": "json",
                "default": [],
                "maxItems": 200,
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "from"
                  ],
                  "properties": {
                    "from": {
                      "title": "Source path",
                      "type": "string",
                      "description": "Documented preset field or dotted object path, for example author.username.",
                      "editor": "textfield"
                    },
                    "to": {
                      "title": "Output name",
                      "type": "string",
                      "description": "Optional literal top-level output key; blank uses the final source-path segment.",
                      "editor": "textfield",
                      "default": ""
                    }
                  }
                }
              },
              "flatten": {
                "title": "Flatten nested objects",
                "type": "boolean",
                "description": "Recursively flatten remaining nested objects into dot-named keys; arrays are not expanded into rows.",
                "editor": "checkbox",
                "default": false
              },
              "constants": {
                "title": "String constants",
                "type": "array",
                "description": "Add constant string columns such as run tags. Keys must be unique and cannot overwrite a projected field.",
                "editor": "keyValue",
                "default": [],
                "maxItems": 100,
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "key",
                    "value"
                  ],
                  "properties": {
                    "key": {
                      "type": "string",
                      "title": "Output name",
                      "description": "Top-level output key for this constant column."
                    },
                    "value": {
                      "type": "string",
                      "title": "Value",
                      "description": "Constant string value placed in that column on every row."
                    }
                  }
                }
              },
              "arrays": {
                "title": "Array handling",
                "type": "string",
                "description": "How to handle top-level array fields: keep them as JSON arrays, encode them as compact JSON strings, or join their values into one string (nested arrays inside kept objects are unaffected).",
                "editor": "select",
                "enum": [
                  "keep",
                  "json",
                  "join"
                ],
                "enumTitles": [
                  "Keep arrays",
                  "JSON-encode arrays",
                  "Join array values"
                ],
                "default": "keep"
              },
              "arrayJoinSeparator": {
                "title": "Array join separator",
                "type": "string",
                "description": "Separator used when array handling is Join; ignored otherwise.",
                "editor": "textfield",
                "default": ","
              },
              "missingFields": {
                "title": "Missing optional fields",
                "type": "string",
                "description": "Omit a listed field that is absent from a tweet, or emit it with a null value.",
                "editor": "select",
                "enum": [
                  "omit",
                  "null"
                ],
                "enumTitles": [
                  "Omit the field",
                  "Output null"
                ],
                "default": "omit"
              }
            },
            "default": {
              "selection": "onlyListed",
              "fields": [],
              "flatten": false,
              "constants": [],
              "arrays": "keep",
              "arrayJoinSeparator": ",",
              "missingFields": "omit"
            },
            "additionalProperties": false
          },
          "jqExpression": {
            "title": "jq expression -- used only in jq mode",
            "type": "string",
            "description": "An advanced jq expression that reshapes each tweet into exactly one output object, for calculated and derived fields (engagement sums, ratios, conditionals, renames) beyond what the field picker can express. It runs on the preset-shaped tweet and must return exactly one JSON object per tweet: it cannot filter, drop, or fan out. An expression that returns nothing, a scalar, null, or multiple values is rejected before any paid run (a free dry-run is available). Module loading and environment or extra-input builtins are not permitted. Ignored unless Transform mode is jq. Example: {id, text, engagement: (.like_count + .retweet_count + .reply_count)}",
            "default": "."
          },
          "jqVariables": {
            "title": "jq variables",
            "maxItems": 50,
            "type": "array",
            "description": "Optional string variables passed to the jq expression as $name (for example a campaign tag reused across the expression). Ignored unless Transform mode is jq.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "key",
                "value"
              ],
              "properties": {
                "key": {
                  "type": "string",
                  "title": "Variable name",
                  "description": "Variable name, referenced in the jq expression as $name."
                },
                "value": {
                  "type": "string",
                  "title": "Value",
                  "description": "String value bound to the variable for this run."
                }
              }
            },
            "default": []
          },
          "outputCardinality": {
            "title": "Output cardinality",
            "enum": [
              "oneToOne"
            ],
            "type": "string",
            "description": "Contract guarantee: exactly one dataset item is produced for each delivered unique tweet. Only \"oneToOne\" is supported.",
            "default": "oneToOne"
          },
          "validateTransformOnly": {
            "title": "Validate transform only (free dry-run)",
            "type": "boolean",
            "description": "Validate the selected preset and transform against a fixed canonical sample tweet and write a preview to the run's Output, with no scrape, no dataset items, and no charge. Use it to check your transform before a paid run.",
            "default": 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}