> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xquik.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Xquik changelog: Twitter API & scraper updates

> Track Xquik REST, MCP, SDK, tweet search, follower export, monitor, webhook, extraction, account action, and contract changes. Newest changes come first.

<blockquote className="agent-llms-directive">
  For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
</blockquote>

Search tweets, API keys, signed webhooks, user profiles, REST, MCP, authentication, billing, and writes all appear in this changelog.

<Update label="October 2026" description="v1">
  **New**

  * The 6 analysis endpoints take `baseline`: the rows of an earlier answer. Each result's `monitor` says whether the post is new, changed or unchanged. The comparison costs nothing extra

  * Score answers, such as `intensity` or `conviction`, can have decimals between levels

  * 6 AI analysis endpoints read X posts, searches or your own texts. Each analyzed post costs 2 credits

  * `POST /x/analysis/sentiment` answers each post's attitude, its intensity & its sarcasm probability

  * `POST /x/analysis/brand` answers each post's relevance, attitude & customer relationship for your brand

  * `POST /x/analysis/news` answers each post's format, source attribution & relevance to your topic

  * `POST /x/analysis/market-signals` answers each post's stance on an asset & counts bullish & bearish posts per cashtag

  * `POST /x/analysis/viral-score` rates how viral a post or draft reads, from 0 to 100, with a verdict

  * `POST /x/analysis/classify` answers up to 8 questions you write: categories, scores or yes/no

  * A search can name an account in `username`, a List in `listId`, or a post in `quotesOf` or `repliesTo`, between `sinceTime` & `untilTime`

  * A post without an analysis costs nothing. MCP lists all 6, and guest keys can call them

  * `GET /x/articles/{tweetId}` adds `bodyMarkdown`: the Article body as Markdown

  * It keeps headings, lists, bold, italic, links & images, without HTML. It costs nothing extra

  * Search rows add `textHighlights`: where the row's `text` matches the search

  * Each range has `startIndex` & `endIndex`, counted in code points of `text`. It costs nothing extra

  * `GET /x/users/batch/tweets` returns the newest posts of up to 20 users in 1 call

  * Name the users by `ids` or `usernames`. It costs 1 credit per post

  * A user it could not read is named in `unprocessed_ids` & costs nothing

  * MCP adds it as `getBatchUserTweets`, and guest keys can call it

  * `GET /x/communities/find` finds X Communities by keyword. It costs 1 credit per Community

  * `GET /x/communities/popular` lists the most popular Communities of a topic or subtopic

  * Send the topic by `topicId` or by name as `topic`. It costs 1 credit per Community

  * `GET /x/communities/topics` lists every Community topic & subtopic, 1 credit per topic

  * `GET /x/communities/suggested` lists the Communities X suggests to join, 1 credit each

  * `GET /x/communities/{id}/media` returns a Community's Media tab, 1 credit per post

  * `GET /x/communities/{id}/tweets` takes `queryType=Top` for the Community's Top posts

  * Community responses add `banner`, with its size, main colors & focus area

  * MCP adds `findCommunities`, `getPopularCommunities`, `getCommunityTopics`, `getSuggestedCommunities` & `getCommunityMedia`, and guest keys can call them

  * Community find & popular answer a free 400 `invalid_cursor` when X refuses a cursor

  * `GET /x/tweets/{id}/retweeters/check` says whether 1 account reposted a post

  * It reads the account's newest posts. Each check costs 1 credit

  * MCP adds it as `getTweetRepostCheck`, and guest keys can call it

  * `GET /x/users/{id}/affiliates` returns the accounts an organization lists as its affiliates, in X's order

  * Each row is a full profile. It costs 1 credit per result

  * MCP adds it as `getUserAffiliates`, and guest keys can call it

  * `GET /x/users/{id}/subscriptions` returns the creators a user subscribes to, in X's order

  * Each row is a full profile. It costs 1 credit per result

  * MCP adds it as `getUserSubscriptions`, and guest keys can call it

  * `GET /x/users/{id}/follower-ids` and `GET /x/users/{id}/following-ids` return user IDs only

  * A page holds up to 5,000 IDs, newest first. Each ID costs 1 credit

  * MCP adds them as `getUserFollowerIds` and `getUserFollowingIds`, and guest keys can call them

  * `GET /x/tweets/{id}/hidden-replies` returns the replies a post's author hid, oldest first

  * It lists replies to hidden replies too. It costs 1 credit per reply

  * MCP adds it as `getTweetHiddenReplies`, and guest keys can call it

  * `GET /x/tweets/{id}/translation` returns X's own translation of a tweet into the language you pick

  * It returns the detected source language and the links of the translated text. It costs 1 credit per call

  * MCP adds it as `translateTweet`. Guest keys and direct MPP can call it

  * `GET /x/tweets/{id}/embed` returns the HTML that embeds a tweet on a website, in a light or dark theme

  * It can hide media and the thread, and leave the widget script out. It costs 1 credit per call

  * MCP adds it as `getTweetEmbed`. Guest keys and direct MPP can call it

  * `GET /x/links/resolve` returns where up to 100 t.co links lead, in the order sent

  * It costs 1 credit per resolved link. A link X does not answer for comes back in `unprocessedUrls`, free

  * MCP adds it as `resolveLinks`, and guest keys can call it

  * `GET /x/tweets` takes tweet URLs beside tweet IDs in `ids`, and reads a tweet named twice once

  * `GET /x/followers/check` takes user IDs beside usernames, and returns `sourceId` & `targetId`

  * `GET /x/tweets/{id}/subtitles` returns the caption tracks of a tweet's videos, with timed cues & the full text

  * It costs 1 credit when a track comes back. A tweet without captions costs nothing

  * MCP adds it as `getTweetSubtitles`, and guest keys can call it

  * `GET /x/users/{id}/similar` lists the accounts X shows as similar to a profile, in X's order

  * It costs 1 credit per account. MCP adds it as `getSimilarUsers`, and guest keys can call it

  * X can list slightly different accounts on each call. Xquik now returns a fuller, steadier list

  * `GET /x/users/{id}/articles` lists the X Articles a profile published, newest first

  * Each row is the Article's post with its title, preview & cover. It costs 1 credit per post

  * MCP adds it as `getUserArticles`, and guest keys can call it

  * `GET /x/users/{id}/highlights` returns the posts on a profile's Highlights tab

  * Rows keep X's order. It costs 1 credit per post returned

  * MCP adds it as `getUserHighlights`, and guest keys can call it

  * `GET /x/trends/locations` lists the places X offers trends for

  * Each location has its `woeid`, country, country code & place type

  * `country`, `placeType`, `q` & `limit` filter the list. It costs 1 credit per location

  * MCP adds it as `getXTrendLocations`

  * `GET /x/search/autocomplete` returns the accounts, topics, hashtags & cashtags X suggests for a query

  * `types` keeps only the kinds you choose. `limit` caps the suggestions

  * Cashtags carry price, market cap & 24-hour change. It costs 1 credit per suggestion

  * MCP adds it as `autocompleteSearch`

  * `GET /x/lists/search` finds public Lists by keyword, at 1 credit per List

  * Each List has its counts, banner & owner profile. Private Lists stay out

  * MCP adds it as `searchLists`, and the SDKs as `lists.retrieve_search`

  * `GET /x/users/{id}/lists` returns the public Lists an account created, in X's order

  * `GET /x/users/{id}/list-memberships` returns the public Lists that include an account

  * Each List costs 1 credit. MCP adds them as `getUserLists` & `getUserListMemberships`

  * `GET /x/spaces/search` finds public Spaces by keyword, host or topic, at 1 credit per Space

  * It returns live, scheduled & ended Spaces, each once per page. MCP adds it as `searchSpaces`

  * Space search takes `pageSize`, the posts a page reads: 1 to 100, default 20

  * `GET /x/spaces/{id}` returns 1 Space with its state, times, listener counts, hosts & speakers

  * It takes a Space ID or URL & costs 1 credit per call. MCP adds it as `getSpace`

  * `GET /x/spaces/{id}/replay` returns an ended Space's recording as an HLS playback URL

  * A live or scheduled Space answers 409. It costs 1 credit per call. MCP adds it as `getSpaceReplay`

  * A Space & each Space search row add `sharings`, the posts shared in the Space

  * Each sharing has the post, the account that shared it & when

  * A Space cancelled before it started answers 404 `space_canceled` on its replay

  * `GET /x/broadcasts/{id}` returns 1 X live video with its title, state, times & watch counts

  * It takes a broadcast ID or URL & costs 1 credit per call. MCP adds it as `getBroadcast`

  * Guest keys & direct MPP can call it. Reading a broadcast adds no view to it

  * A broadcast adds `tweetId` & `tweet`, the post that announces it

  * A Space & each Space search row add `tweet` beside `tweetId`

  * Job search answers a free 400 `invalid_cursor` when X refuses a cursor

  * `GET /x/tweets/{id}/retweeters` answers the same free 400 `invalid_cursor`

  * `GET /x/jobs/search` searches public X job listings by keyword

  * Filter by location, work type, seniority, employment type & company

  * Each job returned costs 1 credit. A closed job is left out & free

  * `GET /x/jobs/{id}` returns 1 job with its description as text & Markdown

  * `GET /x/jobs/locations` finds places & the location ID job search takes

  * MCP adds `searchJobs`, `getJob` & `getJobLocations`, and guest keys can call them

  * `GET /x/places/search` finds X places by name, at 1 credit per place

  * Each place has the `id` that tweet search takes as `place`

  * `GET /x/hashflags` lists the custom emoji X shows after hashtags, at 1 credit each

  * `q` & `activeOnly` filter the hashflags. Each has its image & the time it runs

  * MCP adds them as `searchXPlaces` & `getXHashflags`, and guest keys can call both

  **Changed**

  * `descriptionMarkdown` on `GET /x/jobs/{id}` numbers ordered lists 1, 2, 3 and keeps line breaks

  * It escapes characters that would read as Markdown or HTML, such as `[`, `*` & `<`

  * `GET /x/communities/{id}/tweets` opens its first page with the pinned post, flagged `isPinned`

  * `GET /x/communities/suggested` asks up to 2 more times when X suggests none. An empty list stays free

  * `GET /x/trends` takes a `country` or a `location` name, such as `location=Istanbul`

  * The response returns the place it read as `location`. `woeid` still wins

  * A write's `402` adds `top_up_url` & `dashboard`, which say where to add credits

  * `404 user_not_found` adds `reason`: `not_found` or `suspended`

  * A suspended account answers "X suspended this account. Choose another account."

  * Account responses add `connectedAt`, when the account last connected or reconnected

  * `X-Xquik-Busy-Reason` is now `admission` or `reads`

  * `GET /x/users/batch` takes `usernames` in place of `ids`, with or without `@`

  * Send up to 100 usernames. The ID lists then name the usernames as sent

  * `usernames` also takes profile links, such as `x.com/nasa`. A link is named by its username

  * The text `undefined` or `null` in `usernames` now answers 400 & costs nothing

  * A filtered `Latest` Tweet search adds `readBackTo`, how far back it has read

  * 7 account lists now page with a cursor instead of stopping at 100 or 200 rows

  * They are monitors, keyword monitors, webhooks, webhook deliveries, API keys, styles & support tickets

  * Each takes `limit` & `cursor`, and answers `hasMore` & `nextCursor`

  * A 1st page keeps its size & order, so existing clients see the same rows

  * Xquik keeps queued events until all deliveries finish

  * Events expire 30 days after Xquik creates them

  * `GET /credits` adds `auto_topup_stopped` & `GET /account` adds `creditInfo.autoTopupStopped`

  * `true` means 3 declined charges in a row on one card stopped automatic top-up

  * An event keeps the monitor label from when Xquik created it

  * Renaming a monitor no longer changes past events or their retries

  * Each retry of a webhook delivery sends its first attempt's exact body

  * Tweet & DM `text` now reads as x.com shows it

  * X's `&amp;`, `&lt;` & `&gt;` arrive as `&`, `<` & `>`

  * `displayTextRange` & entity `indices` count the decoded text

  * A repost row now shows its original post's counts, as x.com does

  * That covers likes, replies, reposts, quotes, bookmarks & views

  * X's own repost counts were 0, apart from reposts & a smaller view count

  * Tweet search reads `since:`, `until:`, `sinceDate` & `untilDate` as UTC days

  * x.com uses your time zone, so its day edges can differ

  * `untilDate` is inclusive: `untilDate=2026-03-01` returns that day's posts too

  * Followers come newest first. x.com puts some promoted followers first

  * A reply read with `sinceTime` & `scope=direct` stops X's newest-first view once it is past your window

  * `diagnostic.strategiesAttempted[].stopReason` says `window_passed` for that view

  * Once that view & both window searches end, other views stop with `window_covered`

  * Such a read ends sooner, with `sourcesEnded: true`

  * Tweet search drops `include:replies`, which X refuses. Search shows replies anyway

  * It reads `include:retweets` as `include:nativeretweets`

  * `searchedQuery` then shows the query X searched

  * A write retried with the same `Idempotency-Key` returns the first answer again

  * It keeps the first status, body & `Retry-After`, with `idempotent: true` added

  * A rejected post's retry now answers `422` like the first answer, not `200`
