# Streamable Public Video Downloader (`automation-lab/streamable-video-downloader`) Actor

Download authorized public Streamable videos, store MP4 files, and export identity, title, resolution, source, file URL, and retrieval status.

- **URL**: https://apify.com/automation-lab/streamable-video-downloader.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Videos
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.92 / 1,000 item extracteds

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

## Streamable Public Video Downloader

Download authorized public **Streamable videos**, store MP4 files in Apify, and export a normalized record for every supplied link.
The Actor resolves video identity, title, format, resolution, source URL, current media URL, stored-file URL, byte size, and retrieval status.

No Streamable login, cookies, browser, user API key, or paid proxy is required.
Private, login-only, deleted, and access-controlled videos are outside scope.

### What can the Streamable Public Video Downloader do?

- Process public `streamable.com` share and embed URLs.
- Accept Streamable short codes as well as full URLs.
- Resolve the current signed source MP4 URL.
- Copy the MP4 into the run key-value store.
- Run in resolve-only mode without copying video bytes.
- Return one typed status record for each processed input.
- Continue after invalid, duplicate, deleted, or unavailable inputs.
- Deduplicate repeated video IDs within one run.
- Bound downloads with a configurable file-size limit.
- Process up to 100 supplied inputs per run.

This is a supplied-link archiver. It does not search Streamable, discover videos, open private content, or bypass access controls.

### Who is this Actor for?

**Creators and rights holders** can preserve their own public Streamable clips before links are removed or expire.

**Editorial and production teams** can turn approved links into stored files plus source provenance.

**Researchers and journalists** can maintain a bounded inventory of public videos they are permitted to retain.

**Developers and data engineers** can feed normalized video records into transcription, review, cataloging, or durable-storage pipelines.

**Records teams** can schedule recurring link checks and compare per-input retrieval status over time.

### Why use it for Streamable video archives?

A copied MP4 alone does not preserve its public source, Streamable code, resolution, retrieval time, or failure state.
This Actor keeps those fields together in one dataset row and can store the media in the same run.

The implementation uses Streamable's anonymous oEmbed and media redirect surfaces.
It does not launch a browser or automatically spend on proxy traffic.
Set `saveVideos: false` for a faster, lower-transfer inventory.

### Supported Streamable inputs

Supported inputs include:

```text
https://streamable.com/moo
https://streamable.com/e/moo
https://streamable.com/o/moo
moo
```

Only HTTPS URLs on `streamable.com` are accepted.
The video must be anonymously accessible and expose an MP4.
Signed source media URLs can expire; enable file storage when the workflow needs a retained copy.

### Extracted Streamable video data

| Field | Meaning |
| --- | --- |
| `input` | Original supplied URL or short code |
| `videoId` | Normalized Streamable short code |
| `title` | Public title reported by Streamable |
| `format` | Resolved media format, currently `mp4` |
| `width`, `height` | Public video dimensions |
| `resolution` | Normalized `widthxheight` value |
| `sourceUrl` | Canonical public Streamable page URL |
| `sourceMediaUrl` | Current signed source-hosted MP4 URL |
| `thumbnailUrl` | Current public thumbnail URL |
| `videoFileKey` | Stored MP4 key, or `null` in resolve-only mode |
| `videoFileUrl` | Apify key-value store API URL |
| `videoSizeBytes` | Number of bytes copied to storage |
| `retrievalStatus` | `downloaded`, `resolved`, `not_found`, `failed`, `invalid_input`, or `duplicate` |
| `error` | Concise failure reason, otherwise `null` |
| `retrievedAt` | ISO 8601 retrieval timestamp |

Missing source values are returned as `null`, never guessed.

### How to download a public Streamable video

1. Confirm the video opens while logged out and that you may archive it.
2. Copy its Streamable share URL.
3. Open this Actor in Apify Console.
4. Add the URL under **Streamable video URLs or codes**.
5. Keep **Save video files** enabled.
6. Set a file-size limit appropriate for the expected clip.
7. Click **Start**.
8. Open **Video records** for metadata and status.
9. Open **Stored video files** for the MP4.

The prefilled `moo` URL is a real public sample suitable for a first run, although third-party source availability can change.

### Input parameters

| Input | Type | Default | Description |
| --- | --- | --- | --- |
| `startUrls` | array | required | Public Streamable URLs or short codes |
| `saveVideos` | boolean | `true` | Copy resolved MP4 bytes into run storage |
| `maxItems` | integer | `10` | Maximum supplied inputs processed, 1–100 |
| `maxVideoSizeMb` | integer | `100` | Maximum stored file size, 1–500 MB |
| `maxRequestRetries` | integer | `2` | Bounded transient retries, 0–5 |

Example:

