Skip to main content
Search tweets, API keys, signed webhooks, user profiles, REST, MCP, authentication, billing, and writes all appear in this changelog.
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
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
  • 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
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
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
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
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