{
  "openapi": "3.0.1",
  "info": {
    "title": "X Twitter Posts Search (Reposter Finder)",
    "description": "X (Twitter) Posts Search (Reposter Finder) finds posts matching keywords and identifies users who repost or amplify them. Extract post text, authors, timestamps, engagement, repost data, and profile details for audience research, influencer discovery, and social monitoring.",
    "version": "0.2",
    "x-build-id": "UyE18YypakO5CUQLW"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapier~x-twitter-posts-search/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapier-x-twitter-posts-search",
        "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~x-twitter-posts-search/runs": {
      "post": {
        "operationId": "runs-sync-scrapier-x-twitter-posts-search",
        "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~x-twitter-posts-search/run-sync": {
      "post": {
        "operationId": "run-sync-scrapier-x-twitter-posts-search",
        "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",
          "searchType"
        ],
        "properties": {
          "startUrls": {
            "title": "🎯 Targets — keywords, @handles, profile URLs, search URLs or post URLs",
            "type": "array",
            "description": "📋 **One row per target.** Mix and match freely.\n\n✅ **What works:**\n• 🔤 Keyword(s) — `climate change` *(needs cookies)*\n• 🧠 Search syntax — `search: nasa min_retweets:500` *(needs cookies)*\n• 🔗 X search URL — `https://x.com/search?q=nasa&f=live` *(needs cookies)*\n• #️⃣ Hashtag URL or `#tag` — `https://x.com/hashtag/NASA` *(needs cookies)*\n• 👤 Handle / profile URL — `@NASA` · `https://x.com/NASA` *(works without cookies)*\n• 📌 Single post URL — `https://x.com/NASA/status/1234567890` *(works without cookies)*\n\n🚫 **Skipped:** X app pages (`/explore`, `/i/…`, `/home`) — they have no scrapable timeline.",
            "items": {
              "type": "string"
            }
          },
          "maxTweets": {
            "title": "🔢 Max posts per target",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "🎯 **Cap posts collected per target.**\n\n⚖️ Every kept post costs one or more reposter calls, so this is also your reposter budget multiplier.\n💸 Start at 5–10 while you tune the reposter settings, then scale up.",
            "default": 10
          },
          "searchType": {
            "title": "🔎 Search mode — Top or Latest",
            "enum": [
              "top",
              "latest"
            ],
            "type": "string",
            "description": "🏆 **Top** → popular & relevant posts (best for finding posts that actually got reposted).\n🆕 **Latest** → newest first (best with the time window for live monitoring).\n\n🧑 Note: this applies to **keyword/hashtag search only**. X's profile-timeline API has no sort parameter, so profile targets are always reverse-chronological.",
            "default": "top"
          },
          "timeWindow": {
            "title": "📅 Time window — last N days",
            "minimum": 1,
            "type": "integer",
            "description": "🗓️ **Keep only posts newer than N days (UTC).**\n\n✅ Applied to **every** target type — search, profiles and post URLs alike.\n🔕 Leave empty to collect up to *Max posts* regardless of date."
          },
          "timeWindowHours": {
            "title": "🕐 Time window — last N hours",
            "minimum": 1,
            "type": "integer",
            "description": "⏰ **Keep only posts newer than N hours (UTC).**\n\n✅ Applied to **every** target type.\n⚡ Use for breaking-news amplification tracking.\n👑 Takes precedence over days if both are set."
          },
          "authToken": {
            "title": "🍪 X cookie — auth_token",
            "type": "string",
            "description": "🔐 The `auth_token` cookie from your logged-in x.com session.\n\n🧭 **Where to find it:** open x.com while logged in → DevTools → Application → Cookies → `https://x.com` → copy the `auth_token` value.\n\n⚠️ X rate limits are shared across every run using the same X account."
          },
          "ct0": {
            "title": "🍪 X cookie — ct0",
            "type": "string",
            "description": "🔐 The `ct0` cookie (X's CSRF token) from the **same** logged-in session as `auth_token`.\n\n📌 Both cookies must come from the same session or X rejects the request."
          },
          "includeReposters": {
            "title": "🔁 Collect reposters for each post",
            "type": "boolean",
            "description": "✅ **On** → for every post kept, fetch the accounts that reposted it.\n🚫 **Off** → posts only (each row reports `repostFetchStatus: \"disabled\"`).\n\n💡 Posts whose repost count is 0 are skipped automatically — no wasted calls.",
            "default": true
          },
          "maxRepostersPerPost": {
            "title": "👥 Max reposters per post",
            "minimum": 0,
            "maximum": 5000,
            "type": "integer",
            "description": "🔢 **Cap reposters collected per post.** X returns 100 accounts per call (a hard server clamp — larger `count` values are ignored), so 100 = 1 call, 500 = 5 calls.\n\n⏳ Budget: ~500 reposter calls per 15 minutes per X account.\n📊 Because X ranks reposters by follower count, the first pages are the highest-audience amplifiers.",
            "default": 100
          },
          "minReposterFollowers": {
            "title": "📈 Only keep reposters with at least N followers",
            "minimum": 0,
            "type": "integer",
            "description": "🎯 **Filter out small accounts.** e.g. `10000` keeps only reposters with 10K+ followers.\n\n⚡ Pairs with **Ranked early exit** below: because X returns reposters roughly follower-descending, the actor can stop paging as soon as the remaining pages can no longer clear your threshold.\n\n🔕 Leave at 0 to keep everyone.",
            "default": 0
          },
          "rankedEarlyExit": {
            "title": "⏹️ Ranked early exit — stop paging once follower counts drop below the threshold",
            "type": "boolean",
            "description": "⚡ **On** → when *Min followers* is set, stop paging a post once the accounts being returned have fallen below it, saving calls and time.\n\n🛡️ **Self-verifying, so it cannot silently lose data:** X's follower ranking only holds on posts whose pages come back full. The actor watches each page's median follower count and **arms the early exit only while that ordering is genuinely descending**, and even then waits for 2 consecutive pages below the threshold. Every post row reports `reposterRankingObserved` (`descending` / `unranked`) and `reposterEarlyExit` so you can audit exactly what happened.\n\n🚫 **Off** → always page to *Max reposters*.",
            "default": true
          },
          "includeQuoteAmplifiers": {
            "title": "💭 Also collect quote-post amplifiers",
            "type": "boolean",
            "description": "💬 **On** → also fetch accounts that **quote-posted** the post (a repost with added commentary).\n\n⚠️ **Honest ceiling:** X caps this surface at about **40 quote posts per post** no matter how large the quote count is, and it spends the scarcer search budget (~187 calls / 15 min). Off by default for that reason.",
            "default": false
          },
          "maxQuoteAmplifiersPerPost": {
            "title": "💭 Max quote amplifiers per post",
            "minimum": 0,
            "maximum": 40,
            "type": "integer",
            "description": "🔢 Cap on quote posts collected per post. X's own ceiling is ~40, so higher values change nothing.",
            "default": 40
          },
          "reposterDatasetName": {
            "title": "📚 Name for the reposters dataset",
            "type": "string",
            "description": "📦 Reposter rows are written to a **separate named dataset** so the post rows stay clean.\n\n🔕 Leave empty to auto-name it `x-reposters-<runId>`. Set a fixed name to append every run's reposters into one growing dataset."
          },
          "proxyConfiguration": {
            "title": "🌐 Proxy — recommended for stable runs",
            "type": "object",
            "description": "🔒 **Off** → direct connection.\n✅ **On** → Apify Proxy (pick your groups in the UI).\n\n⭐ RESIDENTIAL is the safest default; datacenter groups were also measured returning HTTP 200 on X."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}