# TikTok Video Downloader - Short Links & Multi-Cloud Storage (`epctex/tiktok-video-downloader`) Actor

$3 per 1,000 TikTok videos, or $0.003 each. Downloads from post URLs, photo posts, and short links, for content teams, compliance teams, and ML pipelines. Re-hosts to Apify, AWS S3, Google Cloud, DigitalOcean, or Azure storage.

- **URL**: https://apify.com/epctex/tiktok-video-downloader.md
- **Developed by:** [epctex](https://apify.com/epctex) (community)
- **Categories:** Social media, Videos
- **Stats:** 949 total users, 60 monthly users, 99.2% runs succeeded, 40 bookmarks
- **User rating**: 4.96 out of 5 stars

## Pricing

$3.00 / 1,000 download videos

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## TikTok Video Downloader

TikTok Video Downloader is a commercial-grade utility actor built for teams that need TikTok videos downloaded and re-hosted reliably, without maintaining scraping or storage infrastructure in-house. Give it TikTok post URLs — or short links you haven't even expanded yet — and it resolves each one, downloads the video, and delivers a stable link to the storage of your choice.

The actor is designed around a single operating mode: direct URL resolution. Every entry in `startUrls` is processed independently within the same job, so a run can mix canonical post URLs, short links, and photo-mode posts, with each one reported on its own dataset row regardless of the outcome.

### TikTok Video Downloader Capabilities

The actor supports the following features:

- **Download by URL** — Accepts canonical TikTok post URLs (`tiktok.com/@user/video/{id}`) and short links (`vt.tiktok.com`, `vm.tiktok.com`, `tiktok.com/t/…`), resolved automatically.
- **Multi-cloud storage** — Deliver to Apify's built-in key-value store with zero setup, or bring your own AWS S3, Google Cloud Storage, DigitalOcean Spaces, or Azure Blob Storage.
- **Stable re-hosted links** — Every downloaded video is re-hosted to your chosen storage, so you get a permanent link instead of TikTok's own short-lived signed URL.
- **Regional CDN targeting** — An optional two-letter region code selects which TikTok CDN edge the video is fetched from.
- **Custom output shaping** — Apply a `customMapFunction` to transform each output item before it's saved.
- **Automatic deduplication** — The same post is only downloaded and charged once per run, even if it appears twice in your input.

### Supported TikTok Sources

| TikTok Source | How to Target It | What It Covers |
|---|---|---|
| Video post | Canonical URL `tiktok.com/@user/video/{id}` in `startUrls` | The post's video, re-hosted to your storage, along with its title and cover image |
| Photo-mode post | Canonical URL `tiktok.com/@user/photo/{id}` in `startUrls` | Recognized as a valid post; reported with no video since it holds a slideshow of images rather than a video, and is never charged |
| Short link | `vt.tiktok.com/...`, `vm.tiktok.com/...`, or `tiktok.com/t/...` in `startUrls` | Resolved to the underlying post automatically — no need to expand it yourself |

### Who Can Use This TikTok Downloader

The TikTok Video Downloader is applicable wherever raw TikTok video files carry operational or analytical value. Typical adopters include:

**Content and social media teams.** Pull down owned or licensed TikTok clips as stable files for repurposing across other channels, without relying on TikTok's own share links.

**Brand and communications functions.** Archive campaign, influencer, or executive content as it's published, so a copy exists independent of the original post's availability.

**Legal and compliance teams.** Preserve a downloaded copy of specific TikTok posts as evidence, with an explicit per-item status showing exactly what was and wasn't retrievable.

**Academic and social science researchers.** Assemble reproducible video datasets from a fixed list of post URLs, with `maxItems` for controlled sample sizes.

**AI and machine learning teams.** Collect raw video files from TikTok posts for model training, evaluation, or benchmarking pipelines.

**Media monitoring teams.** Retrieve the video behind a URL flagged during monitoring, without manually opening and saving it from the app.

**Developers building downstream pipelines.** Get a direct, stable download link per post instead of a temporary signed URL, ready to hand to the next stage of an automated workflow.

### Pricing: Transparent Event-Based Costs

Pay only for what you download. No subscriptions, no hidden fees.

| Event Type | Price | What's Included |
|---|---|---|
| Video Download | $0.003 per video | Charged once per post whose video was successfully downloaded and re-hosted to your storage |

#### Cost Examples

| Scenario | Charges | Calculation | Total Cost |
|---|---|---|---|
| 1 video downloaded successfully | 1 video-download | $0.003 × 1 | $0.003 |
| 10 videos downloaded successfully | 10 video-download | $0.003 × 10 | $0.030 |
| Invalid URL, private/deleted post, photo-mode post, or failed download | none | — | $0.000 |

### Controlling TikTok Downloading Costs

The event-based model rewards precise job design. A few principles follow directly from the rate card:

- **You're only ever charged for a delivered video.** Nothing is charged for a URL that isn't a TikTok post URL, a post that's private/deleted/never existed, a photo-mode post, or a download/upload that failed.
- **Duplicates are free.** The same post — recognized by its post id, or by its own URL for an unresolved short link — is only downloaded and charged once per run, even if it's listed twice in `startUrls`.
- **Use `maxItems` to cap spend directly.** It sets the maximum number of videos a run will download and charge for.
- **Set a realistic cost ceiling.** If your run's maximum cost per run can't cover the price of even one video, the run exits immediately before downloading anything — see the FAQ below for what that means on the Free plan.

### Demo Mode

Free-plan users can run this actor without a subscription. Run and per-run item limits on the Free plan are governed by your Apify plan configuration rather than by a fixed number in the actor itself. Subscribe to a paid plan to raise those limits and to use `maxItems` as your own per-run ceiling.

### How to Use the TikTok Video Downloader

1. **Provide your URLs.** Fill `startUrls` with one or more TikTok post URLs or short links. At least one is required.
2. **Optionally set a region.** Provide a two-letter country code if you need a specific CDN edge.
3. **Choose your storage.** Leave `storageType` as `apify` for zero-setup delivery, or set it to `aws`, `gcp`, `digitalocean`, or `azure` and fill in the matching credentials.
4. **Cap the run.** Set `maxItems` to limit how many videos this run will download and charge for.
5. **Reshape the output, if needed.** Provide a `customMapFunction` to transform each item before it's saved.
6. **Run a small test first.** Execute a low-volume run to confirm the output shape and statuses returned.
7. **Scale.** Increase your URL list once the output matches your requirements.

### Input Parameters

| Field | Type | Description | Default |
|---|---|---|---|
| `startUrls` | array | TikTok URLs to download — canonical post/photo URLs or short links (`vt.tiktok.com`, `vm.tiktok.com`, `tiktok.com/t/...`), resolved automatically. | — |
| `region` | string | Optional two-letter country code (e.g. `US`, `DE`). Selects which TikTok CDN edge the video is fetched from. | — |
| `storageType` | string | Where downloaded videos are delivered: `apify`, `aws`, `gcp`, `digitalocean`, or `azure`. Fill in the matching storage configuration fields below. | `apify` |
| `maxItems` | integer | Maximum number of videos to download and charge for in this run. | unlimited |
| `customMapFunction` | string | Function applied to each output item before it is saved, e.g. `(object) => { return {...object} }`. | `null` |
| `outputConnector` | string | MCP connector to deliver the results to — pick one (see [Send Results to Notion, Todoist and More (MCP Connectors)](#send-results-to-notion-todoist-and-more-mcp-connectors)). | `null` |
| `deliverTarget` | string | Where the connector writes — paste the URL or ID (Notion example: `https://www.notion.so/My-Posts-24f8a1b2c3d44e5f8a9b0c1d2e3f4a5b`); some services need none. | `null` |
| `deliverMode` | string | `perPost` (one record per item) or `summary` (one roll-up per run). | `perPost` |
| `deliverMaxItems` | integer | Optional cap on how many records `perPost` delivers (ignored in `summary`). | `null` |

#### Storage Configuration

- **AWS S3:** `s3AccessKeyId`, `s3SecretAccessKey`, `s3Region`, `s3Bucket`, `s3Path` (optional)
- **Google Cloud:** `googleCloudProjectId`, `googleCloudServiceKeyJson`, `googleCloudBucketName`, `googleCloudPath` (optional)
- **DigitalOcean Spaces:** `digitalOceanAccessKeyId`, `digitalOceanSecretAccessKey`, `digitalOceanRegion`, `digitalOceanBucketName`, `digitalOceanEndpoint` (optional), `digitalOceanAcl` (optional), `digitalOceanPath` (optional)
- **Azure:** `azureAccountName`, `azureAccountKey`, `azureContainerName`, `azurePath` (optional)

### Input Examples

**Basic download**

```json
{
  "startUrls": [
    "https://www.tiktok.com/@cznburak/video/7120985110991604993",
    "https://vt.tiktok.com/ZSDHmaujt/"
  ],
  "storageType": "apify"
}
```

**With a region hint**

```json
{
  "startUrls": ["https://www.tiktok.com/@example_user/video/7123456789012345678"],
  "region": "US",
  "storageType": "apify"
}
```

**Deliver to your own S3 bucket**

```json
{
  "startUrls": ["https://www.tiktok.com/@example_user/video/7123456789012345678"],
  "storageType": "aws",
  "s3AccessKeyId": "AKIAEXAMPLE",
  "s3SecretAccessKey": "example-secret-key",
  "s3Region": "us-east-1",
  "s3Bucket": "my-tiktok-downloads"
}
```

**Capped run with output reshaping**

```json
{
  "startUrls": [
    "https://www.tiktok.com/@example_user/video/7123456789012345678",
    "https://www.tiktok.com/@example_user/video/7123456789012345679"
  ],
  "maxItems": 1,
  "customMapFunction": "(object) => { return { url: object.downloadUrl, status: object.status } }"
}
```

### Output Examples

Every dataset row corresponds to one entry in `startUrls`. The exact shape depends on the outcome for that post.

**Succeeded**

```json
{
  "title": "Example TikTok video caption #fyp",
  "sourceUrl": "https://www.tiktok.com/@example_user/video/7123456789012345678",
  "downloadUrl": "https://api.apify.com/v2/key-value-stores/example-store-id/records/tt-7123456789012345678.mp4",
  "cover": "https://p16-sign.tiktokcdn-us.com/example-cover-image.jpeg",
  "storageType": "apify",
  "status": "succeeded",
  "jobId": "job_a1b2c3d4",
  "error": null,
  "inputSource": {
    "queryIndex": 0,
    "url": "https://www.tiktok.com/@example_user/video/7123456789012345678"
  }
}
```

**Failed**

```json
{
  "title": "Example TikTok video caption #fyp",
  "sourceUrl": "https://www.tiktok.com/@example_user/video/7123456789012345679",
  "downloadUrl": null,
  "status": "failed",
  "error": "The download job failed.",
  "inputSource": {
    "queryIndex": 1,
    "url": "https://www.tiktok.com/@example_user/video/7123456789012345679"
  }
}
```

**Invalid URL**

```json
{
  "title": null,
  "sourceUrl": "https://example.com/not-a-tiktok-url",
  "downloadUrl": null,
  "cover": null,
  "status": "invalidUrl",
  "jobId": null,
  "error": "The URL is not a supported TikTok post URL.",
  "inputSource": {
    "queryIndex": 2,
    "url": "https://example.com/not-a-tiktok-url"
  }
}
```

**Unavailable**

```json
{
  "title": null,
  "sourceUrl": "https://www.tiktok.com/@example_user/video/7999999999999999999",
  "downloadUrl": null,
  "cover": null,
  "status": "unavailable",
  "jobId": null,
  "error": "The post does not exist, or it is private or deleted.",
  "inputSource": {
    "queryIndex": 3,
    "url": "https://www.tiktok.com/@example_user/video/7999999999999999999"
  }
}
```

**No Video Content**

```json
{
  "title": "Example photo-mode post caption",
  "sourceUrl": "https://www.tiktok.com/@example_user/photo/7123456780000000000",
  "downloadUrl": null,
  "cover": "https://p16-sign.tiktokcdn-us.com/example-cover-image.jpeg",
  "status": "noVideoContent",
  "jobId": null,
  "error": "The post contains no video.",
  "inputSource": {
    "queryIndex": 4,
    "url": "https://www.tiktok.com/@example_user/photo/7123456780000000000"
  }
}
```

**Timed Out**

```json
{
  "title": "Example TikTok video caption #fyp",
  "sourceUrl": "https://www.tiktok.com/@example_user/video/7123456789000000000",
  "downloadUrl": null,
  "cover": "https://p16-sign.tiktokcdn-us.com/example-cover-image.jpeg",
  "storageType": "apify",
  "status": "timedOut",
  "jobId": null,
  "error": "The run ran out of time before this video was downloaded.",
  "inputSource": {
    "queryIndex": 5,
    "url": "https://www.tiktok.com/@example_user/video/7123456789000000000"
  }
}
```

### Send Results to Notion, Todoist and More (MCP Connectors)

Skip the manual exports — the TikTok Video Downloader can deliver its results directly into the tools you already work in, through [Apify MCP Connectors](https://apify.com/store/collections/mcp-connectors):

1. Authorize a connector (Notion, Todoist, or any service whose MCP server offers non-destructive write tools) once in [Console → Settings → API & Integrations → MCP connectors](https://console.apify.com/settings/integrations).
2. Pick it from the **Send results to Notion, Todoist, …** dropdown.
3. Fill in where and how to write:
   - **Destination target** — paste the URL or ID (Notion example: `https://www.notion.so/My-Posts-24f8a1b2c3d44e5f8a9b0c1d2e3f4a5b`); share it with your connector first via Notion's **•••  → Connections** menu. For structured columns use a **page** URL (the Actor builds the database for you) or a database that **already has columns** — an empty database only receives titles. (Some services need no target.)
   - **Write mode** — `perPost` writes one record per video; `summary` writes a single roll-up for the run.
   - **Max records to deliver** *(optional)* — cap on how many records `perPost` delivers.

Each video becomes one record with its status, source URL and download link. Failed downloads are delivered too, with their status and error, so the destination doubles as a download log. Links to Apify storage stay valid for as long as the run's storage is retained; use your own cloud storage for permanent links.

**Notion, structured like a spreadsheet:** for a table of typed columns, point the target at a Notion **page** — the Actor auto-creates a database from the data, one matching, correctly-typed column per field (URL, number, date, text). Pointing at an **existing database** fills the columns it already has (matched by name); an **empty database** receives only the title, and the rest of each record goes to the row body — the connector can't add columns to an existing database without destructive access it never requests. Nested fields are flattened into columns too — an `inputSource` object becomes `inputSource.url` and `inputSource.queryIndex` — so everything is sortable and filterable in the grid. Fields that don't fit a column go to the row's page body, so nothing is lost.

Your credentials stay yours: the Actor talks to your services exclusively through your own authorized connector and only ever uses non-destructive write tools — it cannot delete or overwrite anything you already have. Delivery is best-effort and runs after the scrape: if a connector is misconfigured or a delivery fails, your run still finishes normally with all results intact — the failure is reported in the run log, never by failing the run. If the run is about to hit its timeout, delivery stops early so the run still succeeds, and the log tells you how many records were delivered.

### During the Run

The actor logs its progress as it resolves and downloads each post. If you provide incorrect input, such as leaving `startUrls` empty, the actor stops immediately with an explanation of what went wrong.

### Frequently Asked Questions

**What can the TikTok Video Downloader collect?** A single TikTok post's video per URL you provide, re-hosted to your chosen storage, sourced from canonical post URLs or short links.

**Does it work with short links?** Yes. `vt.tiktok.com`, `vm.tiktok.com`, and `tiktok.com/t/...` links are resolved to the underlying post automatically — no need to expand them yourself.

**Can I deliver videos to my own cloud storage instead of Apify's?** Yes. Set `storageType` to `aws`, `gcp`, `digitalocean`, or `azure` and fill in the matching credentials.

**Am I charged for posts that are private, deleted, or not TikTok URLs?** No. You're only charged once a video is successfully downloaded and re-hosted.

**What happens with photo-mode (slideshow) posts?** They're recognized as valid posts but reported with no video, since they hold images rather than a video — and are never charged.

**What happens if the same post appears twice in my input?** It's only downloaded and charged once per run.

**What happens if my configured max cost per run can't cover a single video?** The run exits immediately without downloading anything. On the Free plan, this still charges you for 10 video-download events; on a paid plan, nothing is charged in this case.

**Can I customize the output shape?** Yes. `customMapFunction` takes each output object as an argument and returns the object that gets saved instead.

**Is there a free way to test the actor?** Yes. Demo Mode allows Free-plan users to run the actor without a subscription, subject to the run and item limits set by your Apify plan.

**What happens if my input is invalid?** The actor stops immediately and returns an explanation of the problem. Leaving `startUrls` empty is one such case.

### Support and Custom Integrations

Please visit us through [epctex.com](https://epctex.com) to see all available products. For custom integrations, reach out via the chat box on [epctex.com](https://epctex.com). For support: <business@epctex.com>.

# Actor input Schema

## `startUrls` (type: `array`):

List of TikTok video URLs to download. Both canonical URLs (https://www.tiktok.com/@user/video/{id}) and short links (https://vt.tiktok.com/..., https://vm.tiktok.com/...) are accepted — they are resolved for you, so there is no need to expand them yourself.

## `region` (type: `string`):

Optional two-letter country code (for example US or DE). Selects which TikTok CDN edge the video is fetched from, which can help with geo-restricted videos.

## `customMapFunction` (type: `string`):

Function that takes each of the objects as argument and returns data that will be mapped by the function itself. This function is not intended for filtering, please don't use it for filtering purposes or you will get banned automatically. Must be a single function, e.g. (object) => { return {...object} }. Leave empty if you do not need to transform the output - an unusable function is ignored and the original items are saved instead.

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

Maximum number of items to output. Leave empty for no limit.

## `storageType` (type: `string`):

Target storage provider. Fill the matching configuration section below.

## `s3AccessKeyId` (type: `string`):

Fill in the following fields if you want to upload the video to an S3 bucket

## `s3SecretAccessKey` (type: `string`):

Fill in the following fields if you want to upload the video to an S3 bucket

## `s3Bucket` (type: `string`):

Fill in the following fields if you want to upload the video to an S3 bucket

## `s3Region` (type: `string`):

Fill in the following fields if you want to upload the video to an S3 bucket

## `s3Path` (type: `string`):

Optional folder path in the S3 bucket.

## `googleCloudProjectId` (type: `string`):

GCP project ID.

## `googleCloudServiceKeyJson` (type: `object`):

Service account credentials JSON.

## `googleCloudBucketName` (type: `string`):

Target Google Cloud Storage bucket name.

## `googleCloudPath` (type: `string`):

Optional folder path in the GCS bucket.

## `digitalOceanAccessKeyId` (type: `string`):

DigitalOcean Spaces access key ID.

## `digitalOceanSecretAccessKey` (type: `string`):

DigitalOcean Spaces secret access key.

## `digitalOceanRegion` (type: `string`):

DigitalOcean Spaces region (e.g. nyc3).

## `digitalOceanBucketName` (type: `string`):

DigitalOcean Spaces bucket name.

## `digitalOceanEndpoint` (type: `string`):

Optional Spaces endpoint URL.

## `digitalOceanAcl` (type: `string`):

Optional ACL value (defaults to private).

## `digitalOceanPath` (type: `string`):

Optional folder path in the Spaces bucket.

## `azureAccountName` (type: `string`):

Azure storage account name.

## `azureAccountKey` (type: `string`):

Azure storage account key.

## `azureContainerName` (type: `string`):

Azure container name.

## `azurePath` (type: `string`):

Optional folder path in the Azure container.

## `outputConnector` (type: `string`):

Pick an MCP connector you authorized in Console → Settings → API & Integrations → MCP connectors (e.g. Notion, Todoist — any service whose MCP server offers non-destructive write tools works best-effort). The scraped results are written through your own connector — the Actor never sees your third-party credentials. Only non-destructive write tools are used; it can never delete or overwrite your existing data.

## `deliverTarget` (type: `string`):

Where to write into the connector — paste the URL or ID. Notion example: https://www.notion.so/My-Posts-24f8a1b2c3d44e5f8a9b0c1d2e3f4a5b. Leave empty for services that need no target (e.g. Todoist Inbox, Slack). For Notion, share the page or database with your connector first (Notion's ••• → Connections menu), and point at a PAGE for structured columns (the Actor builds the database for you) — an empty database receives only the title (the rest of each record goes to the row's body).

## `deliverMode` (type: `string`):

perPost writes one record per scraped item; summary writes a single roll-up for the run.

## `deliverMaxItems` (type: `integer`):

Cap on how many records perPost mode writes to the connector; ignored in summary mode. Leave empty to deliver everything scraped.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.tiktok.com/@cznburak/video/7120985110991604993"
  ],
  "customMapFunction": "(object) => { return {...object} }",
  "storageType": "apify",
  "deliverMode": "perPost"
}
```

# Actor output Schema

## `overview` (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 = {
    "startUrls": [
        "https://www.tiktok.com/@cznburak/video/7120985110991604993"
    ],
    "customMapFunction": (object) => { return {...object} }
};

// Run the Actor and wait for it to finish
const run = await client.actor("epctex/tiktok-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 = {
    "startUrls": ["https://www.tiktok.com/@cznburak/video/7120985110991604993"],
    "customMapFunction": "(object) => { return {...object} }",
}

# Run the Actor and wait for it to finish
run = client.actor("epctex/tiktok-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 '{
  "startUrls": [
    "https://www.tiktok.com/@cznburak/video/7120985110991604993"
  ],
  "customMapFunction": "(object) => { return {...object} }"
}' |
apify call epctex/tiktok-video-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,epctex/tiktok-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/9EwE2S3mGpxx665jw/builds/5brdTIlgIh7dBUY70/openapi.json
