Request a tool
All toolsAutomationsGuidesMCP serverRequest a toolPlatformsCategories
X (Twitter) Video Downloader icon

X (Twitter) Video Downloader

Download the video from public X and Twitter posts as MP4, or the sound as MP3. No login or cookies. Pay per megabyte of file delivered.

46 runs on Apify $0.00045 per megabyte downloaded ($0.45 / 1,000)
Run this in the cloudRun on Apify →

Developer & Research Tools

How it works

  1. 1
    Open it on Apify

    Hit Run on Apify — it opens the tool in the cloud, no install.

  2. 2
    Set the inputs

    Adjust urls, quality, audioOnly (sensible defaults are pre-filled).

  3. 3
    Click Run

    The tool runs on Apify’s cloud and collects the data for you.

  4. 4
    Export the results

    Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.

Pricing

$0.00045 per megabyte downloaded = $0.45 per 1,000

You are charged forWhenPrice
Megabyte downloadedEach 1 MB of media actually delivered, rounded up per file. Failed, refused or skipped downloads are not charged.$0.00045

Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-09-13, and they are what you are actually charged.

Inputs

FieldWhat it doesType
urlsOne link per line, each to an X post with a video in it (x.com/name/status/...); twitter.com links work the same. A post holding several videos gives the first one; end the link with /video/2 for the second. Links from other sites are refused, with a pointer to the downloader that takes them.array
qualityMeasured on the short side of the picture, so 1080 means 1920x1080 for a landscape video and 1080x1920 for a vertical one. If a video doesn't come in that quality you get the closest one it has. You pay per megabyte, so a higher quality costs more.string
audioOnlySave just the video's sound, as a 128 kbit/s MP3, instead of the video.boolean
maxMegabytesA video bigger than this is skipped before it is downloaded, and you are not charged for it. One run can hold files up to about 70% of its memory (716 MB at the default 1024 MB), so for anything bigger raise the run's memory as well.integer

What you get

A structured dataset — each result includes fields like:

titleauthordurationSecondsresolutionformatfileSizeBytesbilledMegabytesmediaUrlurlhostmediaKey

Export every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.

Related tools in Developer & Research Tools

Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.

GitHub Scraper iconDeveloper & Research Tools

GitHub Scraper

Search GitHub repos and users: stars, forks, language, topics, licence, plus user bio, company and followers. No token needed. $0.90 per 1,000 rows.

18 use cases

Stack Overflow / Stack Exchange Scraper iconDeveloper & Research Tools

Stack Overflow / Stack Exchange Scraper

Search Stack Overflow and Stack Exchange by keyword or tag. Score, answer count, views, reputation and body text. $2 per 1,000 questions.

2 use cases

Package Registry Scraper (npm + PyPI) iconDeveloper & Research Tools

Package Registry Scraper (npm + PyPI)

Get npm and PyPI package metadata as JSON. Version, license, author, repo, keywords and npm monthly downloads. $2 per 1,000 packages.

2 use cases

arXiv Scraper iconDeveloper & Research Tools

arXiv Scraper

Search arXiv papers by title, author, abstract or category. Get full abstracts, authors, categories, DOI, dates and PDF links. $2 per 1,000 papers.

2 use cases

OpenAlex Scholarly Works Scraper iconDeveloper & Research Tools

OpenAlex Scholarly Works Scraper

Search 250M+ OpenAlex papers with no API key. Get titles, authors, venue, year, citations, DOI, OA links and full abstracts. $2.00 per 1,000 papers.

2 use cases

Crossref Scholarly Works Scraper iconDeveloper & Research Tools

Crossref Scholarly Works Scraper

Search 150M+ papers on Crossref: DOI, title, authors, journal, publisher, date, citations and abstract. No API key. $1.00 per 1,000 works.

2 use cases

See all Developer & Research Tools →

X (Twitter) Video Downloader: save the video from a public post as MP4, or its sound as MP3

Paste links to public X or Twitter posts, one per line. Each video is saved into the run's key-value store as a real file, and the dataset row that goes with it carries a direct download link, the title, the author, the resolution and the exact file size.

The part worth knowing first: this only reaches posts anyone can open signed out. A protected account, a post behind a login, or a deleted one comes back as a sentence in the run's ERRORS record and costs nothing.

InputPublic x.com or twitter.com post links
OutputAn MP4 or MP3 file per link, plus one dataset row listing it
Ceiling500 MB per video by default, 4,000 MB at most
Account neededNone
Price$0.00045 per megabyte delivered, flat on every plan

🎬 What X Video Downloader does

You give it post links. For each one it reads the post, picks the format, checks the file size before a single media byte moves, downloads it, checks the file actually decodes, stores it, and only then lists it in the dataset.

X publishes the same picture twice, as one ready-made MP4 and as a streaming version split into picture and sound. This takes the ready-made MP4, so the file arrives whole with its audio already in it and its size known in advance. Nothing is stitched together afterwards.

With Audio only on you get a 128 kbit/s MP3 of the same post instead.

No login, no cookies, nothing to paste in besides the link.

📥 What you give it

{
  "urls": [
    "https://x.com/historyinmemes/status/1790637656616943991",
    "https://twitter.com/someone/status/1234567890123456789"
  ],
  "quality": "1080",
  "audioOnly": false,
  "maxMegabytes": 500
}
FieldDefaultWhat it is
urlsrequiredOne link per line. x.com and twitter.com both work, with or without www. or mobile.. Query strings are ignored.
quality1080best, 1080, 720, 480 or 360, measured on the short side of the picture. A video that does not come in that size gives you the closest it has.
audioOnlyfalseAn MP3 of the sound instead of the video.
maxMegabytes5001 to 4,000. A video bigger than this is skipped before it is downloaded.