```json
{
  "startUrls": [
    { "url": "https://streamable.com/moo" }
  ],
  "saveVideos": true,
  "maxItems": 1,
  "maxVideoSizeMb": 25,
  "maxRequestRetries": 2
}
```

### Output example

This abbreviated record reflects the current public `moo` sample and a local stored-file run:

```json
{
  "input": "https://streamable.com/moo",
  "videoId": "moo",
  "title": "\"Please don't eat me!\"",
  "format": "mp4",
  "width": 852,
  "height": 480,
  "resolution": "852x480",
  "sourceUrl": "https://streamable.com/moo",
  "sourceMediaUrl": "https://cdn-cf-west.streamable.com/video/...mp4?Expires=...",
  "thumbnailUrl": "https://cdn-cf-west.streamable.com/image/...jpg?Expires=...",
  "videoFileKey": "video-moo.mp4",
  "videoFileUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/video-moo.mp4",
  "videoSizeBytes": 3044857,
  "retrievalStatus": "downloaded",
  "error": null,
  "retrievedAt": "2026-09-16T06:10:00.000Z"
}
```

Default run storage is private.
Authenticate when opening API file URLs, or copy files to storage you control.

### Where are downloaded videos stored?

Stored files use this key pattern in the default key-value store:

```text
video-<streamable-id>.mp4
```

The Actor copies the MP4 without re-encoding or watermarking it.
The source media URL is signed and may expire.
The run-owned storage record remains available according to your Apify storage retention settings.

### How much does it cost to download Streamable videos?

The Actor uses pay-per-event pricing: one **$0.001** start event and one `item` event for each successfully resolved public Streamable video.
Failed, invalid, and duplicate inputs have no item charge.
Saving a video does not create a second charge event, although ordinary platform transfer and storage usage can increase with file size.

The current item tiers are:

| Tier | Successful video |
| --- | ---: |
| FREE | $0.0017572 |
| BRONZE | $0.001528 |
| SILVER | $0.0011918 |
| GOLD | $0.0009168 |
| PLATINUM | $0.0009168 |
| DIAMOND | $0.0009168 |

At BRONZE, one successful video is about **$0.002528**, 10 are about **$0.01628**, and 100 are about **$0.1538**, plus ordinary Apify platform usage.

### Resolve Streamable links without copying media

Set `saveVideos: false` to return metadata and the current signed MP4 URL without copying bytes.
This mode is useful for availability checks, link inventories, and downstream systems that handle approved downloads themselves.

A signed URL is not permanent storage.
Use it promptly or enable file storage.
The `item` event is unchanged because a successful typed video record is still produced.

### Batch and recurring archive workflows

Supply a bounded list of approved links and save the input as an Apify Task.
Schedule the Task when recurring availability checks are needed.

Use `videoId` as the stable source key in your destination.
Compare `retrievalStatus` between runs to identify changes.
A later failure can indicate removal, an access change, or a temporary source error; the Actor does not infer legal or editorial meaning.

The Actor does not discover new videos or compare prior datasets automatically.

### Integrations and exports

Send dataset rows and authorized files to:

- Amazon S3, Google Cloud Storage, or Azure Blob Storage;
- Google Sheets or Airtable for an archive index;
- a webhook for transcription or moderation;
- a database keyed by `videoId`;
- an approved digital asset management system.

Copy authenticated file bytes when a destination cannot read private Apify run storage.

### Run with the Apify API

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~streamable-video-downloader/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":[{"url":"https://streamable.com/moo"}],"saveVideos":true,"maxItems":1,"maxVideoSizeMb":25}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/streamable-video-downloader').call({
  startUrls: [{ url: 'https://streamable.com/moo' }],
  saveVideos: true,
  maxItems: 1,
  maxVideoSizeMb: 25,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("automation-lab/streamable-video-downloader").call(run_input={
    "startUrls": [{"url": "https://streamable.com/moo"}],
    "saveVideos": True,
    "maxItems": 1,
    "maxVideoSizeMb": 25,
})
print(client.dataset(run["defaultDatasetId"]).list_items().items)
```

Keep API tokens in environment variables or a secret manager.

### Use with Apify MCP

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/streamable-video-downloader"
```

#### Claude Desktop setup

