Twitter Video Downloader - X Video to MP4, Tweet Video Saver
Pricing
from $0.20 / 1,000 sd video seconds
Twitter Video Downloader - X Video to MP4, Tweet Video Saver
Download Twitter and X videos as MP4 from tweet URLs or IDs. 720p costs $0.40 per 1,000 seconds, no proxy costs, 3 quality tiers. Saves to Apify, AWS S3, Google Cloud, Spaces or Azure for marketing, newsroom and research teams.
Pricing
from $0.20 / 1,000 sd video seconds
Rating
4.9
(8)
Developer
epctex
Maintained by Apify PartnerActor stats
14
Bookmarked
251
Total users
1
Monthly active users
1.2 days
Issues response
15 hours ago
Last modified
Categories
Share
Twitter Video Downloader: X Video to MP4
Twitter Video Downloader is an Apify actor that downloads MP4 videos from tweet URLs (twitter.com, x.com) or tweet IDs into Apify storage, AWS S3, Google Cloud, DigitalOcean Spaces or Azure. 720p video costs $0.0004 per second, or $0.40 per 1,000 seconds, with no platform or proxy costs.
The Twitter Video Downloader accepts 2 input identifiers, offers 3 quality tiers, writes to 5 storage targets, returns 12 fields per video and bills through 3 pay-per-event charge events. Every row carries 1 of 6 status values and states exactly what it cost.
What Does the Twitter Video Downloader Extract?
The Twitter Video Downloader extracts the video files attached to a tweet and delivers each one as a stored MP4 with a stable download link. The table below lists the 6 capabilities the actor provides.
| Capability | Twitter Video Downloader behavior |
|---|---|
| Video file | Downloads the video/mp4 variant of each video in the tweet. HLS playlists (application/x-mpegURL) are never selected. |
| Quality tier | Picks low, medium or high from the tweet's own bitrate ladder. |
| Re-hosting | Stores the file in the chosen storage target, so the output link replaces Twitter's short-lived media URL. |
| Multi-video tweets | Downloads every video in a tweet, numbered by videoPosition starting at 1. |
| Per-row cost | Writes durationSeconds, unitPricePerSecond and totalCost on every charged row. |
| Per-row status | Writes 1 of 6 status values on every row, including tweets that produced no video. |
The Twitter Video Downloader returns video files only. Tweet text, author profiles, engagement counts and thumbnails are outside its output.
Which Tweet Inputs Does the Twitter Video Downloader Accept?
The Twitter Video Downloader accepts 2 input identifiers: tweet URLs in videoUrls and raw tweet IDs in videoIds. A run needs at least 1 entry across the 2 lists, and both lists can be combined in one run.
videoUrlstakes tweet URLs such ashttps://x.com/tina__nigro/status/1677753111161569281. The URL needs anhttporhttpsscheme, atwitterorxhostname label (sotwitter.com,x.comandmobile.twitter.comall resolve), and a/status/{digits}path.videoIdstakes numeric tweet IDs such as1677753111161569281. The Twitter Video Downloader reports each ID ashttps://x.com/i/status/{id}insourceUrl.
The Twitter Video Downloader removes duplicates by tweet ID across both lists, so a twitter.com link, an x.com link and a raw ID pointing to the same tweet are downloaded and charged once. The first occurrence keeps its queryIndex.
Who Uses the Twitter Video Downloader?
Listed below are the 5 roles that run the Twitter Video Downloader against X (Twitter) video content.
- Social media and marketing teams archive campaign and competitor videos to their own S3 or Google Cloud bucket, then read
downloadUrlandsourceUrlto link each stored file back to its tweet. - Media monitoring and newsroom teams collect videos from breaking-news tweets by URL, then use
statusvaluesunavailableandnoVideoContentto separate deleted tweets from tweets without video. - Machine learning and research teams build video datasets at a fixed
qualitytier, then readdurationSecondsandvideoPositionto index clips per tweet. - Compliance and legal archiving teams preserve evidence copies in Azure or DigitalOcean Spaces under a set
azurePathordigitalOceanPath, then keepjobIdas the download record. - Developers and automation builders call the Twitter Video Downloader through the Apify API on a paid plan with
videoIds, then reconcile spend per row withtotalCostandinputSource.queryIndex.
Each of these roles pays per second of video delivered, and the rate depends on resolution.
What Does the Twitter Video Downloader Cost?
The Twitter Video Downloader charges 3 event types, one per resolution band: $0.0002, $0.0004 and $0.0008 per second of video. Pricing is pay-per-event with no platform or proxy costs on top.
The rate card below lists the 3 charge events.
| Event | Resolution (short side) | Price per second |
|---|---|---|
tw-video-download-sd | below 720p | $0.0002 |
tw-video-download-hd | 720p up to below 1080p | $0.0004 |
tw-video-download-fhd | 1080p and above | $0.0008 |
The Twitter Video Downloader applies 4 billing rules:
- Duration is rounded up to the next whole second, with a minimum of 1 second. A clip with no reported duration, such as an animated GIF, is charged as 1 second.
- Resolution is read from the delivered file, not from the requested
quality.highon a tweet whose best file is 480p is charged at the SD rate. When the file's frame size cannot be read, the event followsquality:lowbills SD,mediumbills HD,highbills FHD. - Orientation does not change the band, because the short side is measured. A vertical 720x1280 video bills as HD.
- Timing is once per video, right after the video is confirmed downloadable and right before its download job starts.
Twitter Video Downloader Cost Examples
The table below prices 5 scenarios against the rate card above.
| Scenario | Charge event | Calculation | Total cost |
|---|---|---|---|
| 13-second 720p clip | tw-video-download-hd | 13 × $0.0004 | $0.0052 |
| 60-second 720p video | tw-video-download-hd | 60 × $0.0004 | $0.024 |
| 2-minute 1080p video | tw-video-download-fhd | 120 × $0.0008 | $0.096 |
| Animated GIF, no duration, 480p | tw-video-download-sd | 1 × $0.0002 | $0.0002 |
| 1,000 videos of 30 seconds at 720p | tw-video-download-hd | 30,000 × $0.0004 | $12.00 |
Twitter Video Downloader Unit Economics
The 4 figures below are derived from the rate card above. Every figure is the full charge, because the Twitter Video Downloader has no separate per-item or per-start event.
| Metric | SD (below 720p) | HD (720p up to below 1080p) | FHD (1080p and above) |
|---|---|---|---|
| Cost per minute of video | $0.012 | $0.024 | $0.048 |
| Cost per hour of video | $0.72 | $1.44 | $2.88 |
| Cost per 1,000 seconds | $0.20 | $0.40 | $0.80 |
| Seconds of video per $1 | 5,000 | 2,500 | 1,250 |
The FHD rate is 4 times the SD rate and 2 times the HD rate.
When Does the Twitter Video Downloader Not Charge?
The Twitter Video Downloader charges nothing in 5 cases:
- The input is not a supported tweet URL or a valid tweet ID (
invalidUrl). - The tweet is private, deleted, age-restricted or does not exist (
unavailable). - The tweet has no video, or its video has no MP4 variant (
noVideoContent). - The run reached its soft deadline before the video started (
timedOut). - The whole video does not fit within the remaining max cost per run. The video is skipped, nothing is charged for it and the run stops picking up new tweets.
A download that fails or times out after it starts is still charged, and its row is written with status set to failed or timedOut.
How Does the Twitter Video Downloader Demo Mode Work?
The Twitter Video Downloader runs in demo mode for Free-plan users, so the actor can be tried without a subscription. Demo mode applies 3 limits:
- 5 runs per month on the Free plan.
- 10 items per run. This cap overrides any
maxItemsvalue, so a Free-plan run never returns more than 10 items. - No API access. The Twitter Video Downloader API is not available on the Free plan.
A paid plan removes these limits for unrestricted use.
How Is the Twitter Video Downloader Configured?
The Twitter Video Downloader exposes 28 input fields in its input form: 4 core fields, 4 delivery fields and 20 storage fields split across 4 cloud providers. quality and storageType are required, and 1 of videoUrls or videoIds has to contain an entry.
The table below lists the 4 core fields and the 4 delivery fields.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
videoUrls | array | 1 of videoUrls or videoIds | none | Tweet URLs to download videos from. |
videoIds | array | 1 of videoUrls or videoIds | none | Raw tweet IDs to download videos from. |
quality | string | Yes | high | Quality tier: low, medium or high. |
storageType | string | Yes | apify | Storage target: apify, aws, gcp, digitalocean or azure. |
outputConnector | string | No | none | MCP connector to deliver the results to. See How Do You Send Twitter Video Downloader Results to Notion, Todoist and More? |
deliverTarget | string | No | none | Where the connector writes: a page or database URL or ID (Notion example: https://www.notion.so/My-Posts-24f8a1b2c3d44e5f8a9b0c1d2e3f4a5b). Some services need none. |
deliverMode | string | No | perPost | perPost writes one record per video, summary one roll-up per run. |
deliverMaxItems | integer | No | none | Maximum number of records perPost delivers. Ignored in summary. |
The Twitter Video Downloader also reads maxItems (integer) from API input. maxItems caps the number of downloaded videos on paid plans, and the lower of maxItems and the plan limit applies. On the Free plan, the 10-items-per-run demo cap overrides maxItems. maxItems does not appear in the input form.
How Does the Twitter Video Downloader Pick a Quality Tier?
The Twitter Video Downloader sorts a video's MP4 variants by bitrate and picks a position in that list: low takes the smallest file, high takes the highest bitrate, and medium takes the middle entry. Twitter exposes a variable number of bitrate tiers per tweet rather than fixed pixel resolutions, so quality selects a rank, not an exact resolution. On a tweet with only 1 MP4 variant, all 3 tiers return the same file.
Which Storage Targets Does the Twitter Video Downloader Support?
The Twitter Video Downloader supports 5 storage targets. The table below lists the fields each one uses.
storageType | Provider | Required fields | Optional fields |
|---|---|---|---|
apify | Apify key-value store | none | none |
aws | Amazon Web Services S3 | s3AccessKeyId, s3SecretAccessKey, s3Region, s3Bucket | s3Path |
gcp | Google Cloud Storage | googleCloudProjectId, googleCloudServiceKeyJson, googleCloudBucketName | googleCloudPath |
digitalocean | DigitalOcean Spaces | digitalOceanAccessKeyId, digitalOceanSecretAccessKey, digitalOceanRegion, digitalOceanBucketName | digitalOceanEndpoint, digitalOceanAcl, digitalOceanPath |
azure | Microsoft Azure Storage | azureAccountName, azureAccountKey, azureContainerName | azurePath |
With storageType set to apify, the Twitter Video Downloader creates a named key-value store called tw-download-{runId} and uploads every video of the run into it. No cloud account or credentials are required. A named store is kept after the run ends.
The Twitter Video Downloader marks 4 credential fields as secret: s3SecretAccessKey, googleCloudServiceKeyJson, digitalOceanSecretAccessKey and azureAccountKey. googleCloudServiceKeyJson takes the service account credentials as a JSON object. digitalOceanRegion takes a Spaces region such as nyc3, and digitalOceanAcl defaults to private. Each *Path field sets a folder inside the bucket or container.
Which Input Rules Does the Twitter Video Downloader Enforce?
The Twitter Video Downloader enforces 6 input rules. The table below lists each rule and its outcome.
| Rule | Outcome when broken |
|---|---|
At least 1 entry across videoUrls and videoIds | The run fails with Tweet URLs or tweet IDs must be provided. |
Every required field of the chosen storageType is set | The run fails with a message naming the missing field, such as AWS region is missing. |
storageType apify has an Apify token available | The run fails with Apify token is missing. |
A URL has an http or https scheme, a twitter or x hostname and a /status/{digits} path | The entry becomes an invalidUrl row, uncharged, and the run continues. |
| A tweet ID contains digits only | The entry becomes an invalidUrl row, uncharged, and the run continues. |
| The max cost per run covers at least 1 second of SD video ($0.0002) | The run stops before any download with a message asking for a higher max cost per run. |
The Twitter Video Downloader caps spend at the lower of the plan limit and the max cost per run set on the run.
How Do You Download a Twitter Video to Apify Storage with the Twitter Video Downloader?
The Twitter Video Downloader stores videos in Apify storage when storageType is apify, which needs no credentials. The input below downloads the highest-bitrate MP4 of 1 tweet.
{"videoUrls": ["https://x.com/tina__nigro/status/1677753111161569281"],"quality": "high","storageType": "apify"}
How Do You Download Twitter Videos to AWS S3 with the Twitter Video Downloader?
The Twitter Video Downloader uploads to an S3 bucket when storageType is aws and the 4 required S3 fields are set. The input below combines 1 URL and 1 raw tweet ID at medium quality into the twitter/videos folder.
{"videoUrls": ["https://twitter.com/tina__nigro/status/1677753111161569281"],"videoIds": ["1677753111161569281"],"quality": "medium","storageType": "aws","s3AccessKeyId": "YOUR_ACCESS_KEY_ID","s3SecretAccessKey": "YOUR_SECRET_ACCESS_KEY","s3Region": "us-east-1","s3Bucket": "my-video-archive","s3Path": "twitter/videos"}
The 2 entries above point to the same tweet, so the Twitter Video Downloader downloads and charges for it once.
How Do You Send Twitter Video Downloader Results to Notion, Todoist and More?
The Twitter Video Downloader can deliver its results straight into the tools you already use, through Apify MCP Connectors.
- Authorize a connector (Notion, Todoist, or any service whose MCP server offers non-destructive write tools) once in Console → Settings → API & Integrations → MCP connectors.
- Pick it in the Send results to Notion, Todoist, … field.
- Fill in where and how to write:
- Destination target: the page or database URL or ID (Notion example:
https://www.notion.so/My-Posts-24f8a1b2c3d44e5f8a9b0c1d2e3f4a5b). Share it with your connector first through Notion's ••• → Connections menu. Some services need no target. - Write mode:
perPostwrites one record per video;summarywrites a single roll-up for the run. - Max records to deliver (optional): a cap on how many records
perPostdelivers.
- Destination target: the page or database URL or ID (Notion example:
Each video becomes one record with its status, source URL and download link. Videos that were not downloaded are delivered too, with their status and error, so the destination doubles as a download log. With storageType set to apify, the links point to the named key-value store, which is kept after the run ends.
Notion: point the target at a Notion page and the Actor creates a database with one typed column per field (URL, number, date, text). An existing database gets its matching columns filled by name. The connector can't add columns to it, so an empty database receives only titles and the rest of each record goes to the row's page body. Nested fields become columns too: the inputSource object becomes inputSource.queryIndex and inputSource.url, and durationSeconds and totalCost become number columns. Fields without a column go to the row's page body, so nothing is lost.
Your credentials stay with you: the Actor writes only through your own connector and only uses non-destructive write tools, so it can't delete or overwrite anything. Delivery runs after the scrape and is best-effort. If it fails, the run still finishes normally with all results in the dataset, and the run log says what went wrong. If the run is close to its timeout, delivery stops early so the run still succeeds, and the log says how many records were delivered.
Which Fields Does the Twitter Video Downloader Output?
The Twitter Video Downloader outputs 12 fields per dataset row, 1 of them an object with 2 nested fields. The actor writes 1 row per video, and 1 row per tweet that produced no video.
| Field | Type | Description |
|---|---|---|
sourceUrl | string | The tweet URL as given, or https://x.com/i/status/{id} for a raw ID. |
videoPosition | integer or null | 1-based index of the video within the tweet. |
downloadUrl | string or null | Link to the stored file. Set only when status is succeeded. |
quality | string or null | The requested tier: low, medium or high. |
storageType | string or null | The storage target the file was written to. |
status | string | 1 of 6 status values, listed below. |
jobId | string or null | Identifier of the download job. |
error | string or null | Reason the video was not delivered. |
durationSeconds | integer or null | Charged seconds, rounded up, minimum 1. Null when the video was not charged. |
unitPricePerSecond | number or null | Rate of the charged event. Null when the video was not charged. |
totalCost | number | durationSeconds × unitPricePerSecond, or 0 when the video was not charged. |
inputSource | object | queryIndex (integer position in the input) and url (the input entry). |
Twitter Video Downloader Status Values
The Twitter Video Downloader writes 6 status values. 2 of them are charged.
status | Meaning | Charged |
|---|---|---|
succeeded | The video was downloaded and stored. downloadUrl is set. | Yes |
invalidUrl | The entry is not a supported tweet URL or a valid tweet ID. | No |
unavailable | The tweet is private, deleted, age-restricted or does not exist. | No |
noVideoContent | The tweet has no video, or no MP4 variant. | No |
failed | The download job could not be created or did not complete. | Yes |
timedOut | The run ran out of time before or during the download. | Only when the download had started |
Twitter Video Downloader Output Example
The row below is a succeeded 13-second 720p video stored in Apify storage.
{"sourceUrl": "https://x.com/tina__nigro/status/1677753111161569281","videoPosition": 1,"downloadUrl": "https://api.apify.com/v2/key-value-stores/.../records/tw-1677753111161569281-1","quality": "high","storageType": "apify","status": "succeeded","jobId": "550e8400-e29b-41d4-a716-446655440000","error": null,"durationSeconds": 13,"unitPricePerSecond": 0.0004,"totalCost": 0.0052,"inputSource": {"queryIndex": 0,"url": "https://x.com/tina__nigro/status/1677753111161569281"}}
The Twitter Video Downloader names each stored file tw-{tweetId}-{videoPosition}, so 2 videos in the same tweet never overwrite each other.
Which Errors Does the Twitter Video Downloader Report?
The Twitter Video Downloader reports 10 error codes in the run log. 7 of the 10 codes are non-terminal: the run logs them and moves to the next tweet or video. 3 codes terminate the run: C098, C099 and C100.
The 7 non-terminal codes split into 3 recovery behaviors:
- 3 codes (
C001,C002,C005) write an uncharged row withstatusinvalidUrl,unavailableornoVideoContent.C005writes itsnoVideoContentrow only when a video has no MP4 variant; a queued tweet that fails to process logsC005and writes no row. - 2 codes (
C006,C007) write a charged row withstatusfailed, because the video was charged before its download job started. - 2 codes (
C003,C004) log the tweet as unresolved and write no row for it.
The table below lists all 10 codes.
| Code | Cause | Twitter Video Downloader behavior |
|---|---|---|
C001 | The entry is not a tweet URL or a tweet ID. | Writes an invalidUrl row, uncharged. |
C002 | The tweet is private, deleted, age-restricted or does not exist. | Writes an unavailable row, uncharged. |
C003 | The tweet could not be resolved. | Logs the tweet, writes no row. |
C004 | The tweet could not be processed. | Logs the tweet, writes no row. |
C005 | A video has no MP4 variant, or a queued tweet failed to process. | Writes a noVideoContent row, uncharged, for a missing MP4 variant. Logs a failed queued tweet without a row. |
C006 | The download job could not be created. | Writes a failed row, charged. |
C007 | The download job did not succeed. | Writes a failed row, charged, with the job's error in error. |
C098 | Unhandled promise rejection. | Ends the run. |
C099 | Uncaught exception. | Ends the run. |
C100 | The run could not be initialized. | Ends the run. |
For C098, C099 and C100, the run log asks for the run ID to be sent to support.
How Does the Twitter Video Downloader Handle the Run Timeout?
The Twitter Video Downloader sets a soft deadline shortly before the run timeout. At that point, tweets that have not started are written as uncharged timedOut rows, downloads in progress stop waiting and report timedOut, and every finished video keeps its row. The run then ends as succeeded instead of being killed mid-write. Runs without a timeout have no soft deadline.
Which Twitter Video Downloader Questions Come Up Most Often?
Does the Twitter Video Downloader work with x.com links?
Yes. The Twitter Video Downloader accepts x.com, twitter.com and subdomains such as mobile.twitter.com, as long as the path contains /status/{digits}.
Does the Twitter Video Downloader need a Twitter account or cloud account?
No cloud account is needed. The Twitter Video Downloader stores files in Apify storage when storageType is apify, and it takes no Twitter login fields as input.
Can the Twitter Video Downloader download videos from private tweets?
No. The Twitter Video Downloader writes an uncharged unavailable row for private, deleted and age-restricted tweets.
Can the Twitter Video Downloader be used for free?
Yes, in demo mode. Free-plan users get 5 runs per month and 10 items per run, without API access.
Does the Twitter Video Downloader download GIFs?
Yes, when the GIF is delivered as an MP4 variant. The Twitter Video Downloader charges a GIF without a reported duration as 1 second.
Which file format does the Twitter Video Downloader deliver?
The Twitter Video Downloader delivers MP4. HLS playlist variants are never selected.
Why was the Twitter Video Downloader charged at SD when quality was high?
The Twitter Video Downloader bills by the resolution of the delivered file. high picks the best bitrate the tweet offers, and when that file's short side is below 720 pixels, the SD rate of $0.0002 per second applies.
Does the Twitter Video Downloader charge for duplicate tweets?
No. The Twitter Video Downloader removes duplicates by tweet ID across videoUrls and videoIds before downloading.
Does the Twitter Video Downloader download every video in a tweet?
Yes. The Twitter Video Downloader downloads every MP4 video in the tweet and numbers each one with videoPosition, charging each video separately.
How long do Twitter Video Downloader links stay valid?
The Twitter Video Downloader re-hosts every file in the chosen storage target, so downloadUrl follows the retention of that storage rather than Twitter's media URL. With storageType apify, the file sits in the named store tw-download-{runId}, which is kept after the run ends.
What happens when the Twitter Video Downloader reaches the max cost per run?
The Twitter Video Downloader skips any video whose full cost does not fit in the remaining budget, charges nothing for it and stops picking up new tweets. Videos already charged keep downloading and write their rows.
Does the Twitter Video Downloader return tweet text or author data?
No. The Twitter Video Downloader returns the 12 fields listed in its output schema, which describe the video file, its storage location, its status and its cost.
Where Do You Get Twitter Video Downloader Support?
The Twitter Video Downloader is published by epctex. Support is available at business@epctex.com and through the chat box on epctex.com, which also lists custom integrations and the full epctex product catalog. Include the run ID when reporting error codes C098, C099 or C100.