Twitter image size suffixes reloaded: pbs.twimg.com URL information
Posted by jpluimers on 2025/02/18
It’s almost
- 8 years ago since I wrote about Twitter image size suffixes – via: Making silly #latex jokes is much more fun than doing final tweaks in my thesis on #coeffects…
- 2 years ago I wrote about Some experience of htmlpreview.github.io as a replacement for rawgit.com
- a day posting about converting a tweet URL to a Tweet JSON URL in Probably many more like these are needed to download Twitter videos: [extractor/twitter] Fix unauthenticated extraction by bashonly · Pull Request #7476 · yt-dlp/yt-dlp
Goal of the current post amend the above posts with information so I can later write a bookmarklet or web-page with JavaScript that – from a x.com or twitter.com – tweet URL can get the JSON, then the images and/or videos in all sizes, then generate a web-page from it for Wayback Machine archival.
Note that htmlpreview needs a CORS server and currently (as the other CORS servers are no longer available, see [Wayback/Archive] Merge branch ‘master’ into notCorsFirst · htmlpreview/htmlpreview.github.com@dfb47f7 · GitHub) depends on the open source [Wayback/Archive] GitHub – jolav/codetabs: Free Online Services. Github/GitLab star history. Count Lines of Code. CORS proxy server. IP GeoLocation. HTTP Headers. Random Data. Api weather temp. Alexa ranking.
If that goes off-line, the CORS server will need changing, hopefully [WaybackSave/Archive] free cors server – Google Search returns enough results. The CORS server days remind me of the SOAP XML days, with by now have hardly any free example server left (see for instance [Wayback/Archive] Compiled list of free and working WSDL URLs. | by Nishanthi Grashia Suresh | Medium).
Media URLs
Media URLs can be obtained from links like https://cdn.syndication.twimg.com/tweet-result?id=1863177456087158995&token=! where 1863177456087158995 is the tweet ID (the token trick is from [Wayback/Archive] Twitter Updates · Issue #32392 · ytdl-org/youtube-dl · GitHub which I already mentioned in the Twitter videos blog post mentioned above but is much worth repeating).
These contain the full data of a Tweet in JSON format. Let’s call them Tweet JSON from now on.
The Tweet JSON can be queried using [Wayback/Archive] GitHub – dchester/jsonpath: Query and manipulate JavaScript objects with JSONPath expressions. Robust JSONPath engine for Node.js.
In the returned JSON, to find video URLs (in my experience: always 3, and always using the same resolution), either search for:
- Search for nodes having
content_type="video/mp4", then for the next sibling with keyurlkey, pick the value. You will find 3 occurrences, each with a resolution and file identifier in their URL:url="https://video.twimg.com/amplify_video/1863174334975504384/vid/avc1/320x568/ugEx1eBAdVkKtAAr.mp4?tag=16"url="https://video.twimg.com/amplify_video/1863174334975504384/vid/avc1/480x852/9o9-VFVM8We6RKnJ.mp4?tag=16"url="https://video.twimg.com/amplify_video/1863174334975504384/vid/avc1/576x1024/7VZu059ex7YV2gya.mp4?tag=16"
Notes:
- The JSONPath query for the values of this is
$..[?(@.content_type=='video/mp4')].url - From these
urlvalues, you can remove the?tag=16suffix
- Search for nodes having
type="video/mp4", then for the next sibling with keyurlkey, pick the value. You will find 3 occurrences, each with a resolution and file identifier in their URL:src="https://video.twimg.com/amplify_video/1863174334975504384/vid/avc1/320x568/ugEx1eBAdVkKtAAr.mp4?tag=16"src="https://video.twimg.com/amplify_video/1863174334975504384/vid/avc1/480x852/9o9-VFVM8We6RKnJ.mp4?tag=16"src="https://video.twimg.com/amplify_video/1863174334975504384/vid/avc1/576x1024/7VZu059ex7YV2gya.mp4?tag=16"
Notes:
- The JSONPath query for the values of this is
$..[?(@.type=='video/mp4')].src - From these
urlvalues, you can remove the?tag=16suffix as well
To find he video cover picture (some call this thumbnail or photo):
- Search for the node with name
media_url_httpsand take its value. There is just one occurrence:media_url_https="https://pbs.twimg.com/amplify_video_thumb/1863174334975504384/img/b3KPFYiKRFz7vW-O.jpg",
Notes the JSONPath query for this is
$..media_url_https - Search for the node with name
posterand take its value. There is just which has one occurrence:poster="https://pbs.twimg.com/amplify_video_thumb/1863174334975504384/img/b3KPFYiKRFz7vW-O.jpg"
Note the JSONPath query for this can be either
$..posteror$.video.poster
JSONPath
The sibbling part (getting to url from content_type and to src from type) of the above queries is based on [Wayback/Archive] jsonpath – Json filter data on the sibling node – Stack Overflow (thanks [Wayback/Archive] Gico).
For the above JSONPath queries, I first pretty printed the Tweet JSON using [Wayback/Archive] JSON Parser Online to parse JSON, then tested all the JSONPath queries using [Wayback/Archive] JSONPath Online Evaluator which is open source at [Wayback/Archive] GitHub – ashphy/jsonpath-online-evaluator: JSONPath Online Evaluator.
Actually, I think the query syntax is OK (not great, as they aimed for a very concise syntax, but hey: it is based off XPath with a notoriously hard syntax and using JSONPath is way easier than writing out all the filtering code), so I want to use it in this aimed to be tiny project of tweet data displaying project.
This means I have to learn how to incorporate JSONPath in either a Bookmarklet or web-page, preferably without using nodejs in order not to blow up the solutions beyond being small.
Hopefully these links help me:
- [Wayback/Archive] jsonpath/jsonpath.min.js at master · dchester/jsonpath · GitHub
- [Wayback/Archive] github.com/dchester/jsonpath/raw/refs/heads/master/jsonpath.min.js
- [Wayback/Archive] jsonpath – npm only shows 3 dependencies at [Wayback/Archive] jsonpath – npm: dependencies
- [Wayback/Archive] JSONPath with JavaScript | JSON tutorial| w3resource
…
<head> <title>JavaScript JSONPath example | JSON tutorial | w3resource</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> /JSON/json.js /JSON/jsonpath.js </head>…
JSONPath history
Early February 2007 was the start of JSONPath with the post [Wayback/Archive] JSONPath – XPath for JSON followed by 4 updates in august that year covering expressions, examples, implementation and issues.
The first implementations included JavaScript and PHP, with soon a repository now at [Wayback/Archive] Google Code Archive – Long-term storage for Google Code Project Hosting. covering C# as well.
All current implementations are derived from that code base.
Getting the JSON
I wasn’t sure how to download a string from a URL in JavaScript, but luckily [Wayback/Archive] javascript – How would I parse json from an external url? – Stack Overflow showed this can be done with good old SOAP-era XMLHttpRequest.
The Stack Overflow code has some examples, and JavaScript documentation is at [Wayback/Archive] XMLHttpRequest – Web APIs | MDN
Image resolutions
The first linked blog post above was in part based on [WaybackSave/Archive] Entities in Objects — Twitter Developers. That link is now gone, but the documentation itself was extended and is now published on [Wayback/Archive] Entities object | Docs | Twitter Developer Platform. New information is now in the table below, including maximum resolutions and URL format names.
I have summarised the information in the table further below.
Tweet JSON after deletion
If a tweet gets deleted, the JSON changes to indicate id is removed, but the the media links from a tweet will stay on-line (so if you have old JSON, then you can still find the tweet content: this is one of the big reasons for writing this blog post: providing information to help archiving old content).
You can see this when looking at two archivals of https://cdn.syndication.twimg.com/tweet-result?id=1577533879283585025&token=!
This makes it very important to archive the Tweet JSON in both Wayback Machine and Archive Today, as with that you can get back to the Tweet media.
Tables (some updated)
Image resolutions and suffixes
Notes:
mediumis still the defaultorigis still undocumented
I got the maximum “orig” resolution from [Wayback/Archive] Retrieving full-size images — media.fields=url points to resized version? – X API / X API v2 – X Developers
Video resolutions
There seem to be tree video resolutions:
- 320×568
- 480×852
- 576×1024
Since all video files have unique IDs, there is no “default”.
Not the first to find out about the CDN JSON
Above you saw the GitHub thread where I got the token from. So I wasn’t the first about finding out about the Tweet JSON. The underlying links are these:
- [WaybackSave/Archive] Twitter Updates · Issue #32392 · ytdl-org/youtube-dl · GitHub
- [WaybackSave/Archive] [Twitter] Account is now required to download (Failed to parse JSON) · Issue #7473 · yt-dlp/yt-dlp · GitHub
- [Wayback/Archive] cdn.syndication.twimg.com/tweet-result?id=1577533879283585025&token=!
- [WaybackSave/Archive] [extractor/twitter] Fix unauthenticated extraction by bashonly · Pull Request #7476 · yt-dlp/yt-dlp · GitHub
- [Wayback/Archive] [extractor/twitter] Fix unauthenticated extraction by bashonly · Pull Request #7476 · yt-dlp/yt-dlp · GitHub
- [Wayback/Archive] [extractor/twitter] Fix unauthenticated extraction by bashonly · Pull Request #7476 · yt-dlp/yt-dlp · GitHub
I wasn’t the second either, as when doing the final search it appeared Vercel people found out about that JSON too as part of their project [WaybackSave/Archive] GitHub – vercel/react-tweet: Embed tweets in your React application.:
- [Wayback/Archive] How to prerender Tweets without using the official Twitter APIs | Stefan Judis Web Development
The Vercel release post points to the solution:
Under the hood,
react-tweetreverse-engineers the Twitter’s Embed API to fetch data for a given tweet and renders it in the same style as Twitter’s embedded iframe.The key is that Twitter’s original
widget.jstalks to an open API atcdn.syndication.twimg.com. This API includes most of the needed data to render a Tweet on your sites (unfortunately, retweet count is unavailable). Reverse engineering the response takes some time but is worth it because, as Vercel says, “react-tweetuses 35x less client-side JavaScript than the Twitter’s Native embed”. - [Wayback/Archive] Introducing React Tweet – Vercel with these demos:
- [Wayback/Archive] react-tweet/packages/react-tweet/src/api/get-tweet.ts at 03f4db52f393ddf84e62a42222d49c765bbd3420 · vercel/react-tweet · GitHub
- [Wayback/Archive] Add missing token to api calls to Twitter’s CDN (#128) · vercel/react-tweet@dc5cadf · GitHub
- [Wayback/Archive] Add missing token to api calls to Twitter’s CDN by lfades · Pull Request #128 · vercel/react-tweet · GitHub
TODO: profile pictures and banners.
It looks like the are stored at these sizes:
- 400×400 profile picture: [Wayback/Archive] 77_ho04k_400x400.jpg (240×240) and [Wayback/Archive] 77_ho04k.jpg (240×240) (though I am not sure why Twitter thinks it is 240×240 for my profile)
- 1500×500 profile banner: [Wayback/Archive] 1500×500 (1500×500) and [Wayback/Archive] 1497448432 (1024×342)
Links:
- [Wayback/Archive] tweets – How to get “bigger-size” user image with Twitter API 1.1? – Stack Overflow (thanks [Wayback/Archive] sam_smith and [Wayback/Archive] Joe Mayo)
- [Wayback/Archive] User profile images and banners | Docs | Twitter Developer Platform
TODO: verify
I want to check the above information against the guidelines in [Wayback/Archive] Twitter Image Specs: An Updated Guide to Sizes for 2024 summarised as:
X (Twitter) supports various file types, including PNG, GIF, JPG, and even animated GIFs. Each file type has specific requirements for aspect ratio, file size, and dimensions. X (Twitter) supports images with aspect ratios of 16:9 and 1:1, the latter being recommended. For animated GIFs, the aspect ratio must be between 1:1 and 3:1. The maximum file size for images is 5 MB, while for animated GIFs, it’s 15 MB. The recommended image size for X (Twitter) is 1200 x 675 pixels for landscape images, 900 x 900 pixels for square images, and 506 x 253 pixels for 2:1 aspect ratio images. For profile pictures, the recommended size is 400 x 400 pixels, while the header image size is 1500 x 500 pixels.X (Twitter) profile image
- Under 2 MB
- 400 x 400 pixels
X (Twitter) cover photo
- Up to 2 MB
- 1500 x 1500 pixels
X (Twitter) image post size
- Landscape: 1600 x 900 pixels
- Square: 1080 x 1080 pixels
- Portrait: 1080 x 1350 pixels
- Aspect ratio between a 2:1 and 1:1 for desktop, and either 2:1, 3:4, or 16:9 for mobile
X (Twitter) card images
- 1200 x 628 pixels
- 1.91:1 aspect ratio
- X (Twitter) will display your image at a maximum of 4096 x 4096 pixels.
Image ads
- Up to 5 MB
- Sizes and aspect ratios vary
X (Twitter) also recommends the following:
- Image ads with app buttons: 800 x 418 pixels recommended for 1.91:1 aspect ratio, and 800 x 800 pixels recommended for 1:1 aspect ratio
- Image ads with conversation buttons: 800 x 418 pixels and 1.91:1 aspect ratio
- Image ads with polls: 800 x 418 pixels recommended for 1.91:1 aspect ratio, and 800 x 800 pixels recommended for 1:1 aspect ratio; 1:1 will crop to 1.91:1 in mobile timeline
- Image ads with website buttons: 800 x 418 pixels recommended for 1.91:1 aspect ratio, and 800 x 800 pixels recommended for 1:1 aspect ratio
- Standalone image ads: 1200 x 1200 pixels recommended for 1:1 aspect ratio, and 1200 x 628 pixels recommended for 1.91:1 aspect ratio; larger images are better for when users click to expand images
- Image carousel: 800 x 418 pixels recommended for 1.91:1 aspect ratio, and 800 x 800 pixels recommended for 1:1 aspect ratio
In-stream images
- 440 x 220 pixels
- X (Twitter) will display your image at a maximum of 1024 x 512 pixels, so it’s important to make sure that your image looks good at that size as well.
X (Twitter) image file types and sizes
X (Twitter) accepts the following image file types:
- JPG
- PNG
- GIF
- WebP
You can’t use other image file types like BMP, PDF, etc.
Hosting code in GitHub gists
See [Wayback/Archive] javascript – Embed Partial Gist File – Stack Overflow and [Wayback/Archive] GitHub – kashif-umair/gist-embed: Easily embed gists into any blog or webpage
Similarly you can host code on GitHub.
Queries
- [Wayback/Archive] twitter image small large 900×900 – Google Suche
- [WaybackSave/Archive] free cors server – Google Search
- [WaybackSave/Archive] free soap xml server – Sök på Google
- [Wayback/Archive] online json parser from url – Google Suche
- [Wayback/Archive] online query json from url – Google Search
- [WaybackSave/Archive] javascript jsonpath – Google Search
- [WaybackSave/Archive] jsonpath get sibling – Sök på Google
- [WaybackSave/Archive] include jsonpath in web page – Google Suche
- [Wayback/Archive] jsonpath without nodejs – Google Search
- [Wayback/Archive] mdn XMLHttpRequest – Sök på Google
- [WaybackSave/Archive] what is cdn syndication twimg com – Google Search
--jeroen
Rate this:
Share this:
- Click to share on Mastodon (Opens in new window) Mastodon
- Click to share on Bluesky (Opens in new window) Bluesky
- Share on Tumblr
- Click to share on Reddit (Opens in new window) Reddit
- Click to share on Threads (Opens in new window) Threads
- Tweet
- Click to share on Telegram (Opens in new window) Telegram
- Click to share on Nextdoor (Opens in new window) Nextdoor
- Click to share on WhatsApp (Opens in new window) WhatsApp
- Click to print (Opens in new window) Print
- Click to email a link to a friend (Opens in new window) Email
Related
This entry was posted on 2025/02/18 at 18:00 and is filed under Development, HTML, JavaScript/ECMAScript, Scripting, SocialMedia, Software Development, Twitter, Web Development. Tagged: 128, 32392, 7473, 7476, LaTeX. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
This site uses Akismet to reduce spam. Learn how your comment data is processed.






Leave a comment