Twitter (X) Media Downloader
Pricing
from $0.49 / 1,000 results
Twitter (X) Media Downloader
Download videos, photos, GIFs, audio and poster images from public Twitter/X posts - no login, no cookies. Works with post links or usernames, supports every video quality, audio-only M4A/MP3, quoted-post media and public signed download links.
Pricing
from $0.49 / 1,000 results
Rating
0.0
(0)
Developer
Dataspryva
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
18 hours ago
Last modified
Categories
Share
Collect public Twitter / X media without an account, cookies or a browser. Paste post links or ask for a profile's media posts and get the actual files back — videos in any available quality, photos, GIFs, audio-only tracks and video posters — each with a public download link.
What it does
- Post mode — one link or ID per post, including
x.com,twitter.com,mobile.twitter.com,/i/web/status/links,/status/<id>/video/1links and bare numeric IDs. - Profile mode — walks a profile's media posts page by page, not just the handful shown to logged-out visitors.
- Both modes in one run — results are de-duplicated across the two paths.
- Status rows — deleted, protected, media-less and rate-limited targets produce an honest status row instead of a silent empty run.
Services
| Service | What you get |
|---|---|
| Video download | Best, 2160p, 1080p, 720p, 480p or smallest MP4; every quality can be saved as separate files |
| Photo download | Original, large, medium or small image files |
| GIF download | The MP4 file X serves for animated GIFs |
| Audio extraction | M4A (AAC) or MP3 soundtrack of a video |
| Poster images | The video/GIF thumbnail as a separate photo file |
| Quoted-post media | Media inside a quoted post, marked mediaSource: "quoted post" |
| Author and post context | Text, date, engagement counts, author name/avatar/verification/followers, hashtags, mentions, links, reply/quote flags and quoted post IDs |
| Profile context | Profile ID, follower count and media count on rows found through a username |
| Profile filters | Minimum likes, minimum reposts and verified-authors-only |
How it works
The actor reads X's public post data and the FxTwitter mirror, combines the fields each source is best at, and falls back to the X status page and oEmbed when a post looks missing. Videos and GIFs use X's direct CDN; if a direct file cannot be fetched, yt-dlp is tried as a last resort. Files are streamed to disk, checked for a sane size, stored in the run's key-value store and linked with a signed public URL. No request uses your cookies, login or API key.
Input
| Field | Type | Default | Description |
|---|---|---|---|
postUrls | array | – | Post links or bare post IDs (the prefill uses one NASA post) |
usernames | array | – | Handles, @handles or profile links to scan |
maxPostsPerUser | integer | 20 | Media posts to check per profile (1–1000) |
maxItems | integer | 100 | Hard cap on media rows for the whole run (1–10000) |
mediaTypes | array | ["video", "photo", "gif"] | video, photo, gif |
imageQuality | string | orig | orig, large, medium, small |
videoQuality | string | best | best, 2160p, 1080p, 720p, 480p, worst |
downloadAllQualities | boolean | false | One row and file per available MP4 quality |
includePosterImage | boolean | true | Save each video/GIF poster as a photo |
includeAltText | boolean | true | Attach X's image description when present |
audioOnly | boolean | false | Save only the audio track of videos; photos and GIFs are skipped |
audioFormat | string | m4a | m4a or mp3 when audio-only is on |
includeQuotedMedia | boolean | true | Include media from a quoted post |
includeMetadata | boolean | true | Attach post, author and engagement context |
minLikes | integer | 0 | Profile scans only: skip posts below this like count |
minRetweets | integer | 0 | Profile scans only: skip posts below this repost count |
onlyVerifiedAuthors | boolean | false | Profile scans only: skip unverified authors |
saveToFile | boolean | true | Store files and return signed links; off means metadata and CDN links only |
At least one post link/ID or username is required. Directly linked posts are always collected; the three filters apply while scanning usernames.
Example: download two posts
{"postUrls": ["https://x.com/NASA/status/2107095768821576019","https://x.com/SheCodeAfrica/status/2107516524965794217"],"videoQuality": "1080p","maxItems": 10}
Example: scan a profile's media
{"usernames": ["NASA"],"maxPostsPerUser": 50,"maxItems": 100,"mediaTypes": ["video", "photo"],"minLikes": 100,"onlyVerifiedAuthors": true}
Example: audio-only MP3
{"postUrls": ["https://x.com/NASA/status/2107095768821576019"],"audioOnly": true,"audioFormat": "mp3"}
Output
Every dataset row has type: media file for a collectible file, or status for a run message.
| Group | Fields |
|---|---|
| Identity | tweetId, tweetUrl, postedAt, conversationId, inReplyToTweetId, isReply, isQuote, isRetweet, quotedTweetId, quotedTweetUrl |
| Media | mediaType, mediaUrl, mediaUrlOriginal, contentType, mediaId, mediaKey, thumbnailUrl, posterImageUrl, filename, fileSizeBytes, width, height, durationSeconds, focusRects, allowDownload |
| Download | downloadUrl, downloadStatus, message |
| Video quality | variantQuality, variantBitrate, availableQualities, qualityCount, isBestQuality |
| Audio | audioFormat |
| Author | uploaderUsername, uploaderName, uploaderVerified, uploaderAvatarUrl, uploaderFollowers |
| Post context | tweetText, likeCount, retweetCount, replyCount, quoteCount, bookmarkCount, viewCount, engagementRate, hashtags, mentions, urls |
| Source | mediaSource (post, quoted post or poster image) |
| Profile | profileId, profileFollowers, profileMediaCount |
| Run | collectedAt |
Empty fields are omitted. Status rows carry status (noInput, invalidLink, invalidUsername, notFound, rateLimited, error, noMatchingMedia, noRecords), a human-readable message, and the related tweetUrl, tweetId or username.
Example record
{"type": "media file","tweetId": "2107095768821576019","tweetUrl": "https://x.com/i/status/2107095768821576019","postedAt": "2026-10-05T13:09:13+00:00","mediaType": "video","mediaUrl": "https://video.twimg.com/amplify_video/.../avc1/1920x1080/video.mp4?tag=16","contentType": "video/mp4","mediaId": "2107095744146460672","filename": "2107095768821576019_video_1_1080p.mp4","fileSizeBytes": 3178943,"width": 1920,"height": 1080,"durationSeconds": 13.3,"downloadUrl": "https://api.apify.com/v2/key-value-stores/{STORE_ID}/records/...?signature=...","downloadStatus": "finished","uploaderUsername": "NASA","uploaderName": "NASA","uploaderVerified": true,"uploaderFollowers": 92310189,"likeCount": 7476,"retweetCount": 1125,"quoteCount": 97,"bookmarkCount": 332,"viewCount": 2961506,"variantQuality": "1080p","isBestQuality": true,"mediaSource": "post","collectedAt": "2026-10-29T00:00:00+00:00"}
Usage cost
You pay the actor's per-result price shown on its Apify page plus normal Apify platform usage. With saveToFile: false no media bytes are stored, so a metadata-only run is the cheapest option. Downloads add key-value store usage proportional to the real file sizes. Keep maxItems and maxPostsPerUser at the values you need — the actor stops as soon as maxItems is reached.
FAQ
Do I need an X account, cookies or an API key? No. Everything is read from public, logged-out sources.
Can I download from a private or protected account? No. Protected and deleted posts return a notFound status row; they are not silently skipped.
How far back does a profile scan go? The walk follows X's media timeline page by page until maxPostsPerUser, maxItems or the end of the timeline. Large profiles can be rate-limited; lower maxPostsPerUser and re-run later.
How are video qualities chosen? The closest available quality to your preference is used. Portrait videos are compared by their short side, so a 1080×1920 video counts as 1080p. With downloadAllQualities, every progressive MP4 becomes its own row and file.
What happens with quoted posts? Media inside a quoted post is included by default and marked mediaSource: "quoted post". Turn includeQuotedMedia off to keep only the linked post's own media.
Does audio-only work on GIFs? No. Animated GIFs have no audio track, so they are skipped in audio-only mode along with photos.
What if a post has no media? You get one noMatchingMedia status row explaining it, not an empty dataset.
Do download links expire? Signed key-value store links follow your Apify storage retention. Re-run the actor or copy the files to your own storage for permanent archiving.
How do the profile filters treat unknown counts? A post whose like/repost count or verification status is unknown is kept rather than excluded.
Can I still use my saved inputs from the previous version? Yes. Old input keys are mapped automatically in code, so saved tasks keep running.
Notes
- All timestamps are UTC ISO 8601.
- Engagement rate is derived from likes, reposts, replies and quotes divided by the author's follower count; it is omitted when the follower count is unknown.
- Media URLs are direct X CDN links and open without a Referer header.
- Download links are public signed links tied to the run's key-value store.
- Use the actor only for content you have the right to download.
Limitations
- Public posts only: deleted posts, protected accounts and login-gated content are not accessible.
- Profile scans cover the most recent media posts X exposes publicly, up to 1,000 posts per run; deeper history is not addressable and very large profiles can hit rate limits, so re-run later if a scan stops early.
- A single media file larger than 1 GB is rejected to keep memory bounded.
- Some media is marked by X as not downloadable; those rows report
downloadStatus: "notDownloaded"with an explanation. - Quote media depends on the quoted post still being public.
- X changes its public endpoints periodically; the actor keeps several fallbacks, but a run can still return
rateLimitedorerrorstatus rows during an outage.