</Update>

<Update label="September 2026" description="v1">
  **New**

  * `DELETE /x/dm/{userId}/messages/{messageId}` deletes a DM from your account's side

  * The other person keeps it. It costs 10 credits, only when X deletes it

  * MCP adds it as `deleteDm`, and the SDKs as `dm.delete_message`

  * Profiles add `accountBasedInUnavailable: true` when X withholds `accountBasedIn` from a read

  * Those profiles omit `accountBasedIn`. Treat the label as unknown & retry later

  * `accountBasedIn: null` still means X shows no label

  **Changed**

  * Native MCP adds `readSavedResult`, which reads a saved oversized answer in free pages

  * Oversized answers up to the 2 MiB MCP response limit now save, up from 256 KB

  * An oversized answer's `retry` names only tools your MCP catalog lists

  * Tweet search drops an unmatched quote, which X refuses, & returns rows

  * `searchedQuery` then shows the query X searched

  * A search X refuses returns `424 search_unavailable`, never an empty page

  * User Tweets, user replies, quotes & List Tweets list `keywords`, `place`, `placeCountry`, `pointRadius`, `boundingBox` & `advancedQuery`

  * User Tweets, user replies & quotes also list `listId`, and Tweet search lists `keywords`

  * A user timeline with a search filter such as `keywords` filters every Tweet, not only older ones

  * `max_results` sets the page size wherever `limit` & `count` do

  * `maxItems`, `max_items` & `per_page` set it too

  * Tweet search `queryType` takes any case & the aliases `type`, `search_type`, `product`, `category` & `section`

  * `Photos`, `Videos` & `Media` search `Latest` with that media type. `People` & `Lists` answer 400 with the route to use

  * Direct replies stop listing 8 search filters they never applied

  * Those are `cardName`, `source`, `excludeSource`, `geocode`, `near`, `within`, `safe` & `news`

  * List Tweets & direct replies take the legacy `after` cursor alias on every page

  * Community search applies `withinTime`

  * Events prefer `monitorId` to `monitor_id`. A monitor filter without a usable ID lists no events

  * A cursor ignores parameters its route doesn't read, so dropping one keeps it

  * A post X never published fails as `x_post_not_sent`. You pay nothing & can post again

  * Writes X never confirms end `expired` & charge nothing. Check your X account before you retry

  * X's 500, 504 & 408 after the send keep a write `pending_confirmation` as `x_write_ambiguous`

  * Pending answers say `retryable: false`

  * Before the send, those give `x_transient_error` & are safe to retry, not `x_write_failed`

  * X refusals that state a reason return `422 x_rejected`. They used to return `500 x_write_failed`

  * X's refusal of an image's size returns `422 x_image_invalid`

  * Avatar & banner uploads take images up to 15 MiB. Xquik fits them to X's limits

  * Post images over 5 MiB shrink to fit. GIFs & videos go to X unchanged

  * An unreadable image returns `415 unsupported_media_type`

  * An image Xquik can't shrink enough returns `413 media_too_large`

  * OpenAPI lists 413 & 415 on media writes, plus 3 media error codes

  * Post & user path params take URLs & handles. See [path IDs](/api-reference/overview#path-ids)

  * Post params take a post ID or an x.com or twitter.com post URL

  * User params take a user ID, a username with or without `@`, or a profile URL

  * Writes look up a username first. An unknown username returns `422 x_target_not_found`

  * Other input returns `400 invalid_tweet_id` or `400 invalid_user_id`

  * `GET /x/users/{id}` returns `invalid_user_id` where it returned `invalid_username`

  * Writes X refuses outright return `422 x_rejected` & charge nothing

  * `POST /x/communities` returns `422 x_account_feature_required` when the account can't create communities

  * Both used to look like unconfirmed writes

  * MCP `execute` takes paths with or without `/api/v1`, such as `/x/users/nasa/follow`

  * `GET /x/users/{id}/tweets` & `GET /x/users/{id}/replies` now list `sinceTime`, `untilTime` & `mode`

  * Both routes already applied them. `sinceTime` keeps its exact second & `untilTime` drops it

  * A time without an offset reads as UTC on every route that takes these bounds

  * An offset whose `+` arrived unencoded, such as `21:20:41 02:00`, reads as `+02:00`

  * Community Tweets, List Tweets, thread & batch users now list every filter they applied

  * Quotes list `includeReplies`, and bookmark folders list `cursor`

  * Likes, media & mentions drop search operators such as `cardName`. They never applied them

  * Replies to a post that is unavailable on X return `422 x_reply_target_unavailable`

  * Some used to return `500 x_write_failed`

  * Xquik sends nothing & charges nothing. Check the post on x.com or reply to another post

  * `GET /draws`, `GET /drafts` & `GET /events` return `400 invalid_input` for an unknown cursor

  * Before, they returned the first page again

  * Send the last `nextCursor` you received, or omit the cursor to start over

  * An empty cursor still returns the first page

  * Replies, quotes, retweeters & thread of a post X does not have return `404 tweet_not_found`

  * They used to return 200 with an empty page. `GET /x/tweets/{id}` already returned this 404

  * Only an empty first page checks the post. A post without engagement still returns 200

  * A 404 costs no credits

  * Each account now gets 500 reads a second, up from 300

  * Writes still allow 120 a minute & deletes 60 a minute

  * `429 x_rate_limited` messages now name the wait from `Retry-After`, such as about 15 minutes

  * Without a known wait, the message says to try again later

  * Writes X refuses as possibly automated return `422 x_automation_refused`

  * They used to return `429 x_rate_limited`

  * Waiting does not change X's answer. Send the next request now with a new `Idempotency-Key`

  * If X keeps refusing, check the account on x.com. Vary your text or pace

  * These refusals cost nothing

  * `429 x_rate_limited` now covers only X's rate limits. Wait for `Retry-After` when present

  * `GET /x/tweets/{id}/replies` with `sort=latest` or `sort=oldest` sets `orderPartial: true` when some rows come from X views without date order

  * Rows stay sorted by date & keep the same status. Replies may be missing between them

  * Nothing marked such answers before. Retry later for a gap-free order

  * When X's Recent view ends early or comes back signed out, Xquik reads the rest from X search's Latest results

  * `GET /x/tweets/{id}/replies` applies `sort` on automatic pages too

  * Those pages used to list the newest replies first, whatever the `sort`

  * Without `sort`, automatic pages still list the newest first. Standard pages ignore `sort`

  * `POST /draws` reads every direct reply & retweeter X shows

  * It used to read X's first page of replies & at most 2,000 retweeters

  * Entries are direct replies to the post. Replies to other replies no longer enter

  * A draw on a busy post takes about 1 minute. Keep the request open for 100 seconds

  * `GET /x/tweets/{id}/retweeters` no longer ends the list early when X refuses a page

  * Xquik reads that page again

  * `POST /draws` returns `424` when X stops the reply or repost read early

  * It used to draw from the entries read so far

  * Retry after `replies_incomplete` or `retweeters_incomplete`

  * `draw_too_large` means the post has more entries than 1 draw reads. Contact support

  * Xquik saves & charges nothing for these draws

  * Bookmark folder reads on accounts without X Premium return `424 bookmark_folders_unavailable`

  * This covers `GET /x/bookmarks/folders` & `GET /x/bookmarks?folderId=...`

  * They used to return an empty list. The message says to upgrade on X or read all bookmarks

  * These answers cost nothing

  * Search Tweets returns `424 search_unavailable` at once for `filter:vine`, `filter:consumer_video`, `filter:pro_video`, `filter:news` & `retweets_of:`

  * X no longer searches these. `news=true` gets the same answer

  * The message says what to change, such as the term to remove

  * A query X refuses as a whole also gets `424 search_unavailable`, such as one over 512 characters

  * These answers cost nothing

  * Follower, following, verified follower, retweeter & user search pages take `enrichProfiles=true`

  * Each row then carries the full profile, with fields such as `accountBasedIn`

  * The `x-xquik-profile-enrichment` header counts the rows that carry it

  * Extractions of these rows take `enrichProfiles` & add the profile at `enrichmentData.profile`

  * The price per row stays the same

  * Complete-mode replies return 200 after reading a whole `sinceTime` or `untilTime` window

  * Replies outside the window no longer turn that answer into `424 replies_incomplete`

  * Complete-mode replies add `diagnostic.sourcesEnded`

  * `true` means every source ended. X hides the other replies

  * A `424 replies_incomplete` with `sourcesEnded: true` returns the same rows on retry

  * Its message says X hides the other replies instead of asking for a retry

  * Complete-mode replies find replies from new & small accounts more reliably

  * `diagnostic.strategiesAttempted[].stopReason` adds `partial_view` for a view that showed only part of a thread

  * Such a view keeps `sourcesEnded` false until the read holds every reply the post counts

  * `withinTime` now filters user Tweets, replies, media, likes & mentions

  * It also filters Tweet replies & quotes

  * Posts outside the window no longer come back or cost credits

  * Use a whole number & `s`, `m`, `h` or `d`, such as `90m` or `7d`

  * On these routes, other values return `400 invalid_input`

  * `GET /x/users/batch` returns the profiles it read when some IDs fail

  * IDs that failed to load come back in `failed_ids`. Retry them

  * Failed IDs cost nothing

  * Draws charge follow checks only for authors who pass your other filters

  * `POST /draws` accepts an optional `Idempotency-Key` header

  * An exact retry returns the original draw with `Idempotency-Replayed: true` & charges nothing

  * A retry while the first request runs returns `409 idempotency_in_progress`

  * Another body with the same key returns `409 idempotency_conflict`

  * A draw that fails its save or final charge stores nothing & charges nothing

  * The dashboard sends 1 key per draw, so a resubmit returns the saved draw

  * Webhook retries have no attempt limit. They continue until your endpoint returns `2xx`

  * `410 Gone` retries like any other failure

  * A failing endpoint gets 1 waiting delivery at a time, at least every 15 minutes

  * When that delivery succeeds, Xquik starts sending `pending` deliveries

  * Resume Webhook & `isActive: true` start sending waiting deliveries at once

  * Without them, a rejected delivery can wait up to 7 days after a fix

  * Only a paused or deleted webhook marks deliveries `exhausted`

  * Resume within 30 days of an event to receive its held delivery

  * Return `2xx` for deliveries you skip. A rejected one can delay new ones up to 15 minutes

  * Private reads use only your connected X account

  * They cover bookmarks, bookmark folders, notifications, home timeline, likes, likers & mutual followers

  * Without one, these routes return `424 account_required`

  * They return `503` while your connected X accounts are busy

  * `favoriters` & `user_likes` extraction jobs need a connected X account

  * Without one, the job fails with `errorMessage` set to `errorXAccountRequired`

  * Guest keys no longer cover likes, likers & mutual followers

  * Guest keys get `403 forbidden` on these 3 routes

  * Guest wallets now prepay 30 GET routes

  * Small conversation searches return more complete results by default

  * Reply Scraper 1.2.65 reports completion more accurately

  * Reply reads return more replies within your requested limit

  * Reply Scraper 1.2.64 recovers replies after a stall & keeps collected rows

  * Dated author searches with `include:nativeretweets` or `-filter:nativeretweets` return more complete results

  * Searches requiring protected authors return an access error before collecting results

  * Tweet Scraper 1.12.99 returns more Latest search results

  * Multi-author Tweet searches return more complete results

  * Pagination docs now explain cursor retries & first-page limits

  * Tweet search keeps exact ID boundaries across pages

  * `sinceId` excludes its ID. `maxId` includes its ID

  * MCP reports missing response-field reads without changing returned values

  * MCP search keeps response descriptions and date-only string types

  * Profile, list, and quote reads keep explicit reply filters

  * Image previews resize AVIF sources again

  * MCP search keeps shared response schemas in `spec.components.schemas`, reducing repeated contract data

  * Extraction results retain attached public media for mixed tweet, reply, quote, thread, and profile-media sources
</Update>

<Update label="August 2026" description="v1">
  **New**

  * Accountless guest wallets prepay 33 GET routes through a scoped `paid_reads` key
  * `POST /guest-wallets`, `GET /guest-wallets/status`, and `POST /guest-wallets/topups` support hosted checkout after confirmation without an account
  * Active guest keys expose the same 33-route read-only catalog through API MCP
  * OAuth discovery advertises claimed `service_auth` agents with revocable access tokens and identity assertions
  * API MCP v2.6.0 supports MCP `2026-07-28` through `server/discover`
  * Modern discovery and tool catalogs include private cache hints
  * `POST /compose` now returns 7 source-specific `radarRecommendations` with endpoints, use cases, and drafting guidance
  * Reddit Radar items now expose available post text, destination URLs, media, public engagement signals, estimated vote counts, and post state
  * `GET /x/account-connection-attempts/{id}` reports a tracked connection as pending, successful, failed, or waiting for an email code

  **Changed**

  * `GET /x/tweets/search` accepts `pageSize` as a `limit` alias
  * API MCP v2.6.58 gives `execute` calls 55 seconds of bounded wall time, documents compact result projection, and keeps completed request diagnostics after a timeout
  * `GET /x/accounts` supports cursor pages through `limit` and `cursor`
  * The best-practice contract paginates X accounts by default. Legacy responses retain up to 10,000 accounts
  * Extraction estimates and jobs now default `resultsLimit` to 10,000. Native MCP schemas retain OpenAPI defaults
  * API MCP v2.6.43 advertises immutable tool catalogs and disables change subscriptions
  * API MCP v2.6.42 adds OpenAPI-native tools at `https://xquik.com/mcp?codemode=false`. Code Mode remains the default
  * API MCP v2.6.41 removes the extraction row threshold from OpenAPI routing metadata
  * API MCP v2.6.40 uses `docs`, `search`, and `execute`. Tool descriptions contain mechanics, not endpoint choices
  * Modern MCP calls are request-scoped and require no initialization session
  * Stateless 2025-era MCP clients remain compatible at the same endpoint
  * Field guidance now documents REST naming exceptions and MCP normalization
  * Export guidance now separates file formats from downstream column selection
  * Account connection email-code challenges now return immediately as a resumable `202 requires_email_code` response
  * `POST /x/accounts` can return a durable `202 pending` response with `Location` and `Retry-After`. Follow that attempt instead of resending credentials
  * Account connection failures now expose the exact cooldown through `retryAfterMs` and `Retry-After`. Retry controls show a live countdown
  * Direct MPP now covers 7 fixed-price `charge` operations. Result-sized reads use guest or full account credits
  * Follow checks and article reads cost USD 0.00075 per direct MPP call
  * Every response after an accepted MPP payment includes `Payment-Receipt`, including non-2xx responses
  * The 26 non-MPP anonymous paid reads return `401` with `WWW-Authenticate: Bearer` and a guest wallet action
  * The 7 direct MPP reads return `402` with `WWW-Authenticate: Payment` and the same guest action
  * Reddit Radar now lists only items with full details
  * Startup growth Radar items now add founder, company, acquisition, margin, and revenue-efficiency fields when available
  * A successful Compose score now points to `GET /x/accounts` and `POST /x/tweets`, while retaining the one-click `intentUrl`

  **Removed**

  * Obsolete public account location fields
</Update>

<Update label="July 2026" description="v1">
  **Changed**

  * From July 21, 2026, X write endpoints require an `Idempotency-Key` header
  * Requests without it return `400 missing_idempotency_key`. Xquik does not charge them
  * A key that is not 1 to 255 visible ASCII characters returns `400 invalid_idempotency_key`
  * Send 1 unique key per intended write. Reuse it only to retry that same write
</Update>

<Update label="April 2026" description="v1">
  **New**

  * `POST /x/tweets` - added `media` field (1-4 image URLs). `text` is now optional when media is present
  * `POST /x/accounts/{id}/reauth` - added `email` parameter
  * `POST /x/media` - now accepts `image/webp` and `image/avif` (allowed: AVIF, GIF, JPEG, PNG, WebP, MP4)
  * `POST /x/accounts` and `POST /x/accounts/{id}/reauth` responses now include a `health` field (enum: `healthy`, `locked`, `needsReauth`, `recovering`, `suspended`, `temporaryIssue`). The same field now appears on `GET /x/accounts` list and detail responses
  * New error code `login_cooldown` (429) for `POST /x/accounts` and `POST /x/accounts/{id}/reauth`, with `reason` and `retryAfterMs` in the body and a `Retry-After` header
  * All 17 write endpoints (under `/x/tweets`, `/x/users`, `/x/dm`, `/x/profile`, `/x/media`, `/x/communities`) now document standardized error responses: `403 account_needs_reauth`, `403 account_restricted`, `422 write_rejected`, `429 rate_limited_by_x`, `503 transient_error`
  * `GET /radar` items now expose 15 metadata fields per source (was 8): `mrr`, `growthPercent`, `last30Days`, `total` (required), `customers`, `activeSubscriptions`, `onSale`, plus optionals `askingPrice`, `country`, `growthMrrPercent`, `multiple`, `paymentProvider`, `rank`, `category`, `xHandle`
  * Expanded Machine Payments Protocol (MPP) pay-per-use to 31 endpoints (tweets, communities, lists, user data)
  * New framework guides: LangChain, Pydantic AI, CrewAI, Mastra, Google ADK, Microsoft Agent Framework

  **Changed**

  * Billing migrated to credits-only model (usage-quota removed)
  * `GET /account` response: `creditInfo` replaces `currentPeriod`
  * `POST /extractions/estimate` response: `creditsRequired` / `creditsAvailable` replace `usagePercent` / `projectedPercent`
  * Monitor delivery changed. The public API contract did not change.
  * `POST /x/tweets/{id}/like` and `POST /x/tweets/{id}/retweet` are now end-to-end idempotent. Calling either on an already-acted-on tweet returns 200 success. The earlier silent rejection produced a 500 plus an account cooldown.

  **Removed**

  * Xquik no longer emits event types `follower.gained` and `follower.lost`. Valid event types: `tweet.new`, `tweet.quote`, `tweet.reply`, `tweet.retweet` (plus `webhook.test`).
  * Error code `shadow_account` (422) removed from `POST /monitors`
  * Error code `stream_registration_failed` (502) removed from `POST /monitors` (monitor activation is now asynchronous)
  * Telegram bot endpoints and integrations pipeline endpoints removed
</Update>

<Update label="March 2026" description="v1">
  **New**

  * MPP expanded from 16 to 31 eligible endpoints
  * Webhook delivery signing now uses HMAC-SHA256 with `X-Xquik-Signature` header

  **Changed**

  * OAuth 2.1 discovery metadata now served from `/.well-known/oauth-authorization-server`
  * Rate limit responses include `Retry-After` header
</Update>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.