A post with several videos gives you the first one. End the link with /video/2 to ask for the second instead.

Duplicates are dropped, and a link that points somewhere else is refused with a note telling you which actor takes it. A t.co short link is refused too: open it, and paste the address it lands on.

File size is bounded by the run's memory. A run can hold a file of roughly 70% of the memory it was given, so about 716 MB at the default 1,024 MB. If you want something bigger than that, raise the run's memory as well as maxMegabytes.

📤 What you get back

Two things per link: the file in the run's key-value store, and a row in the dataset pointing at it.

A real row, from run 4kPIloPIN7IwX9npC, with the signed link trimmed:

{
  "url": "https://x.com/historyinmemes/status/1790637656616943991",
  "host": "x",
  "title": "Historic Vids - One of the most intense moments in history",
  "author": "Historic Vids",
  "durationSeconds": 15.56,
  "resolution": "728x720",
  "format": "mp4",
  "fileSizeBytes": 1404023,
  "billedMegabytes": 2,
  "mediaKey": "x-1790637589910654976.mp4",
  "mediaUrl": "https://api.apify.com/v2/key-value-stores/E2Boy2HNCFDNWIzez/records/x-...?signature=..."
}
FieldWhat it is
mediaUrlA ready-to-use download link to the stored file. This is what you hand to whatever comes next.
mediaKeyThe record name in the run's key-value store. It uses the media id, which is not the post id.
fileSizeBytesThe size of the stored file, read back after it was written.
billedMegabytesWhat that file counted as, in whole megabytes.
titleThe account name, then the post's text.
resolution, durationSecondsRead off the finished file, not off the post.

🧾 Reading the output

A failure never reaches the dataset. Every row in there is a file that exists and was stored.

Links that did not work go into a key-value record called ERRORS, each as {url, error} with the reason written in plain words. It is saved as each failure happens, so a run that runs out of time still tells you what it managed and what it did not.

The sentences you will actually see:

What you readWhat it means
"This post is gone, or its video was removed."The post or its media is no longer there.
"This post is only visible to signed-in accounts."Protected or otherwise not public. Only public posts can be read.
"This post has no video in it."A photo or text post, or a GIF with no video stream.
"X is limiting requests right now."Too many in a short time. Come back in a few minutes.
"t.co is X's link shortener."Open it in a browser and paste the address it lands on.
"This video has no sound to turn into an MP3."Audio-only was asked for on a silent video.

If every link in a run fails, the run ends as failed and the status message points at ERRORS.

▶️ How to run it

1. Open X (Twitter) Video Downloader and click Try for free. 2. Paste your post links into X post links, one per line. 3. Pick a Max quality, or tick Audio only (MP3). 4. Set Max megabytes per video if you want a tighter cap than 500. 5. Click Start, then take mediaUrl from each dataset row, or open the run's Storage tab.

💰 How much does it cost?

$0.00045 for every megabyte delivered, counted in whole megabytes and the same on every Apify plan. The 15-second clip in the example above counted as 2 MB.

You are billed only after a file is stored and listed, so a link that fails, a post that is private or gone, a link to another site, and a video skipped for being over maxMegabytes all add no megabytes. A run that delivers no files has none to bill.

Higher quality means a bigger file, and a bigger file costs more. audioOnly is much smaller than video on the same post.

💡 What people use it for

  • Keeping a copy of a clip before the post that carries it disappears.
  • Pulling the audio out of an interview or a speech to transcribe it somewhere else.
  • Feeding mediaUrl into an editor, a captioner or an uploader as the next step in a pipeline.
  • Archiving a set of posts at a fixed quality so file sizes stay predictable.

🚧 What it does not do

  • Public posts only. Protected accounts and anything behind a login fail with a sentence saying so.
  • No photos, no GIF-only posts, no Spaces and no broadcasts.
  • The first video of a multi-video post unless you ask for another with /video/<n>.
  • No post text, likes, replies or metrics. The title carries the post's text and that is all.

For the post as data, use a scraper instead.

  • No t.co links. They are refused with an instruction rather than followed.
  • No subtitles or captions.
  • Files live in the run's key-value store, which is not permanent. Copy anything you want to

keep, and treat mediaUrl as a link to fetch now rather than store for later.

  • One file per link, so a run's total is bounded by what the run can hold in memory.

🧭 Which downloader do you need?

If you wantUse
The video from an X or Twitter postThis one
A YouTube video, up to 8K, or its audio or captionsYouTube Downloader Pro
A TikTok videoTikTok Video Downloader
A Facebook video or reelFacebook Video Downloader
Posts as data rather than as filesTweet Scraper

❓ Questions people ask

Do I need an X account or cookies? No. Nothing to paste in and nothing that expires.

Where is my file? In the run's key-value store. The fastest way to it is mediaUrl on the dataset row; the Storage tab of the run shows the same records under mediaKey.

Can I download a whole account's videos? Not from here. This takes links you supply. Use a scraper to collect the post links first, then feed them in.

Why is my video smaller than 1080p? Because the post does not have a 1080p version. You get the closest size X published.

What happens if one link is dead? It goes to ERRORS with a reason, adds nothing to your bill, and the run carries on with the rest.

Is downloading these videos legal? The post being public does not make the video yours. Copyright still applies, and so does data-protection law where a person is identifiable. Have a reason for what you are collecting. Apify's write-up on scraping and the law is a fair start, and we are not lawyers.

🆘 If something breaks

Open the Issues tab on the actor page. Send the run ID and the exact post link, and paste the ERRORS record from the run's key-value store: it carries the sentence for every link that failed.