# Instagram Reel Transcript - Audio to Text, Any Language (`neonroobz/instagram-transcripts`) Actor

Instagram reel transcripts from the audio, in the language spoken, not a translation. More accurate than the leading Store tool in our 60-reel test. $5 per 1,000; silent reels and failures free. Reels, posts and creator handles. Pro: English translation, summary, hook. On-screen text add-on.

- **URL**: https://apify.com/neonroobz/instagram-transcripts.md
- **Developed by:** [nnrbzz](https://apify.com/neonroobz) (community)
- **Categories:** Social media, AI, Videos
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

## Instagram Reel Transcript - Audio to Text, Any Language

Get **Instagram reel transcripts from the audio, in the language actually spoken**, from **reel links, post links and whole creator profiles**. Other tools guess the language, translate, or charge for reels with no speech; this one transcribes what is said, names the spoken language, and charges nothing for silent reels or failures. Paste a reel link and click Start: **$5 per 1,000 transcripts**. Add the **on-screen text** reader for silent reels, or **Pro** for a translation (English or any language you pick), a summary and the hook.

### What does it do?

- **Transcribes the audio, in the language spoken.** Spanish stays Spanish, Hindi stays Hindi, Japanese stays Japanese. Nothing is translated unless you turn on Pro.
- **More accurate than the leading Store tool in our published test.** Two blind audio judges scored our transcripts 8.2 out of 10 against 6.4, and the right language 96% of the time against 81%. See [the comparison](#how-does-it-compare-measured).
- **Never charges for a silent reel.** A no-speech check runs before any charge, so music-only reels, silence and invented "speech" come back as free `no_speech` rows.
- **Reads on-screen text** (an add-on): titles, lists and captions burned into the video, also on reels with no speech. Charged only when text is found.
- **Takes reels, posts and creator handles in bulk,** mixed in one run.
- **Pro adds a translation into English or any language you pick, a 5-point summary with 3 topics, and the hook**: what is said in the first 5 seconds.

It works through the Apify API, on a schedule, in Claude, Cursor and ChatGPT through Apify's MCP server, and in n8n, Make and Zapier.

### Use cases

- **Content research:** read what creators in your niche say, in their own words and language.
- **Hooks and scripts:** collect the opening lines of a creator's best reels (Pro).
- **Repurposing:** turn reels into captions, blog posts, newsletters and subtitles.
- **Brand and competitor monitoring:** transcribe a creator's latest reels every day.
- **Recipes, tips and tutorials:** keep the spoken steps and the on-screen lists together.
- **AI agents:** a stable `status` and `error_code` on every row, so an agent knows what happened.

### What data do you get?

| | Data | Fields |
|---|---|---|
| 📝 | Transcript from the audio | `transcript`, `words` |
| 🗣️ | Spoken language (ISO code) | `language` |
| 🎬 | Reel details | `shortcode`, `url`, `creator`, `caption`, `duration_s`, `uses_original_audio` |
| 🚦 | Outcome and charge | `status`, `error_code`, `error`, `charged_event`, `charged_events` |
| 🤖 | How it was made | `model`, `fallback_used`, `audio_source`, `chunks`, `input` |
| 🔤 | On-screen text (add-on) | `on_screen_text`, `on_screen_status`, `on_screen_model` |
| ✨ | Pro: translation, summary, hook | `translation`, `translation_language`, `translation_en`, `summary`, `hook`, `pro_status` |

### How to get Instagram reel transcripts

1. [Create a free Apify account](https://console.apify.com/sign-up).
2. Open this actor and click **Try for free**.
3. Paste reel or post links, or creator handles.
4. Click **Start**.
5. Download the results as JSON, CSV or Excel, or get them through the API.

An empty input runs one example reel, so you can see a real row first.

### How much does it cost to get Instagram transcripts?

| Price | Per 1,000 reels | Each | Charged when |
|---|---|---|---|
| Transcript | **$5 per 1,000** | $0.005 | a transcript passes the no-speech check |
| Transcript + Pro | **$12 per 1,000** | $0.012 | Pro is on, and the translation (unless the reel is already in your target language), summary and hook are all delivered (instead of the $0.005) |
| On-screen text | **$4 per 1,000** | $0.004 | the add-on is on and text is found on screen |
| Silent reels, failures, private reels | **free** | $0 | never |

Pro is charged only when translation, summary and hook are all delivered; otherwise the base price. Every target language costs the same.

**Apify's reel scraper is billed to your account too.** To read Instagram, this actor calls Apify's own [Instagram Reel Scraper](https://apify.com/apify/instagram-reel-scraper) under your account, at its own price: about **$2.60 per 1,000 reels** on Apify's free plan (less on paid plans). So a plain transcript costs about **$7.60 per 1,000 all in** on the free plan, and Apify's $5 monthly free credit covers about **650 reels**.

**Examples (our price, plus the scraper's ~$2.60 per 1,000):**

- 6 recent reels from each of 10 creators: $0.30 + about $0.16.
- 1,000 reels: $5 (with Pro: $12) + about $2.60.
- 1,000 reels with on-screen text, 400 of which show text: $5 + $1.60 + about $2.60.

### Input

**One reel** (the prefilled example):

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

**A creator's latest reels, with on-screen text:**

```json
{ "handles": ["@natgeo"], "maxReelsPerHandle": 12, "onScreenText": true }
```

**Pro on a batch of links:**

```json
{ "reelUrls": ["https://www.instagram.com/reel/…/", "https://www.instagram.com/p/…/"], "pro": true }
```

| Field | Default | What it does |
|---|---|---|
| `reelUrls` | — | `instagram.com/reel/…`, `/reels/…`, `/p/…` or `/tv/…` links. A reel given twice is fetched and charged once. |
| `handles` | `[]` | Usernames (`name` or `@name`) or profile links. Each gives its most recent reels; pinned reels are skipped. |
| `maxReelsPerHandle` | 6 | Reels per handle, up to 100. |
| `pro` | `false` | Translation, summary and hook (see [Pro](#pro)). |
| `targetLanguage` | `"en"` | Pro only: the language of the translation and summary, as an ISO 639-1 code (`es`, `ja`, `hi` …). See [Translate into your language](#translate-into-your-language). |
| `onScreenText` | `false` | Read text burned into the video (see [On-screen text](#on-screen-text)). |
| `concurrency` | 3 | Reels processed in parallel, up to 8. |

### Output

One dataset row per reel:

```json
{
  "shortcode": "De1_g_puK0E",
  "url": "https://www.instagram.com/reel/De1_g_puK0E/",
  "creator": "its_tahayah",
  "caption": "…",
  "duration_s": 92.53,
  "uses_original_audio": true,
  "status": "ok",
  "error_code": null,
  "transcript": "So hey you guys, hey. So today we're making chocolate chip cookies. One of my favorite things to make with the kids in my family…",
  "language": "en",
  "words": 260,
  "model": "qwen/qwen3.8-omni-flash",
  "fallback_used": false,
  "audio_source": "audio",
  "chunks": 2,
  "input": "https://www.instagram.com/reel/De1_g_puK0E/",
  "error": null,
  "charged_event": "transcript",
  "charged_events": ["transcript"]
}
```

A reel with no speech is free, and says why:

```json
{ "shortcode": "…", "status": "no_speech", "error_code": "no_speech", "transcript": null, "error": "no speech in the audio (model_no_speech)", "charged_event": null, "charged_events": [] }
```

#### On-screen text

Set `"onScreenText": true`. Four frames, spread evenly over the reel, are read by a vision model. Each row gets:

```json
{ "on_screen_text": "BEFORE YOUR WORKOUT:\nBANANA WITH PEANUT BUTTER\nRICE CAKES", "on_screen_status": "found", "on_screen_model": "google/gemini-2.5-flash-lite", "on_screen_error": null }
```

- **Charged only when text is found** (`on_screen_status: "found"`): $0.004. `none` and `failed` are free.
- **Works on silent reels.** A music-only reel with a list on screen comes back as `status: "no_speech"` (the transcript is free) with its `on_screen_text`, charged as on-screen text only.
- Usernames, watermarks and the app's own buttons are left out.

#### Pro

Set `"pro": true`. Each delivered row also gets:

```json
{
  "pro_status": "ok",
  "translation_en": "…English translation…",
  "translation_note": null,
  "summary": { "bullets": ["…", "…", "…", "…", "…"], "topics": ["…", "…", "…"] },
  "hook": { "text": "So hey you guys, hey. So today we're making…", "start_s": 0, "end_s": 5 },
  "models": { "translation": "deepseek/deepseek-v4-flash", "summary": "anthropic/claude-haiku-5.5" },
  "translation": "…English translation…",
  "translation_language": "en",
  "charged_event": "transcript-pro"
}
```

- **Reels already in the target language get no translation.** `translation` (and `translation_en`) are `null` and `translation_note` says why; the summary and hook are still made.
- **The hook** is the first 5 seconds of audio, transcribed on its own, in the spoken language. If nobody speaks in those 5 seconds, `hook.text` is `null`, `pro_status` is `"no_hook"`, and the row is charged as a plain transcript ($0.005), with its translation and summary.
- **The summary is checked for your language.** If it comes back in another language, it is asked for again once; if it is still not in your language, `summary` is `null`, `pro_status` is `"summary_language"`, and the row is charged as a plain transcript ($0.005), with its translation and hook.
- **If a part fails,** you get the transcript at the plain price ($0.005), with `pro_status: "failed"`, `pro_error_code: "model_error"`, and any part that worked.

#### Translate into your language

Pro translates into English by default. Set `targetLanguage` to any ISO 639-1 code to get the translation and the summary in that language instead, at the same price:

```json
{ "reelUrls": ["https://www.instagram.com/reel/De1_g_puK0E/"], "pro": true, "targetLanguage": "es" }
```

- `translation` holds the text in your language and `translation_language` names it (`"es"`).
- The **summary** is written in your language too. The **hook** stays as spoken: it is the reel's own opening words, not a translation.
- `translation_en` is filled only when the target is English (as before 1.2); for any other target it is `null`.
- A reel already in your language is not translated (see above). With Pro on, a code that isn't ISO 639-1 stops the run before anything is fetched or charged.
- `targetLanguage` is ignored when Pro is off: transcripts are always in the language spoken.

#### Field notes

- `status`: `ok`, `no_speech` or `error`. `error_code` is `null` exactly when `status` is `ok`.
- `language`: the language of the transcript, as an ISO 639-1 code (`en`, `es`, `hi`, `ja` …), read from the text. `null` when it can't be told.
- `uses_original_audio`: `false` when the reel uses a track from Instagram's music library. Lyrics on such reels are often not transcribed, by design.
- `model`: the speech-to-text model that gave the result. `fallback_used: true` means the first model heard no speech (or failed) and a second one was asked.
- `audio_source`: `audio` (the reel's audio file) or `video` (the video file, when there was no separate audio).
- `chunks`: audio over 90 seconds is transcribed in 60-second pieces.
- `charged_event`: the transcript event (`transcript` or `transcript-pro`); `charged_events`: every event charged on the row, including `onscreen-text`.
- `input`: what you gave that led to this reel (a link or a handle).

### How does it compare (measured)

In our test of **60 reels in 7 languages, 24 Oct 2026**, we ran this actor's engine and the leading Store tool for Instagram reel transcripts (`steadyfetch/instagram-reel-transcript-scraper`) on the same reels. Two audio judges (google/gemini-2.5-flash and xiaomi/mimo-v2.5) heard each reel and scored both transcripts blind, under codenames.

| | This actor's engine | Store leader |
|---|---|---|
| Mean judged accuracy (0–10, all 60 reels) | **8.21** | 6.40 |
| Right spoken language (rows with text) | **49 of 51 (96%)** | 47 of 58 (81%) |
| Delivered on reels with speech | 51 of 53 | 51 of 53 |
| Charged on the 6 reels with no speech | **0** | 4 (invented speech, e.g. Japanese labelled Khmer) |
| Rows with invented content (judges are strict: lyrics count) | **17** | 40 |
| Price per 1,000 reels | **$5** (+ ~$2.60 reel scraper) | $13.53 measured |

The leader's one edge in that test was on-screen text on silent reels, which audio judges can't score. This actor now has the on-screen text add-on for that.

### Error codes

Every row with an error code is free.

| `error_code` | Meaning |
|---|---|
| `no_speech` | No speech in the audio: music, silence, or text the models invented and the check caught. With the add-on on, on-screen text is still read (and charged only if found). |
| `private` | The reel or profile is private, age-restricted or needs a login. |
| `unavailable` | Deleted, not found, or a handle with no public reels. |
| `no_audio` | The post has no audio: a photo or carousel post, or a video file with no sound. |
| `download_failed` | The audio and video files didn't download after 3 attempts each. |
| `transcription_failed` | Both speech-to-text models failed after their retries. |
| `invalid_input` | Not an Instagram reel or post link, or not a handle. |
| `internal_error` | An unexpected error on our side. Please open an issue. |

### FAQ

#### How much does it cost?

$5 per 1,000 transcripts ($0.005 each), $12 per 1,000 with Pro, plus $4 per 1,000 reels where on-screen text is found. Pro is charged only when translation, summary and hook are all delivered; otherwise the base price. Silent reels, failures and private reels are free. Apify's reel scraper, which this actor calls under your account, adds about $2.60 per 1,000 on the free plan. See [the pricing table](#how-much-does-it-cost-to-get-instagram-transcripts).

#### Why does my account show a run of Apify's Instagram Reel Scraper?

This actor reads Instagram through Apify's own reel scraper, called under your account, so its fee (about $0.0026 per reel on the free plan) is billed to you directly by Apify. It is one call per run for your links and one for your handles.

#### Can I use it with integrations?

Yes. Apify connects to n8n, Make, Zapier, Google Sheets, Slack, Airbyte and more, and can send the dataset to them when a run finishes. You can also run it on a schedule, for example to read a creator's new reels every day.

#### Can I use it with the API?

Yes. To run it and get the rows in one call, `POST` your input to `https://api.apify.com/v2/acts/neonroobz~instagram-transcripts/run-sync-get-dataset-items?token=<YOUR_TOKEN>`. The Apify clients for Python and JavaScript (`apify-client`) do the same: `client.actor("neonroobz/instagram-transcripts").call(...)`.

#### Can I use it through an MCP server?

Yes. Add `https://mcp.apify.com?tools=neonroobz/instagram-transcripts` to Claude, Cursor, ChatGPT or any MCP client, then ask, for example, "transcribe the last 6 reels from @natgeo". Every input has a working default, and every row carries a stable `status` and `error_code`.

#### Is it legal to scrape Instagram transcripts?

This actor reads only public reels, as a logged-out viewer would see them, and stores no personal data beyond the public creator handle. Scraping publicly available data is generally legal if you respect copyright and personal-data rules such as the GDPR; transcripts are the creators' work, so check how you may reuse them. Instagram's terms restrict automated collection. If you're unsure, ask a lawyer. Apify's blog has more on [the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

#### Which language do I get?

The language spoken in the reel. The speech-to-text model is asked to transcribe verbatim in the language spoken, and the language code is read from the transcript itself. A reel that mixes languages comes back as spoken, labelled by the language most of the text is in.

#### What if a reel has only music?

You get a free `no_speech` row. Speech-to-text models sometimes "hear" words in music or silence; a check on every transcript catches the usual signs (too few words, one phrase repeated) before anything is charged. With the on-screen text add-on, the text on screen is still read.

#### What does the run summary hold?

The `OUTPUT` record in the key-value store holds counts by status and error code, the delivery rate (delivered ÷ delivered + reels that failed on our side), the models used and how often the fallback model was asked, on-screen and Pro outcomes (with `pro_by_target_language`: Pro rows per target language), events charged, model and vision cost, the reel scraper's runs, and `not_processed`: reels not reached because of your spending limit.

#### What about my spending limit?

A reel starts only when the most it can earn still fits under the limit you set for the run, so you are never charged past it. Reels not reached are listed under `not_processed` in the run summary.

#### How often is it updated?

Instagram changes without notice. Each release is checked against our 60-reel test set, and we aim to fix a break within a day of finding it.

#### Is anything stored?

No. Nothing is kept between runs.

### How we measured

- **Test set:** 60 public reels, picked mechanically on 24 Oct 2026 from hashtags: 30 from English food, business and fitness tags, and 5 each from Spanish, Portuguese, Hindi, German, French and Japanese recipe tags, at most 2 per creator. The transcripts turned out to span more than 15 languages.
- **Judging:** two audio judges from different model families heard every reel and scored each transcript for accuracy (0–10), invented content and language, blind, under codenames. They called 53 reels speech and 6 silent; one they split on.
- **Cost:** the leader's price is what it charged on that run. Ours is the listed price; the reel scraper's fee is Apify's free-plan price.
- **Caveats:** model judges, 60 reels, picked from hashtags. The actor's language labelling was improved after the test (short English lines and Hindi written in Latin letters were mislabelled), and the on-screen text add-on, Pro and the hook were added after it.

### Limits

- **Public reels only.** Private, age-restricted and login-only reels come back as free `private` rows.
- **Music-library tracks:** lyrics of licensed songs are often not transcribed; speech over them is.
- **Speech-to-text makes mistakes,** like any model: names, slang and mixed languages are the hardest.
- **No timestamps yet.** Each reel gives one transcript, without per-sentence times.

### Feedback

A reel came back wrong, or something broke? Open an issue in the **Issues** tab with the reel link. We aim to fix a break within a day of finding it.

### Changelog

- **1.2.1 (24 Oct 2026):** Pro is charged only when the summary is in your target language: a summary that is still in another language after one re-ask gives `pro_status: "summary_language"`, `summary: null`, and the plain price. Very short transcripts (a line or two, or song lyrics) now get a summary instead of failing.
- **1.2 (24 Oct 2026):** Pro translates into any language: set `targetLanguage` (ISO 639-1, default `"en"`). New fields `translation` and `translation_language`; the summary follows the target language; `translation_en` is unchanged for English.
- **1.1 (24 Oct 2026):** a Pro reel with no speech in its first 5 seconds (no hook) gets `pro_status: "no_hook"` and is charged as a plain transcript ($0.005), not $0.012.
- **1.0 (24 Oct 2026):** first release.

# Actor input Schema

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

instagram.com/reel/..., /reels/..., /p/... or /tv/... links. A reel given twice is fetched and charged once.

## `handles` (type: `array`):

Usernames (name or @name) or profile links. Each gives its most recent reels, up to maxReelsPerHandle; pinned reels are skipped.

## `maxReelsPerHandle` (type: `integer`):

Most recent reels taken from each handle. Default 6, maximum 100.

## `pro` (type: `boolean`):

Adds a translation into targetLanguage (English by default; skipped when the reel is already in it), a 5-point summary with 3 topics in that language, and the hook (what is said in the first 5 seconds, as spoken). $12 per 1,000 instead of $5.

## `targetLanguage` (type: `string`):

Pro only. ISO 639-1 code of the language for the translation and summary, such as "es", "ja" or "hi". Default "en". Same price for every language.

## `onScreenText` (type: `boolean`):

Also reads text burned into the video (titles, lists, captions) from frames. $4 per 1,000, charged only when text is found, also on silent reels.

## `concurrency` (type: `integer`):

Reels processed in parallel. Default 3, maximum 8.

## Actor input object example

```json
{
  "reelUrls": [
    "https://www.instagram.com/reel/De1_g_puK0E/"
  ],
  "handles": [],
  "maxReelsPerHandle": 6,
  "pro": false,
  "targetLanguage": "en",
  "onScreenText": false,
  "concurrency": 3
}
```

# Actor output Schema

## `transcripts` (type: `string`):

Transcripts: one row per reel, including free rows for silent reels and failures, each with status and error_code.

## `summary` (type: `string`):

Run summary: counts by status and error code, delivery rate, models used, fallback count, events charged, model and vision cost.

# 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/De1_g_puK0E/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("neonroobz/instagram-transcripts").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/De1_g_puK0E/"] }

# Run the Actor and wait for it to finish
run = client.actor("neonroobz/instagram-transcripts").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/De1_g_puK0E/"
  ]
}' |
apify call neonroobz/instagram-transcripts --silent --output-dataset

```

## MCP server setup

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

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/SrcyRQCUif04B4qYx/builds/eLoetqTM1M4tOQqyB/openapi.json