Add this configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/streamable-video-downloader"
    }
  }
}
```

#### Cursor setup

Add the same MCP server URL in **Cursor Settings → MCP**.

#### VS Code setup

Add the same MCP server URL through your VS Code MCP extension or workspace MCP configuration.

Example prompts:

- "Download this authorized public Streamable clip and return its stored file metadata."
- "Resolve these approved Streamable links without copying media."
- "Export a status inventory for this bounded Streamable video list."

### Reliability, limits, and failure behavior

The Actor retrieves anonymous oEmbed metadata and a fresh media redirect for each unique video ID.
Transient network, rate-limit, and server failures are retried a bounded number of times.
No browser or proxy fallback is enabled.

Invalid, unavailable, and duplicate inputs produce uncharged status rows.
Successful inputs remain available when another input fails.
The run exits with failure when no input succeeds.

A download stops when it exceeds `maxVideoSizeMb`.
The Actor does not bypass passwords, accounts, geographic controls, or other restrictions.

### Troubleshooting

#### Why was my Streamable link marked `not_found`?

Open it in a logged-out browser.
It may have been deleted, expired, made private, or typed incorrectly.
Only anonymous public videos are supported.

#### Why is `videoFileUrl` null?

File storage was disabled, or the download failed.
A successful resolve-only row has `retrievalStatus: "resolved"` and still includes `sourceMediaUrl`.

#### Why does a source MP4 link stop working later?

Streamable signs media URLs and can rotate or expire them.
Enable `saveVideos` when your authorized workflow needs a retained run-owned copy.

#### Why is the stored file URL unauthorized?

Apify run storage is private by default.
Open it while authenticated in Console or use an authorized API request.

### Responsible and legal use

Use this Actor only for public Streamable media you are legally allowed to access, download, retain, and process.
Respect copyright, privacy, publicity rights, contractual restrictions, Streamable's terms, and applicable law.

Do not use it to bypass login, passwords, payment, geographic controls, or access restrictions.
Do not redistribute media without permission.
Minimize retained personal data, restrict file access, choose an appropriate retention period, and honor valid deletion requests.
This tool does not grant rights to third-party content and is not affiliated with Streamable.

### Data handling and retention

The Actor sends only supplied public Streamable identifiers to Streamable's anonymous public endpoints.
It does not use AI providers or additional subprocessors.
Dataset records and optional MP4 files are stored in the run's Apify storage under your account.
Apify retention depends on your plan and storage settings; delete runs or records when they are no longer needed.

Logs contain concise URLs/statuses for diagnosis but never API tokens or private credentials.
Avoid supplying links that embed secrets or personal access tokens.

### Related automation-lab Actors

- [Vimeo Public Video Downloader](https://apify.com/automation-lab/vimeo-public-video-downloader) — archive authorized anonymous Vimeo progressive MP4s.
- [Reddit Public Video Downloader](https://apify.com/automation-lab/reddit-public-video-downloader) — store media from supplied public Reddit posts.
- [Dailymotion Public Video Downloader](https://apify.com/automation-lab/dailymotion-public-video-downloader) — resolve public Dailymotion media metadata.

These Actors cover separate source-specific workflows; they do not broaden this Actor beyond Streamable.

### FAQ

#### Does the Actor require a Streamable account?

No.
It supports only public videos available without login.

#### Can it search Streamable?

No.
Supply exact links or short codes.

#### Does Streamable delete videos?

Streamable videos can become unavailable because of uploader action, account policy, expiration, or access changes.
This Actor records the current per-input state; it does not guarantee future availability.

#### Are failed or duplicate inputs charged as items?

No.
Only successfully resolved public video records create the `item` event.
The one-time start event still applies once per run.

#### Can downloaded files be kept permanently?

Apify storage retention depends on your plan.
Copy authorized files to durable storage you control when you need longer retention.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/streamable-video-downloader/changelog.md

# Actor input Schema

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

HTTPS streamable.com share/embed URLs or Streamable short codes. Private, login-only, and deleted videos are reported as unavailable.

## `saveVideos` (type: `boolean`):

Store each resolved MP4 file in the run key-value store. Disable to return metadata and the current source-hosted media URL only.

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

Maximum number of supplied inputs to process, including unavailable inputs.

## `maxVideoSizeMb` (type: `integer`):

Stop a stored-file download if it exceeds this size. This setting has no effect when file storage is disabled.

## `maxRequestRetries` (type: `integer`):

Retries for temporary network, rate-limit, and Streamable server failures.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://streamable.com/moo"
    }
  ],
  "saveVideos": true,
  "maxItems": 10,
  "maxVideoSizeMb": 100,
  "maxRequestRetries": 2
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing one retrieval record per processed input.

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

Key-value store containing downloaded MP4 files when storage is enabled.

# 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": [
        {
            "url": "https://streamable.com/moo"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/streamable-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": [{ "url": "https://streamable.com/moo" }] }

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/streamable-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": [
    {
      "url": "https://streamable.com/moo"
    }
  ]
}' |
apify call automation-lab/streamable-video-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/streamable-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/8heebWB1nb4dFNuY5/builds/LNCbibtbjwdgIHhog/openapi.json
