Twitter Undocumented Bookmark API (DEPRECATED)
Twitter has released the official API v2 endpoint for the bookmark feature. https://twittercommunity.com/t/build-with-bookmarks-on-the-twitter-api-v2/168804/
The following descriptions are or will soon be no longer useful; I suggest using the new official API.
I found out the endpoints for bookmark with Chrome Developer Tools:
The rate limits below are values returned by an official endpoint
This document is still a work in progress because I got stuck in
GET timeline/bookmark. Please let me know if you find how to use it.
- It is necessary that
x-csrf-tokenin a request header and
ct0in a cookie are the same value. Twitter uses them to avoid CSRF attacks. I recommend that you extract the values from your browsers.
- All of the endpoints requires OAuth2 Authorizations. Note that they refuse OAuth2 Bearer tokens obtained from
- You can easily reach the rate limit and get HTTP 429 Error (too many requests), so you should be careful about how many requests you send.
- I have heard that someone said that "GET timeline/bookmark" returned HTTP 403 Error even though OAuth authentication succeeded. Maybe the endpoint refuses mechanical accesses.
- In some cases, perhaps it is better to use the official TweetDeck Collection API instead of the undocumented and uncertain API.
- cf: https://github.com/geekodour/twitmarks/ / https://github.com/acorn/twitter-bookmarks-search (It seems the developers understand how to use the endpoints)
I'm trying to extract the data out of
https://api.twitter.com/2/timeline/bookmark.jsonand am making some headway. To start, I'm extracting my cookies and headers from a selenium session elsewhere, and then following along with how the browser makes the requests:
url = "https://api.twitter.com/2/timeline/bookmark.json?include_profile_interstitial_type=1&include_blocking=1&include_blocked_by=1&include_followed_by=1&include_want_retweets=1&include_mute_edge=1&include_can_dm=1&include_can_media_tag=1&skip_status=1&cards_platform=Web-12&include_cards=1&include_composer_source=true&include_ext_alt_text=true&include_reply_count=1&tweet_mode=extended&include_entities=true&include_user_entities=true&include_ext_media_color=true&include_ext_media_availability=true&send_error_codes=true&simple_quoted_tweets=true&count=20&ext=mediaStats%2ChighlightedLabel%2CcameraMoment"
(there's a lot of crap happening here that I haven't experimented removing/altering yet -- I just lifted the URL straight from dev tools)
A successful response to this looks like so:
Within that response we can find the
'value': 'our_cursor_value=='which is used for the next request. I build this request by appending
&cursor=our_cursor_value==to the end of our first URL.
This also returns a 200 response with the next 20 bookmarked tweets. This process can be repeated a few more times (extracting the latest cursor and passing it in) until, after 3-6 requests it starts returning a
401all of sudden:
My ideas so far for why I'm hitting that 401 status:
POST:client.jsonrequest happening every few seconds/minutes.
If I get anywhere further I'll update here.