# Instagram Reels Transcript Scraper - Reel & Video to Text (`scrapewise/instagram-reels-transcript`) Actor

Transcribe public Instagram reels and videos to text without login: full transcript with timestamps, hook, language, caption, plays and likes. Paste reel links or a username; onlyNew on a schedule transcribes only new reels. US$ 18 per 1,000. Music-only reels and errors are free.

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

## Pricing

from $15.30 / 1,000 reel transcribeds

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

## Instagram Reels Transcript Scraper: Instagram reel and video to text, no login

Turn public **Instagram reels and video posts into text**: the full spoken transcript with **timestamps**, the
**hook** (the first sentence), the **detected language**, word count, caption, hashtags, likes, comments and plays,
one row per reel. Paste reel links, or give a **username** and get that creator's latest reels transcribed.
Turn on `onlyNew` and schedule it: every run transcribes **only the reels posted since the last run**, so you pay
once per reel. No login, no cookies, no Instagram account and no third-party API key.

Built for content creators and agencies building swipe files of hooks, marketers watching competitor reels,
researchers and AI teams who need clean spoken text from short videos, and anyone repurposing reels into posts,
newsletters or subtitles.

### At a glance

| Event | Price, Free plan | Charged for |
|---|---|---|
| Reel transcribed | **US$ 0.018 (US$ 18 per 1,000)** | each unique reel with a transcript, up to 2 minutes of video |
| Extra minute | US$ 0.012 | each started minute after the first 2 (most reels never pay this) |

