TwitterAPIs Docs
API ReferenceTweet Details

Twitter Quote Tweets API | Get Quotes of a Tweet

Fetch the quote tweets of a given tweet, cursor-paginated as full tweet objects, so you can read the commentary people attached rather than just count it. This endpoint is search-backed rather than served by a dedicated X operation, and every response says so in-band via source, search_query and quote_matched. Cost: $0.0008 per call.

Tweet Quotes returns the tweets that quote a given tweet, by id or url, cursor-paginated as full tweet objects. It is SEARCH-BACKED: X exposes no dedicated quote-tweets operation, so this endpoint runs the search query quoted_tweet_id:<id> and returns what X's search index holds. The count field is therefore how many quotes this search returned, never the tweet's true total, which is quote_count on the tweet object itself. Each page is one $0.0008 read.

GET
/tweet/quotes

Authorization

bearerAuth
AuthorizationBearer <token>

Pass your API key as a bearer token on every request: Authorization: Bearer <API_KEY>.

In: header

Query Parameters

id?string

Numeric ID of the tweet whose quotes you want. Provide either id or url.

url?string

Full status URL of the tweet whose quotes you want. Provide either id or url.

cursor?string

Pagination cursor from a previous response's next_cursor.

count?integer

Max items to request for this page. Defaults to 20 and is clamped to 1-100 by the underlying search, so a larger number returns at most 100 rather than erroring.

product?string

Search ordering: Latest (default, reverse-chronological) or Top (X's ranked ordering, materially slower upstream). Any other value falls back to Latest rather than changing what the endpoint means.

strict?boolean

Set to true to drop every returned row that does not demonstrably quote the requested tweet, instead of only counting them in quote_matched. Default false, because X does not embed the quoted original on every search result, so strict mode can hide real quotes.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/tweet/quotes?id=1759123456789012345&url=https%3A%2F%2Fx.com%2Fnaval%2Fstatus%2F1759123456789012345&count=20&product=Latest&strict=false"
{  "count": 2,  "next_cursor": "DAADDAABCgABF...",  "has_more": true,  "tweets": [    {      "id": "1759987654321098765",      "text": "This is the clearest write-up of the problem I have read all year.",      "created_at": "Tue Feb 20 16:02:11 +0000 2026",      "author": {        "id": "9921",        "username": "devjane",        "name": "Jane"      },      "is_quote": true,      "quoted_tweet": {        "id": "1759123456789012345",        "text": "Launching today."      },      "favorite_count": 41    },    {      "id": "1759988812345678901",      "text": "Adding one caveat to this.",      "created_at": "Tue Feb 20 16:20:44 +0000 2026",      "author": {        "id": "3310",        "username": "buildlogs",        "name": "Build Logs"      },      "is_quote": true,      "quoted_tweet": {        "id": "1759123456789012345",        "text": "Launching today."      },      "favorite_count": 7    }  ],  "source": "search",  "search_query": "quoted_tweet_id:1759123456789012345",  "quote_matched": 2}
{  "error": "bad_request",  "message": "Missing or malformed parameter. Fix the request before retrying."}
{  "error": "unauthorized",  "message": "The API key is missing, malformed, or revoked. Check the Authorization header."}
{  "error": "insufficient_credits",  "message": "Your balance is exhausted. Top up your credits to continue."}
{  "error": "not_found",  "message": "The resource does not exist, for example a deleted tweet or a private account."}
{  "error": "rate_limited",  "message": "Too many requests. Back off and retry with exponential backoff."}
{  "error": "server_error",  "message": "Something failed on our side. Retry with backoff; if it persists, contact support."}

Pricing

UnitPrice
Per call$0.0008
Per 1,000 calls$0.80
Per 1,000 records (~20 per call)~$0.04

Each page of quotes is one $0.0008 read. strict=true is metered on the rows you actually receive, so the dropped non-matching rows are not billed.

When to use

Use it to read what people said when they quoted a post, which is the commentary Tweet Replies does not capture and Tweet Retweeters cannot show you (a retweet carries no text). Reach for Tweet Detail instead when all you need is the authoritative quote_count number.

Notes

  • SEARCH-BACKED, and this is the one thing to internalise before using the numbers. X exposes no dedicated quote-tweets operation, so this endpoint runs the search query quoted_tweet_id:<id> against X's search index. count is what that search returned. The authoritative total is quote_count on the tweet object, available from Tweet Detail, and the two WILL differ.
  • Why they differ, concretely: a quote posted seconds ago may not be indexed yet; quotes that were deleted, or posted by protected or suspended accounts, or withheld in your region, are absent from search; and X's index makes no promise to hold every historical match for a high-volume tweet.
  • quote_matched is the in-band honesty check. If it equals count, every returned tweet really is a quote of the id you asked for. If it is 0 while tweets is non-empty, X is no longer honouring the quoted_tweet_id: operator and is returning tweets that merely contain that number: discard the page rather than trusting it.
  • quote_matched is a LOWER bound, not an upper one. It only counts rows where X embedded the quoted original in the search result, and X does not always do that, so a genuine quote can be missing from quote_matched. That is why strict is off by default.
  • product=Top routes upstream to X's ranked search, which is materially slower than the default Latest. Use Latest for monitoring and paging.

Pagination

Pass the returned next_cursor straight back as ?cursor= to get the next page. This endpoint pages on the search timeline's own bottom cursor, exactly like Advanced Tweet Search. Stop when tweets comes back empty or has_more is false.

FAQ

Why does count disagree with the quote_count on the tweet?

Because they measure different things. quote_count on the tweet object is X's authoritative total. count here is how many quotes X's SEARCH INDEX returned for this page, and the two will differ: a very fresh quote has not been indexed yet, and deleted, protected, suspended and region-withheld quotes are absent from search entirely. Treat count as a floor on what is publicly readable, not as the total.

What are source, search_query and quote_matched for?

They exist so you never have to guess how a number was produced. source is always "search", which tells you this endpoint is not backed by a dedicated X operation. search_query is the exact query sent upstream, quoted_tweet_id:<id>. quote_matched is how many of the returned tweets demonstrably carry the requested tweet as their quoted_tweet, so quote_matched equal to count means every row is a genuine quote.

What does strict=true do?

It drops every returned row whose embedded quoted_tweet is not the tweet you asked about, instead of merely counting them in quote_matched. It is off by default because X does not embed the quoted original on every search result, so strict trades a false-positive risk for a false-negative one, and only you can decide which is worse for your use case.

Should I worry if quote_matched comes back 0 on a non-empty page?

Yes, and that is exactly what the field is for. It means X stopped honouring the quoted_tweet_id: operator and tokenized it as plain text, so the rows returned are tweets that merely contain that number. Treat a zero quote_matched with a non-empty tweets array as a bad result, not as data.