# Social Video Downloader - TikTok, Instagram, Facebook, X (`scrapewise/social-video-downloader`) Actor

Download TikTok, Instagram Reels, Facebook, X (Twitter), Reddit and Vimeo videos by URL as MP4 up to 1080p or MP3/M4A audio, from 1,000+ sites. A direct download link per video with title, author, duration and file size. Bulk links, no login. Errors are free.

- **URL**: https://apify.com/scrapewise/social-video-downloader.md
- **Developed by:** [Scrapewise Data](https://apify.com/scrapewise) (community)
- **Categories:** Videos, Social media
- **Stats:** 3 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $17.00 / 1,000 video downloadeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Social Video Downloader: TikTok, Instagram, Facebook, X (Twitter), Reddit

Social Video Downloader saves **public videos as MP4 files** from **TikTok, Instagram reels and video posts, Facebook
videos and reels, X (Twitter), Reddit, Vimeo, Dailymotion** and 1,000+ other video pages. Paste the links, run, and
get one row per video with a **direct download link** to the file, plus title, author, date, duration, resolution,
codec and file size.

Need only the sound? Turn on **Audio only** and get **M4A or MP3** files instead.

No login, no cookies, no browser extension. **US$ 0.02 per file downloaded. Errors are free.**

### Social video downloader at a glance

- **Price:** US$ 0.02 per video (or audio file) delivered, no run start fee, no monthly fee
- **Quality:** best available (up to 1080p), or cap it at 1080p, 720p, 480p or 360p
- **Formats:** MP4 video; M4A or MP3 audio
- **Download link:** every row has `downloadUrl`, a public link to the file that opens in a browser, `curl` or any app
- **What we charge for:** only files saved and delivered. Private, deleted, too-large, unsupported and duplicate links are free rows with an `errorCode`
- **Speed:** a short TikTok or reel takes about 2 to 5 seconds; 3 videos are downloaded at the same time

### What it fixes

- **Many links in one run,** from different sites mixed together: TikTok, Instagram, Facebook, X, Reddit, Vimeo and
  more. One row per video.
- **Every site, not only TikTok.** Each site in the table below is tested on Apify with real public links, and a
  link that fails gives a row that says why (`LOGIN_REQUIRED`, `NOT_FOUND`, `NOT_A_VIDEO`...) instead of an empty
  run marked as a success.
- **Best quality by default,** the same from the Console and from the API: the highest resolution the site serves
  (up to 1080p), or the cap you set with `quality`. `width`, `height` and the codecs are on every row.
- **Duration always in seconds** (`durationSeconds`), and file size in bytes, on every site.
- **No third-party download service in the middle,** so no expiring API keys, no "invalid API key" or "server error"
  outages, and no garbled binary text in the output: the file is in the run's storage and `downloadUrl` opens it.
- **Share text works.** Paste the whole text copied from an app ("Watch this! https://vm.tiktok.com/... #fyp"): the
  link inside is used.
- **Clear answers for what cannot be saved:** stories and private videos need a login (`LOGIN_REQUIRED`), and
  YouTube, Spotify and other DRM or unsupported pages return a free row instead of a broken file.

### Switching from another video downloader? Your existing input works

Paste the input you already use. These names and values are read as they are:

| You may already send | Read as |
|---|---|
| `postUrls`, `posts`, `videoUrls`, `tweetUrls`, `startUrls`, `link`, `videoUrl` (text or `{ "url": ... }`) | `urls` |
| `quality`: `best`, `1080`, `720`, `480`, `360` (also `1080p`, `hd`, `max`, `low`) | `quality` |
| `audioOnly`; `downloadMusic: true` with `downloadVideo: false` | `audioOnly` |
| `maxItems`, `maxFileSizeMb` | same names |

```json
{ "postUrls": ["https://www.instagram.com/reel/DaSz9gXgFla/"] }
```

```json
{ "videoUrls": ["https://www.tiktok.com/@natgeo/video/7549930445127896333"], "quality": "720" }
```

Options for other services (cloud buckets, link expiry, cover images, transcription) are accepted and ignored:
files always go to the run's key-value store with a signed `downloadUrl`.

### What the video downloader returns

TikTok video downloaded on Apify on 2026-10-07 (`quality: best`):

```json
{
  "type": "video",
  "url": "https://www.tiktok.com/@natgeo/video/7549930445127896333",
  "pageUrl": "https://www.tiktok.com/@natgeo/video/7549930445127896333",
  "platform": "TikTok",
  "id": "7549930445127896333",
  "title": "Ever wondered where you'd end up if you started digging a hole throug...",
  "author": "natgeo",
  "authorId": "6780344874811442181",
  "authorUrl": "https://www.tiktok.com/@natgeo",
  "publishedAt": "2025-09-14T13:07:07Z",
  "durationSeconds": 74.4,
  "width": 720,
  "height": 1280,
  "videoCodec": "hevc",
  "audioCodec": "aac",
  "fileSizeBytes": 3823392,
  "format": "mp4",
  "downloadUrl": "https://api.apify.com/v2/key-value-stores/qV9T0xMS4V1dpoVxw/records/tiktok-7549930445127896333.mp4?signature=1QpduAg0Bv4CRruUUsurm",
  "fileKey": "tiktok-7549930445127896333.mp4",
  "thumbnail": "https://p16-common-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/...",
  "viewCount": 1400000,
  "likeCount": 98900,
  "commentCount": 727,
  "errorCode": null
}
```

The row also carries `description` (the full caption), `source` (the link exactly as you gave it) and `scrapedAt`.

### Supported video sites

Tested on Apify on 2026-10-06 and 2026-10-07 with real public links:

| Site | Links that work | Tested |
|---|---|---|
| **TikTok** | `tiktok.com/@user/video/ID` | 2 of 2, up to 1080p |
| **Instagram** | `instagram.com/reel/CODE/`, `/p/CODE/`, `/tv/CODE/` | 2 of 2, up to 1080p |
| **Facebook** | `facebook.com/PAGE/videos/ID`, `/reel/ID`, `/watch/?v=ID` | 3 of 3, up to 1080p |
| **X (Twitter)** | `x.com/user/status/ID`, `twitter.com/...` | 2 of 2; a post with several videos gives one file per video |
| **Reddit** | `reddit.com/r/.../comments/ID/...`, `redd.it/ID`, `v.redd.it/ID`, share links | 2 of 2 |
| **Vimeo** | `vimeo.com/ID`, `player.vimeo.com/video/ID` | 1 of 1, 720p |
| **Dailymotion** | `dailymotion.com/video/ID` | 1 of 1 |
| **Other sites** | any page the open-source yt-dlp reads (Twitch clips, Loom, Bilibili, SoundCloud, news sites and more) | best effort |

Single videos only for now: profile, channel and playlist links come back as a free `NOT_A_SINGLE_VIDEO` row.

### Video downloader input

| Field | What it does |
|---|---|
| `urls` | Video links, one per line |
| `quality` | `best` (default), `1080`, `720`, `480` or `360`. Counts the short side, so `1080` means 1080x1920 for vertical videos |
| `maxCompatibility` | Prefer H.264 MP4, which plays in every player and editor, even at a lower resolution |
| `audioOnly` | Deliver the sound only, as `audioFormat` |
| `audioFormat` | `m4a` (default, original AAC sound) or `mp3` (192 kbps) |
| `maxItems` | Stop after this many files; 0 = every link |
| `maxFileSizeMb` | Larger files become a free `MEDIA_TOO_LARGE` row. Default 300, up to 2,000 |
| `proxyConfiguration` | Used only when a site refuses the first try |

Example: three short videos in H.264, up to 720p, ready for any video editor:

```json
{
  "urls": [
    "https://www.tiktok.com/@natgeo/video/7549930445127896333",
    "https://www.instagram.com/reel/DaSz9gXgFla/",
    "https://x.com/historyinmemes/status/1790637656616943991"
  ],
  "quality": "720",
  "maxCompatibility": true
}
```

Example: the sound of a reel as MP3:

```json
{
  "urls": ["https://www.instagram.com/reel/DaSz9gXgFla/"],
  "audioOnly": true,
  "audioFormat": "mp3"
}
```

### Where the downloaded videos are

Each file is saved in the **key-value store of the run** (Storage tab of the run, or the "Downloaded files" link in the
Output tab), and `downloadUrl` points straight to it. The link is signed, so it opens without an Apify token: share it,
send it to your app, or fetch it with `curl -o video.mp4 "<downloadUrl>"`.

Files of a run are kept as long as your Apify plan keeps run storage (7 days on most plans). Copy them to your own
storage if you need them longer, for example with an Apify integration or a webhook that reads the dataset.

Video guides from Apify: [how to schedule an Actor](https://www.youtube.com/watch?v=1jI7WcVQmwM) and [how to connect it to other apps](https://www.youtube.com/watch?v=bNACk1_S_6w).

#### Error codes (never charged)

| errorCode | Meaning |
|---|---|
| `NOT_FOUND` | Deleted, private or wrong link |
| `LOGIN_REQUIRED` | The site shows this video only to logged-in users (private accounts, friends-only posts, age-restricted videos) |
| `UNSUPPORTED_PLATFORM` | A YouTube link (see FAQ) |
| `NOT_A_SINGLE_VIDEO` | A profile, channel or playlist link instead of a video |
| `NOT_A_VIDEO` | A photo, carousel, text post or audio-only page (turn on `audioOnly` for audio pages) |
| `MEDIA_TOO_LARGE` | The file is above `maxFileSizeMb`; lower `quality` or raise the limit |
| `NO_AUDIO` | `audioOnly` was on and the video has no sound |
| `DRM_PROTECTED`, `LIVE_STREAM` | Protected streams and live broadcasts cannot be saved |
| `UNSUPPORTED_URL`, `INVALID_URL`, `INVALID_INPUT` | A link or value the Actor does not understand |
| `BLOCKED`, `DOWNLOAD_FAILED`, `CONVERSION_FAILED`, `STORAGE_FAILED` | The site or the file did not cooperate after retries; run again |
| `TIMEOUT_TOO_SHORT` | The run timeout was too short to download even one video; raise it |
| `NOT_REACHED`, `UNEXPECTED` | The run timeout or your spending limit arrived first, or something unforeseen broke; only that link is lost |

### Video downloader pricing

| Event | Price |
|---|---|
| Video downloaded (MP4, or M4A/MP3 with Audio only) | US$ 0.02 |

- 100 videos cost US$ 2.00; 1,000 videos cost US$ 20.
- An X post with two videos gives two files and costs US$ 0.04.
- Errors, duplicates in the same run and links not reached before the timeout are free. There is no Apify compute bill on top.
- On the Apify Free plan each run delivers up to 20 files.

### Social video downloader FAQ

**Can I download YouTube videos?** No. YouTube refuses requests from cloud servers, so every YouTube download would
need a paid residential proxy, and the price per video would be many times higher. YouTube links come back as a free
`UNSUPPORTED_PLATFORM` row. If what you need is the words spoken in a YouTube video, [YouTube Transcript](https://apify.com/scrapewise/youtube-transcript) returns its transcript.

**Why not the official TikTok or Instagram APIs?**
Those APIs are built for apps acting on behalf of a logged-in account, need an approved developer app, and cover that account's own content; they do not hand you the MP4 of any public video by its link. This Actor takes public links from many sites in one run, with no account or app review, and returns a direct download link per video.

**Does it remove the TikTok watermark?** It downloads the video stream TikTok's web player uses, which normally has no
watermark (the watermarked "save video" file is not used).

**Why is my video VP9 or HEVC?** Instagram, Facebook and TikTok often serve their highest resolution in these codecs.
They play on phones and modern browsers. If your editor or player refuses them, turn on `maxCompatibility` for H.264.

**Can it download private videos or stories?** No. Only videos anyone can watch without logging in.

**Can I give a profile and get all its videos?** Not yet; paste the links of the videos you want.

**How do I get the files into my own storage?** Read the dataset (JSON, CSV or Excel from the Output tab or the API)
and fetch each `downloadUrl`. Integrations such as Make, Zapier or n8n can do it after each run.

### Legal use of downloaded videos

Download only content you own, content you have a license for, or content whose owner allows it. Videos on social
networks are protected by copyright and by each platform's terms. You are responsible for how you use the files; this
Actor only saves videos that are already public and does not bypass logins, paywalls or DRM.

### Related scrapers

- [Audio & Video Transcriber](https://apify.com/scrapewise/media-transcriber): any video, audio file or podcast RSS to text.
- [TikTok Transcript Scraper](https://apify.com/scrapewise/tiktok-transcript): TikTok captions with views and likes.
- [Instagram Reels Transcript Scraper](https://apify.com/scrapewise/instagram-reels-transcript): reel and video to text.
- [X (Twitter) Tweet Scraper](https://apify.com/scrapewise/x-tweet-scraper): tweets by URL with media and video, no login.
- [Bulk Image Downloader](https://apify.com/scrapewise/bulk-image-downloader): download, resize, convert and ZIP images in bulk.

### Changelog

- **2026-10-09:** input from other video downloaders works as it is (see the table above); links inside pasted
  share text; quality names such as `1080p`, `hd` or `max`.
- **2026-10-07, 0.1:** first release. TikTok, Instagram, Facebook, X, Reddit, Vimeo, Dailymotion and other yt-dlp pages; quality cap, H.264 option, M4A/MP3 audio, signed download links, free error rows.

# Actor input Schema

## `urls` (type: `array`):

One link per line: TikTok videos, Instagram reels and video posts, Facebook videos and reels, X (Twitter) posts with video, Reddit video posts, Vimeo, Dailymotion and 1,000+ other video pages. Single videos only (not profiles or playlists). YouTube is not supported.

## `quality` (type: `string`):

Highest resolution up to this limit (the short side of the video, so 1080 also means 1080x1920 for vertical videos). When a video has nothing at or below the limit, the closest one above it is used.

## `maxCompatibility` (type: `boolean`):

Some sites serve their best quality as VP9 or H.265, which older players and some editors do not open. Turn this on to prefer H.264 MP4, even if it means a lower resolution.

## `audioOnly` (type: `boolean`):

Deliver only the sound of each video as an audio file (format below) instead of the MP4. Same price per file.

## `audioFormat` (type: `string`):

Used only with Audio only. M4A keeps the original AAC sound when possible; MP3 is re-encoded for players that need it.

## `maxItems` (type: `integer`):

Stop after this many files are delivered. 0 = no limit (every link). Apify Free plan runs are capped at 20 files.

## `maxFileSizeMb` (type: `integer`):

Larger videos come back as a free MEDIA_TOO_LARGE row instead of a file. Lower the quality to fit long videos under the limit.

## `proxyConfiguration` (type: `object`):

Videos are read from the server's own IP first (the fastest way). The proxy is used only when a site refuses that IP. Facebook videos that ask for login get one more try through the Apify residential proxy, used only to read the page, never to download the file.

## Actor input object example

```json
{
  "urls": [
    "https://www.tiktok.com/@natgeo/video/7549930445127896333",
    "https://www.instagram.com/reel/DaSz9gXgFla/"
  ],
  "quality": "best",
  "maxCompatibility": false,
  "audioOnly": false,
  "audioFormat": "m4a",
  "maxItems": 0,
  "maxFileSizeMb": 300,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `resultsCsv` (type: `string`):

No description

## `files` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://www.tiktok.com/@natgeo/video/7549930445127896333",
        "https://www.instagram.com/reel/DaSz9gXgFla/"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/social-video-downloader").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "urls": [
        "https://www.tiktok.com/@natgeo/video/7549930445127896333",
        "https://www.instagram.com/reel/DaSz9gXgFla/",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/social-video-downloader").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://www.tiktok.com/@natgeo/video/7549930445127896333",
    "https://www.instagram.com/reel/DaSz9gXgFla/"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapewise/social-video-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapewise/social-video-downloader"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dUuKTd0UemCMyAO9a/builds/GuH5qb3kyqVJCTGuK/openapi.json