- **31 fields per reel**, among them `transcript`, `hook`, `segments` with start and end in seconds, `language`
  with its probability, `wordCount`, `playCount`, `likeCount`, `commentCount`, `takenAt` and `onScreenText`. All of
  them are in the [field reference](#field-reference).
- **Free:** reels without speech (music only), photo posts, too-long videos, errors, duplicates and, with
  `onlyNew`, reels you already received.
- **No monthly fee, no start fee, no Apify compute bill on top.** Whisper runs inside the Actor.
- **Three accuracy levels at the same price:** Whisper `tiny`, `base` (default) or `small`.
- **Close to 100 languages,** detected per reel or forced with a 2-letter code.

### One real row

Reel `DdWqyK3DlVv` by `@whoop`, transcribed on Apify on 2026-09-30 (caption, transcript and `videoUrl` shortened
with "...", segments cut to 3, a few fields left out):

```json
{
  "type": "reel",
  "code": "DdWqyK3DlVv",
  "url": "https://www.instagram.com/reel/DdWqyK3DlVv/",
  "ownerUsername": "whoop",
  "ownerIsVerified": true,
  "caption": "Take control of how you age. \n\nThis week on the WHOOP Podcast, ...",
  "takenAt": "2026-09-16T18:00:04Z",
  "likeCount": 727,
  "commentCount": 39,
  "playCount": 83647,
  "durationSeconds": 44.57,
  "videoUrl": "https://scontent-dfw6-1.cdninstagram.com/o1/v/t2/f2/m86/...mp4?...",
  "transcript": "the idea that getting old has to suck is almost entirely untrue, especially if you're paying attention. For sure, people want to live a long time, but it's really about the quality, how long do you live and live well? ... Health doesn't exactly accrue with compound interest, but disease short does.",
  "hook": "the idea that getting old has to suck is almost entirely untrue, especially if you're paying attention.",
  "wordCount": 120,
  "language": "en",
  "segments": [
    { "start": 0, "end": 2.44, "text": "the idea that getting old has to suck" },
    { "start": 2.44, "end": 5.24, "text": "is almost entirely untrue," },
    { "start": 5.24, "end": 6.96, "text": "especially if you're paying attention." }
  ],
  "onScreenText": "THE SCIENCE OF LONGEVITY HEALTHSPAN PODCAST ...",
  "model": "whisper-base"
}
```

### What you can do with it

- **Hook research and swipe files:** read what top creators actually say in the first seconds, not just their
  captions, and compare hooks across a niche in minutes.
- **Competitor and brand monitoring:** follow competitor profiles daily with `onlyNew` and search their new reels
  by what is said in them.
- **Repurpose your own reels:** turn them into blog posts, newsletters, threads or subtitles (`segments` has the
  timing for each phrase).
- **Datasets for AI:** clean spoken text with timestamps and language for RAG, summarisation, topic tagging or
  semantic search.
- **Engagement vs. script:** put `playCount`, `likeCount` and `wordCount` next to the transcript to see which
  scripts perform.

### Input examples

Two reels by link (an empty input `{}` transcribes one example reel, so you can see the output first):

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

The 10 latest reels of two creators, most accurate model:

```json
{ "profileUrls": ["natgeo", "https://www.instagram.com/nasa/"], "maxReelsPerProfile": 10, "model": "small" }
```

Daily monitoring, only reels posted since the last run (save as a Task and schedule it):

```json
{ "profileUrls": ["natgeo", "nasa"], "maxReelsPerProfile": 10, "onlyNew": true }
```

Spanish reels, no timestamps, skip anything over 3 minutes:

```json
{ "reelUrls": ["https://www.instagram.com/reel/DaSz9gXgFla/"], "language": "es", "includeSegments": false, "maxDurationSeconds": 180 }
```

| Field | What it does |
|---|---|
| `reelUrls` | Links to public reels or video posts (`instagram.com/reel/CODE`, `/p/CODE`) or just the code. Also accepts `postUrls`, `directUrls`, `startUrls` |
| `profileUrls` | Usernames or profile links; the Actor transcribes their latest public reels. Also accepts `profiles`, `usernames`, `handles` |
| `maxReelsPerProfile` | Default 10, newest first. Caps the cost of each profile |
| `onlyNew` | Default false. On: only reels not delivered in an earlier run, per profile |
| `language` | Empty = detect per reel. Or force a 2-letter code (`en`, `es`, `fr`, `de`, `hi`...) |
| `model` | `tiny` (fastest), `base` (default), `small` (most accurate, best for non-English and noisy audio). Same price |
| `includeSegments` | Default true: phrase-level `start` and `end` in seconds |
| `maxDurationSeconds` | Default 600. Longer videos get a free `VIDEO_TOO_LONG` row |

### Daily monitoring with onlyNew

The first run transcribes up to `maxReelsPerProfile` reels per profile and remembers them in a key-value store in
your own Apify account, named `instagram-reels-transcript-state` (one record per profile). Every later run reads
the profile's reels tab from the newest down, skips what it already delivered (pinned reels included) and stops at
the first reel it has seen before. You pay only for reels that are new to you.

- A profile with nothing new returns one free row: `"errorCode": "NO_NEW_REELS"`.
- Reels that hit a temporary problem (`BLOCKED`, `DOWNLOAD_FAILED`, `NOT_REACHED`) are not remembered, so the next
  run tries them again.
- Reels that will never have a transcript (`NO_SPEECH`, `NOT_A_VIDEO`, `NO_AUDIO`, `POST_NOT_FOUND`) are
  remembered, so they are not fetched again.
- `onlyNew` applies to profiles. Reel links are always transcribed.
- To start over, delete the `instagram-reels-transcript-state` store in Storage. Two Tasks that watch the same
  profile share its memory.

A real profile row from a test on 2026-10-14 (`@nasa`, newest reel; long fields cut):

```json
{
  "code": "DeTUk4sDSp-",
  "ownerUsername": "nasa",
  "takenAt": "2026-10-10T15:15:02Z",
  "likeCount": 667313,
  "commentCount": 6536,
  "playCount": 9582904,
  "durationSeconds": 43.8,
  "transcript": "Would you look at that man.",
  "language": "en",
  "hashtags": ["Artemis", "ArtemisII", "NASA"],
  "source": "profile:nasa"
}
```

The same input a minute later gave a single free row:

```json
{ "type": "error", "source": "profile:nasa", "errorCode": "NO_NEW_REELS", "error": "onlyNew: no new reels since the last run (not charged)" }
```

<a id="field-reference"></a>

### Field reference

| Field | What it is |
|---|---|
| `type` | `reel`, or `error` for a free error row |
| `code`, `url` | reel shortcode and its link |
| `ownerUsername`, `ownerFullName`, `ownerIsVerified` | the creator |
| `caption`, `hashtags`, `accessibilityCaption` | caption text, hashtags in it, Instagram's own image description |
| `takenAt` | publish time (ISO 8601, UTC) |
| `likeCount`, `commentCount` | likes and comments |
| `playCount` | plays; filled when the reel comes from a profile (Instagram shows it on the reels tab) |
| `durationSeconds`, `extraMinutes` | video length and the charged minutes beyond the first 2 |
| `videoUrl`, `thumbnailUrl` | MP4 and cover links (the MP4 link expires after a few days) |
| `musicTitle`, `musicArtist` | audio track, when Instagram returns it to logged-out visitors (often empty) |
| `transcript` | the full spoken text |
| `hook` | the first sentence of the transcript |
| `wordCount` | words in the transcript |
| `language`, `languageProbability` | detected (or forced) language and Whisper's confidence |
| `segments` | phrases with `start`, `end` (seconds) and `text`, when `includeSegments` is on |
| `onScreenText` | text Instagram detected in the video image, when present (can be partial) |
| `model` | Whisper model used (`whisper-tiny`, `whisper-base`, `whisper-small`) |
| `source` | what produced the row (the reel link you gave, or `profile:username`) |
| `scrapedAt`, `errorCode`, `error` | time of the row and, on error rows, the reason |

#### Error codes (never charged)

| errorCode | Meaning |
|---|---|
| `NO_SPEECH` | Music, sound effects or silence only; nothing to transcribe |
| `NOT_A_VIDEO` | The link is a photo or a carousel |
| `NO_AUDIO` | The reel has no audio track |
| `VIDEO_TOO_LONG` | Longer than `maxDurationSeconds` |
| `NO_NEW_REELS` | `onlyNew` is on and the profile posted nothing since the last run |
| `POST_NOT_FOUND`, `PROFILE_NOT_FOUND` | Deleted, private, or the link or username is wrong |
| `NO_RESULTS` | The profile shows no reels to logged-out visitors (some accounts hide their grid) |
| `INVALID_URL`, `INVALID_INPUT` | A value the Actor does not understand |
| `DOWNLOAD_FAILED`, `TRANSCRIPTION_FAILED`, `BLOCKED`, `NO_VIDEO_URL` | Instagram or the audio did not cooperate after retries; run again |
| `NOT_REACHED`, `UNEXPECTED` | The run timeout or spending limit arrived, or something unforeseen broke; only that reel is lost |

### Pricing examples

- 1,000 typical reels (under 2 minutes) cost **US$ 18**.
- A 5-minute video costs US$ 0.018 + 3 x US$ 0.012 = US$ 0.054.
- A daily Task on 20 profiles that post one reel a day costs about US$ 0.36 a day with `onlyNew`, instead of
  paying again for the same reels.
- Set `maxDurationSeconds` to cap long videos and `maxReelsPerProfile` to cap each profile. You can also set a
  maximum cost per run in Apify; the Actor stops there and keeps what it saved.

### Integrations, scheduling and AI agents

- **Schedule** a Task daily or weekly in [Apify schedules](https://docs.apify.com/platform/schedules) with
  `onlyNew: true`; a quiet day costs nothing.
- **Export** as JSON, CSV, Excel or XML, or read the dataset from the [Apify API](https://docs.apify.com/api/v2).
- **Connect** it to Make, n8n, Zapier, Google Sheets, Slack or a webhook through
  [Apify integrations](https://docs.apify.com/platform/integrations), for example "send every new competitor
  transcript to a sheet".
- **AI agents:** the Actor works as a tool through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp)
  in Claude, ChatGPT, Cursor and other MCP clients, for example "transcribe the last 5 reels of this creator and
  list their hooks".
- From code: call `scrapewise/instagram-reels-transcript` with the Apify JavaScript or Python client.

### Limitations

- **Public reels only.** Private accounts, stories and reels that need login are out of reach.
- **Machine transcription.** Whisper is strong on clear speech; loud music, crowds and heavy slang lower accuracy.
  Use `small` for non-English speech.
- **No speaker names.** The transcript is one text; it does not tell who is speaking.
- **Plays only in profile mode.** Instagram shows play counts on the profile's reels tab, not on the reel page.
- Runs with 4 GB of memory by default (one CPU core for the model). Less memory makes the run much slower, not
  cheaper.

### FAQ

**Do I need an Instagram account or cookies?** No. The Actor reads public pages as a logged-out visitor. Your
account is never involved.

**Do I need an OpenAI or other speech API key?** No. The open Whisper model (faster-whisper) runs inside the
Actor, and its cost is in the per-reel price.

**Can it transcribe private accounts or stories?** No. Only public reels and public video posts.

**Which languages work?** Whisper detects close to 100 languages. For short or noisy clips in a language other than
English, set `language` and use the `small` model.

**Am I charged for music-only reels?** No. They come back as a free `NO_SPEECH` row.

**Why is a reel missing from a profile?** Some accounts hide their reels tab from logged-out visitors
(`NO_RESULTS`), and with `onlyNew` the Actor stops at the first reel it already delivered.

### Changelog

- **18 Oct 2026:** profiles are listed reliably again: when Instagram served its mobile profile page, a real profile
  could come back as `PROFILE_NOT_FOUND`; the first page of reels now comes from the same reels feed in that case.
- **16 Oct 2026:** field reference, more input examples and an integrations section in this page.
- **0.2 (14 Oct 2026):** `onlyNew` for daily monitoring of profiles (memory per profile in your account, free
  `NO_NEW_REELS` row), `profileUrls` as the profile field (the old names still work).
- **0.1 (30 Sep 2026):** first release. Reels by link or by profile without login, Whisper tiny, base or small,
  auto language, timestamps, hook, on-screen text hint, free rows for no speech and errors.

Independent tool, not affiliated with Instagram or Meta.

# Actor input Schema

## `reelUrls` (type: `array`):

Public reels or video posts to transcribe, one per line: links like https://www.instagram.com/reel/DaSz9gXgFla/ or /p/CODE, or just the code (DaSz9gXgFla). Each reel returns one row with the full transcript text, detected language, duration, caption and engagement counts, charged as 'Reel transcribed'. Also accepts 'postUrls', 'directUrls' and 'startUrls'.

## `profileUrls` (type: `array`):

Instagram usernames or profile links, one per line, for example natgeo or https://www.instagram.com/natgeo/. The Actor lists the profile's latest public reels, newest first, and transcribes them, up to 'Max reels per profile'. No login or cookies. Also accepts 'profiles', 'usernames' and 'handles'.

## `maxReelsPerProfile` (type: `integer`):

How many reels to transcribe from each profile, newest first, default 10. You pay per reel transcribed, so this caps the cost of each profile. Reel links are not limited by it.

## `onlyNew` (type: `boolean`):

For scheduled runs on profiles. The first run transcribes up to 'Max reels per profile' and remembers them in a key-value store in your account ('instagram-reels-transcript-state', one record per profile). Later runs transcribe only reels posted since, so you never pay twice for the same reel; a profile with nothing new gives one free NO_NEW_REELS row. Reels that failed for a temporary reason are retried next time. Delete the store to start over.

## `language` (type: `string`):

Leave empty (default) to detect the spoken language of each reel. Or force a 2-letter code, for example en, pt, es, fr, de, hi or ar, when detection picks the wrong language on short or noisy clips.

## `model` (type: `string`):

Speech recognition model: Fast (Whisper tiny), Balanced (Whisper base, the default) or Accurate (Whisper small, slower). Same price for all three. Accurate is best for non-English speech, accents and noisy audio, but takes longer per reel.

## `includeSegments` (type: `boolean`):

On (default): adds a 'segments' list with start and end seconds for each phrase, useful for subtitles or jumping to a moment. Turn off to get only the full text.

## `maxDurationSeconds` (type: `integer`):

Skip videos longer than this many seconds, from 5 to 1,800 (default 600, 10 minutes). Longer videos get a free VIDEO_TOO_LONG row instead of a transcript. Reels over 2 minutes are charged an 'Extra minute' per started minute beyond the first two, so lower this to cap the cost.

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

Apify Proxy is the default and recommended. Instagram pages go through the proxy and, when Instagram keeps refusing datacenter IPs, the Actor moves to residential proxies on its own, with no extra charge. Audio is downloaded directly from Instagram's CDN. Change it only to use your own proxies.

## Actor input object example

```json
{
  "reelUrls": [
    "https://www.instagram.com/reel/DaSz9gXgFla/"
  ],
  "maxReelsPerProfile": 10,
  "onlyNew": false,
  "model": "base",
  "includeSegments": true,
  "maxDurationSeconds": 600,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `resultsCsv` (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 = {
    "reelUrls": [
        "https://www.instagram.com/reel/DaSz9gXgFla/"
    ],
    "maxReelsPerProfile": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/instagram-reels-transcript").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 = {
    "reelUrls": ["https://www.instagram.com/reel/DaSz9gXgFla/"],
    "maxReelsPerProfile": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/instagram-reels-transcript").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 '{
  "reelUrls": [
    "https://www.instagram.com/reel/DaSz9gXgFla/"
  ],
  "maxReelsPerProfile": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapewise/instagram-reels-transcript --silent --output-dataset

```

## MCP server setup

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

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/kImDLtFdBhx3E5f2I/builds/IZTBJPOOuBIJ0Nar5/openapi.json
