Twitter (X) Media Downloader avatar

Twitter (X) Media Downloader

Pricing

from $0.49 / 1,000 results

Go to Apify Store
Twitter (X) Media Downloader

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

Dataspryva

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

18 hours ago

Last modified

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/1 links 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

ServiceWhat you get
Video downloadBest, 2160p, 1080p, 720p, 480p or smallest MP4; every quality can be saved as separate files
Photo downloadOriginal, large, medium or small image files
GIF downloadThe MP4 file X serves for animated GIFs
Audio extractionM4A (AAC) or MP3 soundtrack of a video
Poster imagesThe video/GIF thumbnail as a separate photo file
Quoted-post mediaMedia inside a quoted post, marked mediaSource: "quoted post"
Author and post contextText, date, engagement counts, author name/avatar/verification/followers, hashtags, mentions, links, reply/quote flags and quoted post IDs
Profile contextProfile ID, follower count and media count on rows found through a username
Profile filtersMinimum 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

FieldTypeDefaultDescription
postUrlsarray–Post links or bare post IDs (the prefill uses one NASA post)
usernamesarray–Handles, @handles or profile links to scan
maxPostsPerUserinteger20Media posts to check per profile (1–1000)
maxItemsinteger100Hard cap on media rows for the whole run (1–10000)
mediaTypesarray["video", "photo", "gif"]video, photo, gif
imageQualitystringorigorig, large, medium, small
videoQualitystringbestbest, 2160p, 1080p, 720p, 480p, worst
downloadAllQualitiesbooleanfalseOne row and file per available MP4 quality
includePosterImagebooleantrueSave each video/GIF poster as a photo
includeAltTextbooleantrueAttach X's image description when present
audioOnlybooleanfalseSave only the audio track of videos; photos and GIFs are skipped
audioFormatstringm4am4a or mp3 when audio-only is on
includeQuotedMediabooleantrueInclude media from a quoted post
includeMetadatabooleantrueAttach post, author and engagement context
minLikesinteger0Profile scans only: skip posts below this like count
minRetweetsinteger0Profile scans only: skip posts below this repost count
onlyVerifiedAuthorsbooleanfalseProfile scans only: skip unverified authors
saveToFilebooleantrueStore 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.

GroupFields
IdentitytweetId, tweetUrl, postedAt, conversationId, inReplyToTweetId, isReply, isQuote, isRetweet, quotedTweetId, quotedTweetUrl
MediamediaType, mediaUrl, mediaUrlOriginal, contentType, mediaId, mediaKey, thumbnailUrl, posterImageUrl, filename, fileSizeBytes, width, height, durationSeconds, focusRects, allowDownload
DownloaddownloadUrl, downloadStatus, message
Video qualityvariantQuality, variantBitrate, availableQualities, qualityCount, isBestQuality
AudioaudioFormat
AuthoruploaderUsername, uploaderName, uploaderVerified, uploaderAvatarUrl, uploaderFollowers
Post contexttweetText, likeCount, retweetCount, replyCount, quoteCount, bookmarkCount, viewCount, engagementRate, hashtags, mentions, urls
SourcemediaSource (post, quoted post or poster image)
ProfileprofileId, profileFollowers, profileMediaCount
RuncollectedAt

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 rateLimited or error status rows during an outage.