Twitter (X.com) Tweets & Profiles Scraper
Pricing
from $4.99 / 1,000 results
Twitter (X.com) Tweets & Profiles Scraper
Scrape public Twitter X profiles with tweets, bios, followers, links, and engagement data. This actor captures structured profile insights at scale, supports keyword filtering, and exports clean JSON or CSV for research, analysis, and automation workflows.
Pricing
from $4.99 / 1,000 results
Rating
0.0
(0)
Developer
API Empire
Maintained by CommunityActor stats
0
Bookmarked
16
Total users
0
Monthly active users
a day ago
Last modified
Categories
Share
X (Twitter) Scraper — Extract Posts, Replies & Quote Posts as JSON
This X (Twitter) scraper pulls a profile's timeline and then walks every post into its own
conversation: replies and quote posts come back as their own child rows, linked to the
parent post by parentId, replyDepth, and per-thread roll-up counts. Every row — post,
reply, or quote — is typed, normalized JSON with the same column set, so it drops straight
into a pipeline, a spreadsheet, or an LLM context window with no HTML and no selectors to
write. Read on for exactly which fields each row type carries, what X requires before it
hands over a reply or a quote post, and where the platform's own caps sit.
🧭 What is X (Twitter) User Profile & Tweets Scraper + Reply Threads?
X (Twitter) User Profile & Tweets Scraper + Reply Threads is an Apify Actor that scrapes
public X profile timelines and turns each post into its full conversation. One run returns
three connected entity types — posts, replies, and quote posts — each carrying
the same base columns plus a nested author profile. Profile timelines run fully logged out
over X's guest-token GraphQL surface; replies, quote posts, and keyword search need a
customer-supplied X session (an auth_token + ct0 cookie pair), because X answers those
three surfaces with an empty HTTP 404 to anonymous clients.
- 🧵 Scrape a profile's posts, sorted newest, oldest, or most-liked
- 💬 Walk every post into its reply thread, up to 3 levels deep
- 🔁 Collect the quote posts that reference each post
- 👤 Attach full author profile data — bio, follower counts, join date, verification — to every row
- 📦 Export the dataset as JSON, CSV, Excel, or any format Apify's dataset API supports
📊 What data does X (Twitter) User Profile & Tweets Scraper + Reply Threads collect?
A single run returns four kinds of data, all in one dataset: the profile's own posts, the replies under each post, the quote posts that reference each post, and the author profile nested on every row.
| Data Type | Key Fields | JSON Field Names |
|---|---|---|
Posts (rowType: "tweet") | Text, engagement counts, media, links, per-thread roll-up stats | text, likes, retweets, quotes, views, media, links, repliesClaimed, repliesCollected, replyRecoveryRatio |
Replies (rowType: "reply") | Reply text, parent link, depth, in-reply-to target | text, parentId, replyDepth, inReplyToId, inReplyToUsername |
Quote posts (rowType: "quote") | The quoting post's own text and engagement, parent link | text, parentId, isQuote, likes, retweets |
| Author profile (nested on every row) | Bio, location, follower/following counts, verification | user.description, user.totalFollowers, user.totalFollowing, user.verified, user.joinDate |
Need more X (Twitter) data?
If your workflow is really about who reposted or quoted a post rather than the conversation underneath it, the same account also publishes Twitter X Tweets Scraper Scraper - Repost and Quote, which opens every repost and quote back to the original post's own engagement counts and the original author's profile — a narrower, cheaper tool when reply threads aren't what you need.
⚔️ How does X (Twitter) User Profile & Tweets Scraper + Reply Threads differ from the official X API?
The official X API requires a developer account, app credentials, and metered billing before you get a single row back; this Actor runs from a profile URL with no developer account needed for post data.
| Feature | Official X API | This Actor |
|---|---|---|
| Access setup | Sign up at console.x.com, create an app, buy credits (docs.x.com, checked 2026-08-04) | Paste a startUrls entry and run — no developer account for post data |
| Pricing | Pay-per-use: $0.005 per post read, $0.015–$0.200 per post created, capped at 2,000,000 reads per monthly billing cycle (docs.x.com, checked 2026-08-04) | Apify's per-result pricing on the Actor's own Store page — no separate per-post metering to track |
| Read rate limits | 3,500 tweet reads / 15 min and 450 search requests / 15 min per app (docs.x.com, checked 2026-08-04) | Bound by the same X-side limits the Actor reads from x-rate-limit-remaining; backs off automatically on HTTP 429 instead of hard-failing |
| Reply/conversation coverage | Conversation lookups go through the same metered search endpoints as everything else | Walks each post into a full reply tree up to 3 levels deep, with recovery stats, in the same run |
| Output shape | Raw GraphQL/REST JSON keyed to X's own schema; stitching a post to its replies and quotes is your job | One dataset, three row types already joined by parentId |
| Setup time | Developer account approval plus (for legacy tiers) a subscription starting at $200/month (docs.x.com, checked 2026-08-04) | Runs immediately; only the reply/quote/search surfaces need a copied session cookie pair |
The official API is the right call for real-time, high-volume programmatic access under a predictable per-request budget with formal API terms attached. This Actor fits one-off or scheduled dataset pulls where you want posts, replies, and quote posts pre-joined into one JSON row without opening a developer account or tracking credits.
🎯 Why do developers and teams scrape X (Twitter)?
🤖 For AI engineers and agent builders
Reply threads are exactly the kind of unstructured signal RAG pipelines want structured.
Pull a brand's or a topic's posts with scrapeReplyThreads on, index text and
fullTextLongForm per row into a vector store, and use parentId / replyDepth to keep
the conversation tree intact for an agent that needs to reason about who said what to whom.
Because every row is typed JSON with stable field names, there's no HTML to strip before it
reaches the model.
📣 For marketers and brand teams
Point startUrls at a competitor's handle, set includeQuoteTweets on, and read
quoteTweetsCollected and the nested user block on each quoting account to see who is
amplifying a competitor's launch post and how large their following is — without opening
X's own login-walled search UI by hand.
🔬 For researchers and analysts
Public conversation data — who replies to whom, at what depth, with what engagement — is
the raw material for discourse and network research. replyRecoveryRatio reports what
fraction of a post's claimed replies were actually recoverable, so a study can state its
coverage honestly instead of treating a partial pull as complete. Scope is limited to what
X serves publicly to the session you supply.
🛠️ For developers building data products
Because posts, replies, and quote posts share one column set, a scheduled run (Apify
schedule or webhook) can feed a downstream table or dashboard without a translation layer
between row types. threadStatus and quoteStatus on each post row tell your pipeline
exactly why a given post's conversation is thin, instead of leaving you to guess.
🚀 How to scrape X (Twitter) (step by step)
- Open X (Twitter) User Profile & Tweets Scraper + Reply Threads on its Apify Store listing and click Try for free (or Run, if you already have it saved).
- Provide the required input —
startUrls, an array of profile URLs,@handles, bare handles, or numeric user IDs. This is the only required field. - Set the entity scope: leave
scrapeReplyThreadsandincludeQuoteTweetson for the full conversation walk, or turn them off for post-only runs; adjustmaxTweets,maxRepliesPerTweet, andmaxQuoteTweetsPerTweetto the volume you want. - Start the run from the Apify Console, or trigger it programmatically with
apify_client, an Apify schedule, or a webhook. - Download the results as JSON, CSV, Excel, or any format the Apify dataset export supports, or stream them via the API while the run is still going.
What to do when X (Twitter) changes its structure
The Actor re-discovers X's current GraphQL query IDs live from X's own JS bundle at the start of each run instead of hard-coding them, and it parses X's "features cannot be null" responses to add newly required feature flags automatically. Output field names and types stay stable on your end, so downstream integrations keep working without a rewrite. No specific turnaround time is promised for platform changes outside this self-healing.
🔄 What changed in X (Twitter) scraping recently?
Two things tightened in 2026. On the official API side, X discontinued the free developer tier and made pay-per-use pricing the default for new signups from February 6, 2026, migrating remaining legacy Basic subscribers onto the same metered plan starting June 1, 2026 (per 2026 X API pricing trackers, checked 2026-08-04). On the anti-bot side, X has been reported moving its login wall and rate-limited endpoints onto Cloudflare's Turnstile challenge as of March 2026 (per scrapeops.io, checked 2026-08-04), layering browser fingerprinting on top of the login wall it rolled out across the site in 2023. For DIY scripts, that means credential and fingerprint churn stacked on the wall itself. For this Actor's users, replies, quote posts, and keyword search already assume a login-gated surface — verified live on 2026-08-02, those three answer HTTP 404 with an empty body to logged-out clients — while post-only runs keep working with no session at all, since the guest-token timeline path remains open.
⬇️ Input
startUrls is the only required field; every other parameter has a default.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
startUrls | Yes | array of strings | Profile URL, @handle, bare handle, numeric user id, or a search phrase/hashtag. Profile targets run logged out; keyword targets are X search and need the session cookies below. Default ["https://x.com/NASA", "@apify"]. | ["https://x.com/NASA", "@apify"] |
maxTweets | No | integer (1–100) | Timeline posts to keep per target — parents only, replies and quotes have their own caps. Default 10. | 10 |
sortOrder | No | string, enum newest/oldest/popular | Order applied to fetched posts before the cap is applied. Default "newest". | "newest" |
withReplies | No | boolean | OFF removes posts that are themselves replies written by the scraped profile. Default true. | true |
includeUserInfo | No | boolean | Attaches the nested user profile object to post, reply and quote rows. Default true. | true |
scrapeReplyThreads | No | boolean | Walks each post into its conversation; needs the session cookies below. Default true. | true |
maxRepliesPerTweet | No | integer (0–200) | Reply rows kept per post. 0 = everything X serves, up to the 200 ceiling. Default 25. | 25 |
replyDepth | No | integer (1–3) | 1 direct replies only, 2 also the nested replies X ships inline, 3 one extra request per answered reply. Default 2. | 2 |
threadRankingMode | No | string, enum relevance/recency | Which replies X serves first when the cap cuts the thread short. Default "relevance". | "relevance" |
minRepliesToFetch | No | integer (0–100000) | Skip posts with fewer replies than this, read from the post's own counter before any request. Default 1. | 1 |
followHiddenReplies | No | boolean | Follows the "show more replies" cursors X puts behind hidden branches. Default true. | true |
includeQuoteTweets | No | boolean | Runs one X search per post for posts that quoted it. Default true. | true |
maxQuoteTweetsPerTweet | No | integer (0–50) | Quote rows kept per post; 0 skips the quote search entirely. Default 10. | 10 |
authToken | No | string (secret) | auth_token cookie from a logged-in x.com tab. Required for replies, quote posts, and keyword search. No default. | "a1b2c3..." |
ct0 | No | string (secret) | ct0 cookie (CSRF token) from the same session as authToken. No default. | "9f3a7c..." |
proxyConfiguration | No | object | Proxy attached to every outbound request, including guest-token activation and query-id discovery. Default {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}. | {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]} |
Example input, all parameters shown:
{"startUrls": ["https://x.com/NASA", "@apify"],"maxTweets": 10,"sortOrder": "newest","withReplies": true,"includeUserInfo": true,"scrapeReplyThreads": true,"maxRepliesPerTweet": 25,"replyDepth": 2,"threadRankingMode": "relevance","minRepliesToFetch": 1,"followHiddenReplies": true,"includeQuoteTweets": true,"maxQuoteTweetsPerTweet": 10,"authToken": "","ct0": "","proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"]}}
⚠️ Common pitfall: leaving authToken and ct0 empty and still expecting reply, quote,
or keyword-search rows. Those three surfaces answer HTTP 404 with an empty body to
logged-out clients, so a keyless run silently returns post rows only — every post row
carries threadSkippedReason: "auth_required" so you can see why, rather than assuming the
post had no replies.
⬆️ Output
Every run pushes typed, normalized JSON rows to one Apify dataset — no HTML, no per-field
parsing. Export as JSON, CSV, Excel, or any format the dataset API supports. rowType
distinguishes the three shapes below; isChild and parentId link a reply or quote back to
its post. If includeUserInfo is off, the user object is omitted from every row rather
than being sent as null.
Scraped post (rowType: "tweet")
{"id": "1948213340098213888","url": "https://x.com/NASA/status/1948213340098213888","verified": true,"username": "@NASA","fullname": "NASA","timestamp": "Fri Jul 31 21:25:11 +0000 2026","postedAt": "2026-07-31T21:25:11Z","text": "New images from the James Webb Space Telescope reveal...","links": ["https://science.nasa.gov/mission/webb"],"isPinned": false,"isQuote": false,"isRetweet": false,"isReply": false,"likes": 8421,"replies": 297,"retweets": 1520,"quotes": 63,"views": 512034,"user": {"avatar": "https://pbs.twimg.com/profile_images/example_normal.jpg","username": "NASA","userFullName": "NASA","description": "Explore the universe and discover our home planet.","location": "","website": "https://www.nasa.gov","url": "https://t.co/abc123","joinDate": "Wed Dec 19 20:20:32 +0000 2007","verified": true,"verifiedType": "Business","totalLikes": 5123,"totalTweets": 76210,"totalFollowing": 320,"totalFollowers": 96500000,"totalMediaCount": 15340,"userId": "11348282"},"media": [{"type": "photo", "url": "https://pbs.twimg.com/media/example.jpg"}],"tweetUserId": "11348282","retweetedFrom": null,"originalTweetId": null,"isPinnedPost": false,"retweetSource": null,"rowType": "tweet","isChild": false,"parentId": null,"parentUrl": null,"replyDepth": 0,"conversationId": "1948213340098213888","bookmarks": 940,"lang": "en","inReplyToId": null,"inReplyToUsername": null,"isLongForm": false,"fullTextLongForm": null,"targetInput": "https://x.com/NASA","targetType": "username","threadFetched": true,"threadStatus": "ok","threadSkippedReason": null,"repliesClaimed": 297,"repliesCollected": 25,"replyRecoveryRatio": 0.0842,"uniqueReplyAuthors": 24,"deepestReplyDepth": 2,"threadPagesFetched": 3,"promotedRepliesSkipped": 1,"quoteTweetsCollected": 10,"quoteStatus": "ok"}
Scraped reply (rowType: "reply")
Reply rows carry the same base columns as a post row (minus the thread roll-up stats, which
live only on the post row they belong to), plus parentId, parentUrl, and replyDepth.
{"id": "1948214001233456789","url": "https://x.com/spacefan42/status/1948214001233456789","verified": false,"username": "@spacefan42","fullname": "Space Fan","timestamp": "Fri Jul 31 21:40:02 +0000 2026","postedAt": "2026-07-31T21:40:02Z","text": "@NASA This is incredible, thank you for sharing!","links": [],"isPinned": false,"isQuote": false,"isRetweet": false,"isReply": true,"likes": 12,"replies": 1,"retweets": 0,"quotes": 0,"views": 480,"user": {"avatar": "https://pbs.twimg.com/profile_images/example2_normal.jpg","username": "spacefan42","userFullName": "Space Fan","description": "Amateur astronomer.","location": "Ohio","website": null,"url": null,"joinDate": "Mon Mar 03 14:02:10 +0000 2014","verified": false,"verifiedType": null,"totalLikes": 22140,"totalTweets": 5310,"totalFollowing": 640,"totalFollowers": 812,"totalMediaCount": 210,"userId": "998877665"},"media": [],"tweetUserId": "998877665","retweetedFrom": null,"originalTweetId": null,"isPinnedPost": false,"retweetSource": null,"rowType": "reply","isChild": true,"parentId": "1948213340098213888","parentUrl": "https://x.com/NASA/status/1948213340098213888","replyDepth": 1,"conversationId": "1948213340098213888","bookmarks": 0,"lang": "en","inReplyToId": "1948213340098213888","inReplyToUsername": "NASA","isLongForm": false,"fullTextLongForm": null,"targetInput": "https://x.com/NASA","targetType": "username"}
Scraped quote post (rowType: "quote")
Quote rows share the same shape as a reply row, except replyDepth is always null — a
quote post lives outside the conversation and isn't a reply.
{"id": "1948220112233445566","url": "https://x.com/newsdesk/status/1948220112233445566","verified": true,"username": "@newsdesk","fullname": "News Desk","timestamp": "Fri Jul 31 22:05:47 +0000 2026","postedAt": "2026-07-31T22:05:47Z","text": "NASA just dropped the clearest Webb images yet -- thread below","links": ["https://x.com/NASA/status/1948213340098213888"],"isPinned": false,"isQuote": true,"isRetweet": false,"isReply": false,"likes": 340,"replies": 18,"retweets": 52,"quotes": 3,"views": 21500,"user": {"avatar": "https://pbs.twimg.com/profile_images/example3_normal.jpg","username": "newsdesk","userFullName": "News Desk","description": "Science and space news.","location": "New York, NY","website": "https://newsdesk.example.com","url": "https://t.co/xyz789","joinDate": "Tue Jan 08 09:15:00 +0000 2013","verified": true,"verifiedType": "Business","totalLikes": 41230,"totalTweets": 98211,"totalFollowing": 210,"totalFollowers": 154000,"totalMediaCount": 6210,"userId": "445566778"},"media": [],"tweetUserId": "445566778","retweetedFrom": null,"originalTweetId": null,"isPinnedPost": false,"retweetSource": null,"rowType": "quote","isChild": true,"parentId": "1948213340098213888","parentUrl": "https://x.com/NASA/status/1948213340098213888","replyDepth": null,"conversationId": "1948220112233445566","bookmarks": 22,"lang": "en","inReplyToId": null,"inReplyToUsername": null,"isLongForm": false,"fullTextLongForm": null,"targetInput": "https://x.com/NASA","targetType": "username"}
threadStatus is one of not_requested, skipped, ok, or failed; threadSkippedReason
is one of auth_required, below_min_replies, no_replies, rate_limited,
fetch_failed, or null; quoteStatus is one of not_requested, auth_required,
rate_limited, ok, or failed. Repost rows carry the original post's content and
author throughout — retweetedFrom names the account that reposted it, and
originalTweetId is the original post's id.
🆚 How does this scraper compare to other X (Twitter) scrapers?
| Feature | This scraper | Generic alternative |
|---|---|---|
| Replies as their own dataset rows | ✅ rowType: "reply", linked by parentId | ❌ Usually returns only the post's own reply count, not the reply content |
| Quote posts included | ✅ rowType: "quote", one search per post | ❌ Typically out of scope; needs a second tool |
| Reply/quote budgeted separately from posts | ✅ Raising maxRepliesPerTweet never costs post rows | ❌ Commonly a single shared item cap across everything |
| Honest partial-result reporting | ✅ replyRecoveryRatio, threadStatus, threadSkippedReason on every post | ❌ Usually silent — an empty thread looks identical to "no replies exist" |
| Works without login for post data | ✅ Profile timelines run on X's guest-token flow | Varies by tool |
If you're building an AI agent or RAG pipeline, the "replies as their own rows" row is the decision-maker — reconstructing a conversation tree from a bare reply count inside an agent loop is not something you can do at all, let alone reliably.
🔢 How many results can you scrape with this scraper?
There is no single result cap — the ceiling is per-post and per-target. maxTweets tops out
at 100 posts per target (X's own limit on this surface, matched by the schema's maximum).
Under each kept post, maxRepliesPerTweet caps out at 200 reply rows and
maxQuoteTweetsPerTweet at 50 quote rows, so one target can yield up to
100 × (1 + 200 + 50) = 25,100 rows in the extreme case, before withReplies and
minRepliesToFetch filtering.
Pagination runs as cursor walks under the hood: the profile timeline fetches up to 6 pages
of 40 raw posts before applying your sort and cap; the conversation walk under each post
fetches up to 12 pages of replies; the quote-post and keyword-search surfaces fetch up to 5
pages of 20. Reply depth 3 additionally re-queries up to the first 10 answered replies per
post to pull their own children. startUrls accepts multiple targets in one run, and totals
scale linearly with how many you provide. No benchmark timing is published — actual
throughput depends on X's live rate-limit state at the moment you run.
🔌 Integrate this scraper and automate your workflow
This scraper works with any language or tool that can send an HTTP request.
REST API integration
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_API_TOKEN>")run = client.actor("x-twitter-user-profile-and-tweets-scraper-and-reply-threads").call(run_input={"startUrls": ["https://x.com/NASA"],"maxTweets": 10,"scrapeReplyThreads": True,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["rowType"], item.get("username"), item.get("text"))
Works in Python, Node.js, Go, Ruby, cURL — any client that can call the Apify API with your token.
Automation platforms (n8n, Make)
Apify publishes official integrations for both Make and n8n (apify.com/integrations, checked 2026-08-04): add the Apify module in a Make scenario, or the Apify node in an n8n workflow, point it at this Actor, pass your input as JSON, and the resulting rows land directly in the next step of your automation — no custom code required.
⚖️ Is it legal to scrape X (Twitter)?
Scraping publicly accessible data is generally lawful. This scraper returns only data X serves publicly — or to the session cookie you personally supply — including profile bios, post text, engagement counts, and the same for replies and quote posts. Because that includes personal data about identifiable people (usernames, display names, bios, locations, follower counts, join dates), collecting and storing it falls under data protection law such as the EU GDPR and the US CCPA/CPRA wherever those regimes apply to you or the people in your dataset. Scraping public data isn't itself prohibited by these laws, but you need a lawful basis for storing and using it, should honor data-subject rights (access, deletion, objection) on request, and shouldn't retain more than your purpose requires. X's own Terms of Service separately govern your use of its platform. Consult legal counsel for commercial use cases involving bulk personal data.
❓ Frequently asked questions
Does this scraper work without an X (Twitter) account?
Partially. Profile timelines and post rows run fully logged out over X's guest-token flow —
no account needed. Replies, quote posts, and keyword search need authToken + ct0
cookies from a logged-in x.com session; X answers those three surfaces with HTTP 404 and an
empty body to logged-out clients (verified live 2026-08-02).
How often is the scraped data updated?
Every run fetches live from X at request time. There's no cache — each run reflects whatever X's guest-token or authenticated GraphQL endpoints return at that moment.
What happens if a profile is suspended or a post is deleted?
If a profile can't be resolved (suspended, renamed, or non-existent), the run logs the
failure for that target and continues with the rest of startUrls. If a post's conversation
returns nothing, the post row still gets pushed, with threadStatus and
threadSkippedReason explaining why (no_replies, rate_limited, fetch_failed, etc.)
instead of the row silently looking like the post had no replies.
Can I scrape private or protected X accounts?
No. Only content the guest-token flow or your supplied session can see is returned — protected/locked accounts and content restricted to followers are not accessible.
What happens if my X session cookies expire or are invalid?
The reply, quote, and search surfaces raise an "unauthorised" error for that call and the
affected post rows record it via threadStatus/threadSkippedReason rather than crashing
the run; post rows keep flowing regardless, since they don't need the session at all.
Does this scraper work for AI agent workflows and LLM pipelines?
Yes. It's callable as an HTTP endpoint via the Apify API or apify_client from any agent
framework. Every row is typed JSON with stable field names — no HTML, no parsing step
before you pass it to an LLM.
How does this scraper handle X (Twitter)'s anti-bot system?
Requests run over curl_cffi with Chrome TLS impersonation (chrome131), because X answers
plain-TLS clients differently than real browsers. Apify Residential proxy is wired in by
default. The Actor reads X's own x-rate-limit-remaining / x-rate-limit-reset headers and
backs off for up to 90 seconds with one retry on HTTP 429 instead of hammering the same
window, and it re-discovers X's current GraphQL query IDs live from X's own JS bundle each
run, falling back to pinned IDs only if live discovery fails.
How does this scraper compare to other X (Twitter) scrapers?
Most generic Twitter/X scrapers return only a profile's own posts. Turning each post into a
reply tree with quote posts and honest recovery stats (repliesClaimed vs
repliesCollected) typically means stitching together a second tool or hand-rolled
pagination. This Actor keeps posts, replies, and quote posts budgeted separately in one run
and one dataset.
Does this scraper return data in a format LLMs can use directly?
Yes — typed, normalized JSON with stable field names across all three row types. Pass it directly into an LLM context window, index it into a vector store, or route it through an agent tool without a parsing step.
Can I use this scraper without managing proxies?
Yes. Apify Residential proxy is configured by default via proxyConfiguration and rotated
automatically per request; you can swap in your own proxy groups through the same field, but
residential is the default because X answers datacenter IP ranges inconsistently.
What happens when X (Twitter) changes its structure or blocks the scraper?
The Actor re-discovers X's GraphQL query IDs and required feature flags live at the start of each run rather than hard-coding them, so it keeps working as X rotates them. Output field names and types stay stable on your end. No numeric turnaround time is promised for platform-side changes.
💬 Your feedback
Found a bug or missing a field? We want to know. Open an issue or a message through the Actor's page on the Apify Store, or use the Console's built-in support/issue link on the run page — reports get triaged against the live X payload, not against a stale schema.