# Get a User's Liked Tweets with the API Canonical: https://www.twitterapis.com/answers/how-to-get-a-users-liked-tweets-api Description: user/likes reads a favourites timeline by numeric user_id behind a registered session, 20 per page, newest first. Each page of results costs $0.0008. Generated: 2026-08-26T06:52:18.654Z ---[Pricing](/pricing)[Docs](https://docs.twitterapis.com)[Blog](/blogs) Compare and Tools [MCP Server](/mcp)[Integrations](/integrations)[Language Clients](/sdk)[Free Tools](/tools)[Twitter ID Finder](/tools/twitter-id-finder)[Twitter API Cost Calculator](/twitter-api-cost-calculator)[Twitter Search API](/twitter-search-api)[Twitter Followers API](/twitter-followers-api)[Twitter Scraper](/twitter-scraper)[Twitter API Use Cases](/twitter-api-usecases)[Twitter API Rate Limits](/twitter-api-rate-limits)[Twitter Unofficial API](/twitter-unofficial-api)[Twitter Free API](/twitter-free-api)[Twitter API Alternatives](/twitter-api-alternatives)[TwitterAPIs vs Tweepy](/twitterapis-vs-tweepy)[TwitterAPIs vs RapidAPI](/twitterapis-vs-rapidapi)[TwitterAPIs vs GetXAPI](/twitterapis-vs-getxapi) Company [About](/about)[Status](/status)[Affiliates](/affiliates)[Trust](/privacy-and-data-handling)[Changelog](/changelog)[Contact](/contact) [Start Free](/signup) 1. [Home](/) 2. /[Answers](/answers) 3. /How do you get the tweets a user has liked? # How do you get the tweets a user has liked? Last updated August 24, 2026 The likes timeline lives behind user/likes, a Session Read that needs a registered session and takes user\_id, not a handle. It returns count, next\_cursor, and tweets, newest first, 20 per page by default. Its sibling user/media pages the same profile's photo and video posts by username. Both bill $0.0008 a page. Every rate here is the pricing TwitterAPIs publishes. The billed rate is $0.0008 per call; $0.04 per 1,000 tweets is derived from it at a full 20-tweet page, which is the default page size rather than a guaranteed yield (source: [twitterapis.com/pricing](/pricing)). ## The likes route and what it takes GET user/likes takes user\_id, the numeric identifier of the account whose favourites you want, as its one required argument. count is optional and defaults to 20. cursor is optional and omitted on the opening request. Nothing else exists on this route: there is no date range, no keyword filter and no way to ask only for likes on a particular author, so any narrowing happens after the page lands. The identifier is a string in the request for the usual reason, that X identifiers exceed the range JSON represents exactly, and the documented example uses 44196397. Auth is the same bearer header every route here uses, and the session cookies sit alongside it rather than replacing it: the API key decides who is billed, the registered session decides whose X account the read runs as. ## What one page of favourites contains Three fields come back: count, the number of tweets in this page; next\_cursor, the token to pass forward; and tweets, the liked posts themselves. Those are full tweet objects rather than references, so each one carries id as a string, text with URLs expanded, created\_at, an author object, and the engagement counters favorite\_count, retweet\_count, reply\_count and view\_count. The practical consequence is that a favourites pull is also an author list and an engagement dataset in one pass, with no follow-up lookup needed to find out who wrote the things somebody liked. text arrives with its URLs already expanded, and view\_count is populated only when the upstream source exposes it, so treat that one field as optional rather than assuming a number is always there. ## This route runs as your own account user/likes is filed under Session Reads, which is a visibility classification rather than a pricing one. It executes as your own logged in X account instead of a shared pool identity, so the vantage point of the read is whoever you registered. Without a registered session there is no acting identity and the call has nothing to read as. Note that the price is unaffected: this sits at the same standard rate as an ordinary profile lookup, and the session requirement is about what X will show, not about what the request costs. Registering a session and revoking it are both free calls, and the revoke is priced at zero on purpose so an account that has run out of credit can still delete its own stored cookies. ## Registering a session and reading its state Registration is a free POST to the customer session route carrying auth\_token and ct0, the two cookies from a logged in x.com browser session, in the JSON body rather than the query string. Optional user\_agent and proxy\_url fields exist. The response is worth parsing carefully: ok true only confirms the pair was stored, not that it works. The validation field is the one that matters and it has three states. validated means X answered an authenticated probe with a 200. dead means X explicitly rejected the cookies, the only state that proves them bad. unknown means the probe itself failed to resolve, through a timeout or a proxy fault, and must never be treated as invalid. A resolved username comes back too, or null when the identity lookup did not resolve, which is a separate concern from validation. ## The identifier trap between the two feeds These two neighbouring routes disagree about how to name an account. user/likes wants user\_id, numeric. user/media wants username, the handle with the @ stripped. Wiring both feeds into one profiling job and passing the same variable to each is the usual first failure, and it produces a 400 rather than wrong data, so it surfaces quickly. Resolve the handle once through a profile lookup, keep both forms on the record, and hand each route the one it asks for. Since identifiers survive renames and handles do not, the numeric form is also the one worth storing long term. Both routes ship with concrete documented examples, 44196397 on the favourites side and the handle nasa on the media side, which is the quickest way to confirm each argument is wired to the route that wants it. ## Why a favourites feed says something a timeline does not What an account posts is written for an audience. What it favourites accumulates without an audience in mind, which is why the two rarely describe the same interests. For research that gap is the whole point: the authors appearing repeatedly in someone's likes map who they actually read, competitor mentions show up there before they show up in public commentary, and the topics are unedited. Because every entry is a full tweet object with its author attached, ranking authors by frequency across a few pages needs no additional requests, just a counter over the array you already have. The author object on every entry carries that writer's id and username, which is what makes a frequency count over a few pages possible with no additional lookups at all. ## The media sibling and its attachment block user/media is the visual counterpart. It takes username and cursor, returns tweets, count and next\_cursor, and filters the timeline down to posts carrying attachments. Every tweet in that array includes an extended\_entities.media block, and each entry there exposes a type, photo in the documented example, along with a media\_url\_https address you can fetch directly without any further API call. The example returns a NASA post whose media entry points at a pbs.twimg.com image URL. There is no count parameter on this route, so page size is whatever the feed gives you and cursor is the only control. Entries can carry other media types, so branch on that field rather than assuming every attachment is an image, and note the route returns the same count and next\_cursor envelope the favourites feed uses. ## Ordering, and running the job again tomorrow Favourites come back newest first, which is what makes an incremental job cheap. Store the id of the most recent entry from each run, then on the next pass walk forward only until you meet that id and stop, rather than repaging the whole history. Read the count field from the response rather than assuming the size you requested was honoured. next\_cursor arriving empty or null means there are no further pages. Keep the raw tweet bodies rather than only the fields you parse today, because a re-pull costs requests while a stored payload does not. The media route offers no equivalent page size control, so an incremental strategy on that side rests entirely on the identifiers you already stored from the previous run. ## What a profiling pass costs Both feeds sit at the flat standard rate, so the bill is page count multiplied out and nothing else. Fifty pages of favourites at the default twenty per page covers roughly a thousand liked posts for four cents. Adding fifty pages of attachments takes the total to a hundred requests, about eight cents. The $0.50 credit issued at signup covers 625 requests with no card, enough for several full profiles. Registering the session and revoking it later are both free, so the only thing you ever pay for here is the pages themselves. Neither route carries a premium rate: both sit at the same standard figure an ordinary profile lookup bills, and the classification separating them is about access rather than price. We bill $0.0008 a call, per our public pricing. ## The likes feed against the media feed Property user/likes user/media Identifier accepted user\_id, numeric username, no leading @ Category Session Reads User Reads Registered session required Yes No Page size argument count, default 20 None documented, cursor only Distinctive payload tweets, newest first, with engagement counters extended\_entities.media with media\_url\_https Price per page $0.0008 $0.0008 > The Likes endpoints let you like and unlike Posts, see which users liked a Post, and get Posts liked by a user. X Developer Platform, Likes documentation. [Source](https://docs.x.com/x-api/posts/likes/introduction) ## Questions and answers Do I pass a handle or an ID to the likes endpoint? A numeric user\_id. Unlike most profile routes this one does not accept a handle, so resolve the @name to an identifier first and cache it. The media route is the opposite and wants username with the @ stripped. Mixing the two arguments up is the usual first failure when wiring both feeds into one job, though it fails loudly with a 400 rather than returning the wrong account. Why does the request need a logged in account? The route sits in the Session Reads group, meaning it executes as your registered account rather than a shared identity, so the read has a vantage point. Register the auth\_token and ct0 cookies once through the customer session endpoint and later calls apply them automatically. The requirement is about what X will show the caller, not about price, which stays at the standard per page rate. How do I register the session? POST the auth\_token and ct0 cookies from a logged in x.com browser session to the customer session route, in the JSON body rather than the query string. The call is free. Optional user\_agent and proxy\_url fields let you control how session traffic is sent. As an alternative to registering once, any single call can carry the same pair as the x-auth-token and x-ct0 headers. What does a validation state of unknown mean? That the probe did not resolve, through a timeout, a rate limit or a proxy fault, and it must never be read as the cookies being bad. Only the dead state means X explicitly rejected them. validated means an authenticated request came back 200. Note that ok true on the registration response confirms storage only, so a stored pair can be expired and still return a 200 there. How many liked posts arrive per request? Twenty by default, and the count parameter adjusts it. The response repeats the actual number in its own count field, so read that rather than assuming the size you asked for was honoured. Ordering is newest first, which is what lets a recurring job walk forward only until it meets an entry it already stored instead of repaging the whole history. What happens if I revoke the session? Routes that act as your account return 409 session\_required until you register again or start passing credentials per call. Revocation is a free, idempotent POST that returns 200 whether or not anything was stored. It deletes the stored copy of the cookies rather than logging the account out of x.com, so invalidating the cookies themselves means also ending the session from X account settings. What can a favourites feed tell me that a timeline cannot? Attention rather than presentation. A public timeline is written for an audience, while favourites accumulate quietly and track what genuinely held someone's interest. For research that means the authors and topics recurring in the feed describe an account's actual reading habits, which routinely differs from the subjects it posts about, and competitor interest often appears there long before any public comment does. How do I pull only images and video from a profile? Use user/media, which filters a timeline down to posts carrying attachments. Each returned tweet includes an extended\_entities.media array whose entries expose a type such as photo and a media\_url\_https address you can fetch directly, with no further API call needed to reach the file. Paging uses the same cursor mechanic, and there is no page size parameter on that route. Can one loop serve both feeds? Mostly. Both return a cursor to pass forward and both stop when the cursor is empty or the collection runs out, so the paging skeleton is shared. Two things differ and need parameterising: the identifier argument, user\_id against username, and the collection key, since likes returns its records under tweets while the media route returns the tweets it filtered plus a count. What does a research pass cost? It is multiplication, not a subscription. Every page of either feed is one request at the standard rate, so fifty pages of favourites covering about a thousand liked posts is four cents, and adding fifty pages of attachments takes it to eight. The free signup credit absorbs 625 requests, several full profiles worth, and session registration and revocation are both free. ## Keep reading - [Twitter Analytics API](/twitter-analytics-api?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-get-a-users-liked-tweets-api) - [Twitter Engagement API](/twitter-engagement-api?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-get-a-users-liked-tweets-api) - [Twitter Timeline API](/twitter-timeline-api?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-get-a-users-liked-tweets-api) - [Using multiple X accounts with one API key](/answers/how-to-use-multiple-x-accounts-with-one-api-key?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-get-a-users-liked-tweets-api) - [Endpoint documentation](https://docs.twitterapis.com/docs) - [Exporting your bookmarks](/answers/how-to-export-twitter-bookmarks-api?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-get-a-users-liked-tweets-api) ### Start with $0.50 in free credits No credit card. Roughly 12,500 tweets to test every endpoint. [Get your API key](/signup?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-get-a-users-liked-tweets-api)[See pricing](/twitter-analytics-api?utm_source=aio&utm_medium=organic&utm_campaign=aeo-answers-how-to-get-a-users-liked-tweets-api) [ TwitterAPIs](/) The cheapest pay-as-you-go Twitter and X API. $0.0008 per call, which works out to $0.04 per 1,000 tweets on a full 20-tweet page. No subscriptions and no developer account. ## Product / API - [Pricing](/pricing) - [Pay-Per-Use Pricing](/pay-per-use-pricing) - [Cost Calculator](/twitter-api-cost-calculator) - [Rate Limits](/twitter-api-rate-limits) - [MCP Server](/mcp) - [Integrations](/integrations) - [Language Clients](/sdk) - [Changelog](/changelog) - [Status](/status) ## Developers - [Documentation](https://docs.twitterapis.com) - [API Reference](https://docs.twitterapis.com/docs/reference/search/tweet-advanced-search) - [User Info](https://docs.twitterapis.com/docs/reference/user-reads/user-info) - [User Tweets](https://docs.twitterapis.com/docs/reference/user-reads/user-tweets) - [Advanced Search](https://docs.twitterapis.com/docs/reference/search/tweet-advanced-search) - [Verified Followers](https://docs.twitterapis.com/docs/reference/follower-graph/user-verified-followers) ## Resources / Compare - [Answers](/answers) - [Reviews](/reviews) - [Free Tools](/tools) - [Twitter ID Finder](/tools/twitter-id-finder) - [Get a Twitter API Key](/twitter-api-key) - [Official X API Comparison](/twitter-api-pricing) - [Twitter API Use Cases](/twitter-api-usecases) - [Twitter API Alternatives](/twitter-api-alternatives) - [Twitter Unofficial API](/twitter-unofficial-api) - [Twitter Free API](/twitter-free-api) - [TwitterAPIs vs twitterapi.io](/twitterapis-vs-twitterapi-io) - [TwitterAPIs vs GetXAPI](/twitterapis-vs-getxapi) - [TwitterAPIs vs TweetAPI](/twitterapis-vs-tweetapi) - [TwitterAPIs vs TwexAPI](/twitterapis-vs-twexapi) - [TwitterAPIs vs RapidAPI](/twitterapis-vs-rapidapi) ## Legal - [About](/about) - [Security](/security) - [Trust](/privacy-and-data-handling) - [Terms of Service](/terms-of-service) - [Affiliates](/affiliates) - [Contact](/contact) - [Jobs](/jobs) © 2026 TwitterAPIs. All rights reserved. TwitterAPIs is an independent third-party API for developers and researchers. Not affiliated with, endorsed by, or sponsored by X Corp. All systems operational