# Loom Video Downloader: MP4, Transcript & Metadata (`getascraper/loom-video-downloader`) Actor

Turn any public Loom share link into a downloadable MP4 URL, full transcript, VTT captions and rich metadata in one run. No login required. Handles share links, embed links, iframe snippets and raw video IDs.

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

## Pricing

from $1.20 / 1,000 video records

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Loom Video Downloader: MP4, transcript and metadata in one run

**Turn any public Loom link into a ready-to-download video file, a full transcript, subtitles, and rich video details, all in a single run.** No login, no password, no browser extension. Paste a share link, an embed link, an embed snippet, or a raw video ID and get everything back in one clean row per video.

### 🔍 What does the Loom Video Downloader do?

The Loom Video Downloader turns a [Loom](https://www.loom.com/) link into structured data and, if you want it, the actual video file. Point it at one or more Loom videos that were shared as "anyone with the link", and for each one you get:

- A direct, ready-to-download video link
- The full transcript, both as clean readable text and as timestamped lines
- Subtitles (VTT captions) for editors and subtitle files
- Title, description, duration, resolution, view count, owner name and avatar, and thumbnails
- An honest status for every video: downloadable, private, or download disabled, never a guess

Because it runs on the Apify platform, you also get scheduling, ready-made integrations, run monitoring, and exports in JSON, CSV, or Excel.

### 💡 Why use the Loom Video Downloader?

Most Loom tools do only one job: either they download the video, or they pull the transcript, never both. This one does both, plus the metadata, in a single pass.

- **I am a content creator** repurposing my Loom walkthroughs into blog posts and social clips, and I need the transcript and the video file in one step.
- **I am a customer support lead** archiving every Loom recording my team sends to customers, so nothing gets lost when a workspace changes hands.
- **I am an AI or automation builder** feeding Loom transcripts into a summarizer or knowledge base, and I need clean, timestamped text without manually copying captions.
- **I am an agency or consultant** backing up client demo recordings and onboarding videos before a Loom account gets cancelled or a link expires.
- **I am a course creator** pulling subtitles and video files from a batch of recorded lessons to publish somewhere else.

### 🚀 How to use the Loom Video Downloader

1. Click **Try for free** at the top of this page.
2. Paste one or more Loom links into **Loom videos**. Share links, embed links, embed snippets, and raw video IDs all work.
3. Choose whether to include the **transcript** and **captions** (both on by default).
4. Turn on **Download and store the video file** only if you need the actual file saved, not just the link. This takes longer and costs more for large videos.
5. Set **Max items** to cap how many videos you want processed.
6. Press **Start** and watch the results fill the Output tab.
7. Download the dataset in JSON, CSV, or Excel, or connect it to Google Sheets, Make, Zapier, or your own app.

New here? Try it with a single link first to see the output shape before running a larger batch.

### 📥 Input

Set these fields in the Console form, or pass them as JSON.

| Field | Type | Required | Description |
|---|---|---|---|
| Loom videos | array of strings | Yes | Share links, embed links, embed snippets, or raw video IDs, one per line. |
| Max items | integer | No | Maximum number of videos to process. Leave empty to process every video you listed. |
| Include full transcript | boolean | No | Attach the clean transcript text and timestamped lines. On by default. |
| Include captions (VTT) | boolean | No | Attach subtitle file content and its link. On by default. |
| Download and store the video file | boolean | No | Save the actual video file to this run's storage, not just the link. Off by default, since it takes longer and costs more for large videos. |
| Proxy configuration | object | No | Network settings. The default works for almost everyone. |

### 📤 Output

Every video becomes one row with everything about it in one place. Here is a shortened example:

```json
{
  "videoId": "230fc263c6784be7a0a4840a8c8f6216",
  "canonicalUrl": "https://www.loom.com/share/230fc263c6784be7a0a4840a8c8f6216",
  "title": "Loom 101 Webinar",
  "durationSeconds": 3224,
  "width": 2400,
  "height": 1350,
  "totalViews": 109,
  "ownerName": "Brittany Soinski",
  "thumbnailUrl": "https://cdn.loom.com/sessions/thumbnails/230fc263...jpg",
  "mediaUrl": "https://cdn.loom.com/sessions/transcoded/230fc263...mp4",
  "mediaFormat": "mp4",
  "transcriptText": "All right everybody, let's go ahead and get started...",
  "captionsUrl": "https://cdn.loom.com/mediametadata/captions/230fc263...vtt",
  "downloadable": true,
  "status": "ok",
  "scrapedAt": "2026-07-03T03:59:40.417Z"
}
````

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. The Output tab has three ready-made views: Videos, Transcripts, and Downloads.

### 📊 Data table

Main fields returned for every video. Empty fields are dropped, so every value you see is real.

| Field | Type | Description |
|---|---|---|
| videoId | string | The Loom video ID resolved from your input. |
| canonicalUrl | string | Direct share link to the video on Loom. |
| title | string | Video title. |
| description | string | Video description, when the owner added one. |
| durationSeconds | number | Video length in seconds. |
| width / height | number | Video resolution in pixels. |
| totalViews | number | Total view count, when available. |
| ownerName | string | Display name of the person who recorded the video. |
| ownerAvatarUrl | string | Link to the owner's profile picture. |
| thumbnailUrl | string | Static thumbnail image. |
| animatedThumbnailUrl | string | Animated preview thumbnail, when available. |
| mediaUrl | string | Direct, ready-to-download video link. |
| mediaFormat | string | File format of the video link, typically mp4. |
| transcriptText | string | Full transcript as clean, readable text. |
| transcriptPhrases | array | Transcript broken into timestamped lines. |
| captionsVtt | string | Raw subtitle file content. |
| captionsUrl | string | Direct link to the subtitle file. |
| downloadable | boolean | Whether a video link was found for this video. |
| status | string | `ok`, `private`, `download_disabled`, or `not_found`. |
| statusReason | string | Plain-language explanation when status is not `ok`. |
| savedFile | object | Stored file details, only present when file download was turned on. |
| scrapedAt | string | When this row was collected, in ISO 8601 UTC. |

### 💰 Pricing

This Actor uses **pay per result**, so you only pay for the videos you actually receive data for. Runs that return nothing cost nothing, and there are no monthly subscriptions or hidden fees. Turning on file download costs more per video since it moves the actual video file, and is billed separately from the standard result. Start with a small batch to preview the data before scaling up.

### ❓ FAQ

##### Does this work on private or password-protected videos?

No, and it should not. This Actor only resolves videos that were shared as "anyone with the link", the same access level Loom itself gives any visitor holding that link. Private, workspace-only, and password-protected videos are reported with a clear status instead of being bypassed.

##### Why does a video sometimes show no video link?

Some video owners turn off downloads, or the video may no longer be publicly shared. When that happens, the row still comes back with a clear `download_disabled` or `private` status and a plain-language reason, instead of a broken or fake link.

##### Do I need a Loom account or API key?

No. The Actor needs no login, no password, and no account connection. Just paste a link and press start.

##### Can I get both the transcript and the video file in the same run?

Yes. That is the whole point of this Actor. Every video's metadata, transcript, captions, and video link come back together in one row, and you can additionally turn on file storage if you want the actual video saved.

##### Why is `savedFile` missing on a very long recording?

Unusually long recordings, well beyond a typical Loom clip, can be too large to safely store in one run. When that happens, you still get the full metadata, transcript, captions, and the direct video link, just not a stored copy. This is a deliberate safety limit, not a bug.

### 🛟 Support

Found a bug, or need an extra field? Open an issue on the **Issues** tab of this Actor and it will be reviewed. Custom versions and larger batch runs are available on request.

# Actor input Schema

## `targets` (type: `array`):

One or more Loom videos to resolve. Paste a share link (loom.com/share/{id}), an embed link, a full <iframe> embed snippet, or a raw 32-character video ID - any format works.

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

Maximum number of videos to process. You are billed per video returned. Leave empty to process every target.

## `includeTranscript` (type: `boolean`):

Attach the clean, concatenated transcript text plus timestamped phrases (ready to paste into an LLM or notes) to every video. Only available when the video owner enabled transcription.

## `includeCaptions` (type: `boolean`):

Attach the raw WebVTT captions file content and its source URL, suitable for subtitle files or video editors.

## `downloadFile` (type: `boolean`):

When enabled, the actor streams the actual MP4 file into this run's storage and returns a permanent download link in 'savedFile'. When disabled (default), the actor only returns the temporary signed video URL Loom itself serves - faster and much cheaper, since no video bandwidth is used. Downloading large videos adds noticeable time to the run and is billed as a separate, higher-cost event.

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

Loom has no bot-detection wall, so a plain datacenter proxy (the default) works. Only switch to residential if you are running very high volume from a single location.

## Actor input object example

```json
{
  "targets": [
    "https://www.loom.com/share/230fc263c6784be7a0a4840a8c8f6216"
  ],
  "maxItems": 100,
  "includeTranscript": true,
  "includeCaptions": true,
  "downloadFile": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "targets": [
        "https://www.loom.com/share/230fc263c6784be7a0a4840a8c8f6216"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("getascraper/loom-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 = {
    "targets": ["https://www.loom.com/share/230fc263c6784be7a0a4840a8c8f6216"],
    "proxyConfiguration": { "useApifyProxy": True },
}

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

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

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

```

## CLI example

```bash
echo '{
  "targets": [
    "https://www.loom.com/share/230fc263c6784be7a0a4840a8c8f6216"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call getascraper/loom-video-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=getascraper/loom-video-downloader",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Loom Video Downloader: MP4, Transcript & Metadata",
        "description": "Turn any public Loom share link into a downloadable MP4 URL, full transcript, VTT captions and rich metadata in one run. No login required. Handles share links, embed links, iframe snippets and raw video IDs.",
        "version": "0.1",
        "x-build-id": "utmovBGRqaFVobqgr"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/getascraper~loom-video-downloader/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-getascraper-loom-video-downloader",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/getascraper~loom-video-downloader/runs": {
            "post": {
                "operationId": "runs-sync-getascraper-loom-video-downloader",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/getascraper~loom-video-downloader/run-sync": {
            "post": {
                "operationId": "run-sync-getascraper-loom-video-downloader",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "targets"
                ],
                "properties": {
                    "targets": {
                        "title": "Loom videos",
                        "type": "array",
                        "description": "One or more Loom videos to resolve. Paste a share link (loom.com/share/{id}), an embed link, a full <iframe> embed snippet, or a raw 32-character video ID - any format works.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum number of videos to process. You are billed per video returned. Leave empty to process every target.",
                        "default": 100
                    },
                    "includeTranscript": {
                        "title": "Include full transcript",
                        "type": "boolean",
                        "description": "Attach the clean, concatenated transcript text plus timestamped phrases (ready to paste into an LLM or notes) to every video. Only available when the video owner enabled transcription.",
                        "default": true
                    },
                    "includeCaptions": {
                        "title": "Include captions (VTT)",
                        "type": "boolean",
                        "description": "Attach the raw WebVTT captions file content and its source URL, suitable for subtitle files or video editors.",
                        "default": true
                    },
                    "downloadFile": {
                        "title": "Download and store the video file",
                        "type": "boolean",
                        "description": "When enabled, the actor streams the actual MP4 file into this run's storage and returns a permanent download link in 'savedFile'. When disabled (default), the actor only returns the temporary signed video URL Loom itself serves - faster and much cheaper, since no video bandwidth is used. Downloading large videos adds noticeable time to the run and is billed as a separate, higher-cost event.",
                        "default": false
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Loom has no bot-detection wall, so a plain datacenter proxy (the default) works. Only switch to residential if you are running very high volume from a single location.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
