# Instagram Reel Transcript Extractor — AI Speech-to-Text (`inexhaustible_glass/instagram-reel-transcript-extractor`) Actor

Transcribe spoken audio from a public Instagram profile's Reels with AI — full text, language detection, segment & word-level timestamps, optional translation. No login, no API key. Free Cloudflare WARP download path keeps runs cheap.

- **URL**: https://apify.com/inexhaustible_glass/instagram-reel-transcript-extractor.md
- **Developed by:** [Hitman studio](https://apify.com/inexhaustible_glass) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 results

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 Extractor — AI Speech-to-Text

Transcribe the **spoken audio in a public Instagram profile's Reels** with AI —
full text, detected language, sentence-level timestamps, **word-level
timestamps**, and optional translation into 100+ languages. No login, no API
key, no browser.

> Keywords: instagram reel transcript, instagram speech to text, instagram ai
> transcription, instagram transcript generator, reel caption generator, video
> transcript api, word-level timestamps, whisper transcription, social media
> content analysis, creator research tool.

### 🌟 Why this one

The existing Instagram-transcript Actors on Apify carry real demand but a
**2.27/5 average rating despite 3,000+ users** — people want this, the
execution has problems. This Actor is built honestly scoped instead, and
every claim below is something that was actually tested on a real Apify
cloud run, not a marketing number:

- **Free download path** — video files are fetched over **Cloudflare WARP**
  (free, no account, no residential-proxy GB burned) for the bandwidth-heavy
  part of the run, falling back automatically to Apify's proxy pool if WARP
  is ever refused. Only the tiny profile-metadata lookup uses a paid proxy.
- **Word-level timestamps, not just sentence blocks** — every word gets its
  own start/end time and confidence score, ready for auto-captioning.
- **Honest scope**: this version works in **channel mode** (give it a public
  username, it transcribes that profile's recent Reels). Single-reel-URL mode
  isn't offered yet — see the FAQ for exactly why.
- **No fabricated speaker diarization or comment scraping** — neither is
  built yet, so neither is claimed. When they ship, they'll show up here as
  tested features, not promised ones.
- **A real, disclosed limitation**: a small subset of Business/brand-flagged
  Instagram accounts currently can't be read anonymously by *any* tool —
  this Actor fails those cleanly with a real error instead of silently
  returning nothing. Full explanation in the FAQ.

### ⚙️ How it works

1. Fetches the profile's public `web_profile_info` data (the same
   server-rendered endpoint Instagram's own web app uses) — this already
   includes each recent post's direct video URL, no extra request needed.
2. Downloads each Reel's video (free Cloudflare WARP path, residential-proxy
   fallback).
3. Transcribes the audio with **faster-whisper** (CPU, pre-baked model —
   no download delay on your run), with word-level timestamps and automatic
   language detection.
4. Optionally translates the transcript via a free translation endpoint.

### 🚀 Quick start

```json
{ "channelUsername": "nasa", "reelCount": 5, "wordLevelTimestamps": true }
```

Or via the API, once published:

```bash
curl "https://api.apify.com/v2/acts/instagram-reel-transcript-extractor/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"channelUsername": "nasa", "reelCount": 5}'
```

### 📥 Input

| Field | Type | Default | Description |
|---|---|---|---|
| `channelUsername` | string | — (required) | Public Instagram username, no `@` |
| `reelCount` | integer | all (~12) | How many recent reels to transcribe |
| `onlyPostsNewerThan` | string | — | Absolute date (`YYYY-MM-DD`) or relative (`"3 months"`, `"2 weeks"`) |
| `modelSize` | `base` | `small` | `base` | Whisper model — base is faster, small is more accurate |
| `wordLevelTimestamps` | boolean | `true` | Per-word start/end + confidence |
| `translateTo` | string | — | ISO language code for a translated transcript |
| `useWarpForVideoDownload` | boolean | `true` | Free download path, with automatic proxy fallback |
| `maxConcurrency` | integer | `2` | Whisper is CPU-heavy — keep this low unless you know your run has spare CPU |

> ⚠️ **Before you run it:** this Actor reads a username, not a reel URL (see
> FAQ for why). Good input: `"channelUsername": "nasa"`. Bad input:
> `"channelUsername": "https://instagram.com/nasa"` — strip it down to just
> the username. And a small subset of Business-flagged accounts currently
> can't be read anonymously at all (not just by this Actor — see FAQ) —
> those come back as one clear `success: false` row, not a crash.

Example with translation and a date filter:

```json
{
  "channelUsername": "natgeo",
  "onlyPostsNewerThan": "3 months",
  "translateTo": "hi",
  "modelSize": "small"
}
```

### 📤 Output (one row per reel)

| Field | Description |
|---|---|
| `success` | Whether this reel was transcribed |
| `error` | Real error message (only present on failure) |
| `url`, `shortcode` | Reel URL and Instagram shortcode |
| `transcript` | Full transcribed text |
| `language`, `language_probability` | Detected spoken language + confidence |
| `segments` | Sentence-level blocks with start/end timestamps |
| `words` | Word-level timestamps + per-word confidence (when enabled) |
| `translated_text` | Translated transcript (when `translateTo` is set) |
| `caption`, `hashtags`, `mentions` | Parsed from the reel's caption |
| `likes`, `comments`, `views`, `duration`, `width`, `height` | Engagement + media metadata |
| `taken_at` | Post timestamp (unix) |
| `owner_username`, `owner_full_name`, `owner_verified` | Creator info |
| `thumbnail_url` | Reel thumbnail image URL |

```json
{
  "success": true,
  "url": "https://www.instagram.com/reel/Cxxxxxxxxxx/",
  "shortcode": "Cxxxxxxxxxx",
  "transcript": "Would you look at that man.",
  "language": "en",
  "language_probability": 0.982,
  "segments": [{ "start": 2.14, "end": 3.9, "text": "Would you look at that man." }],
  "words": [{ "word": "look", "start": 2.14, "end": 2.32, "probability": 0.971 }],
  "caption": "...", "hashtags": ["space"], "mentions": [],
  "likes": 738377, "comments": 1204, "views": 3241573, "duration": 43.83,
  "owner_username": "nasa", "owner_full_name": "NASA", "owner_verified": true,
  "thumbnail_url": "https://..."
}
```

A reel with no detectable speech, an expired CDN link, or a private/missing
profile produces one row with `success: false` and a real `error` message —
it never silently returns nothing, and one bad reel never stops the rest.

### 📈 Why Instagram Reels

Instagram has over 2 billion monthly active users, and Reels are now the
platform's primary video format — a huge volume of spoken content that, until
now, has existed only as audio inside a video file, not as searchable text.

### 🎯 Use cases

- **Content research** — pull a competitor's or creator's recent talking points at scale
- **Auto-captioning / accessibility** — word-level timestamps drop straight into a caption generator
- **Localization** — translate a creator's content into another market's language
- **Social listening / brand monitoring** — searchable text from video content that was previously unsearchable
- **Trend analysis** — track what language/phrasing a niche's creators are using over time
- **Training data** — transcript + timestamp pairs for fine-tuning or RAG pipelines
- **Compliance / moderation review** — human-readable text version of video claims
- **SEO / repurposing** — turn a reel's spoken content into blog or caption copy

### 🔌 Integration examples

**Python (apify-client):**

```python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("instagram-reel-transcript-extractor").call(
    run_input={"channelUsername": "nasa", "reelCount": 5}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["transcript"])
```

**JavaScript (apify-client):**

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_TOKEN>' });
const run = await client.actor('instagram-reel-transcript-extractor').call({
    channelUsername: 'nasa', reelCount: 5,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

### 📊 Performance & reliability

| Metric | Value (measured, not estimated) |
|---|---|
| Cost per run (1 reel, base model) | ~$0.0038 (real cloud run, tracked via Apify REST API) |
| Transcription engine | faster-whisper, CPU int8, model pre-baked into the image (no runtime download) |
| Word-level timestamp support | Yes, with per-word confidence |
| Posts per profile | Up to ~12 — Instagram's own public-endpoint limit on this data source |
| Known failure mode | Business/brand-flagged accounts (see FAQ) — fails with a clear error, never silently |

### ❓ FAQ

**Does this need an Instagram login or API key?**
No — it reads Instagram's own public profile data and public CDN video files.

**Why only ~12 reels per profile?**
That's how many recent posts Instagram's public profile endpoint itself
returns, with no official "load more" on this data source. This Actor is
honest about that limit rather than claiming unlimited history it can't
actually deliver.

**Why no single-reel-URL input?**
Instagram's individual post/reel page is rendered client-side with no
server-side video URL left in the page source to parse without a logged-in
session — unlike the profile endpoint, which still returns full post data
server-side. Channel mode is the reliable path; we're not shipping a
single-URL mode that would silently fail half the time.

**What happens to reels with no speech (music-only, silent)?**
They come back with `success: false` and a clear error — never a fabricated empty transcript.

**Does every public account work?**
Almost all do. A small subset of brand/Business-flagged accounts (confirmed
with `@natgeo`, `@spacex` — not `@nasa`) currently hit a real,
account-specific Instagram restriction: as of October 2026, Instagram blocks
all anonymous data paths we tested for these accounts — the profile API, the
profile page, and the embed page — confirmed by testing each path
individually with fresh proxy IPs. This was cross-checked against the wider
open-source scraping community (Instaloader's own maintainers have the
identical issue open and unresolved) — it isn't a gap in this Actor, it's a
current platform-side restriction nobody has an anonymous fix for. These
accounts return a clear `success: false` with a real error instead of a fake
result. Personal, creator, and most brand accounts are unaffected.

**Is the free WARP download path reliable?**
It's used only for the video file download, which generally isn't behind
the same anti-bot wall as Instagram's own API — and it falls back
automatically to a proxy if ever refused, so a run never silently stalls on it.

**How accurate is the transcription?**
It uses faster-whisper, the same open-source engine behind most production
Whisper deployments — accuracy depends on audio clarity and accent like any
speech-to-text system. Choose the `small` model for harder audio.

**Is this affiliated with Instagram or Meta?**
No. It reads the same public data any logged-out visitor's browser already
receives — it isn't an official Instagram/Meta product or integration.

**Will this get my Instagram account banned?**
This Actor never logs in or uses any account — yours or anyone else's — so
there's no account to ban. It only reads public profile data and public CDN
video files anonymously.

**Found a bug or an account that fails unexpectedly?**
A failed row always includes a real `error` message — if you see one that
doesn't match the known Business-account limitation above, it's worth
reporting through the Actor's Issues tab so it can be looked into.

### ⚖️ Notes

Reads only public Instagram profile data and public video files. No login,
no scraping of private accounts or DMs.

# Actor input Schema

## `channelUsername` (type: `string`):

A public Instagram username (no @, no login needed). This version works in channel mode only — see README for why single-URL mode isn't offered yet.

## `reelCount` (type: `integer`):

Leave empty to transcribe all video posts Instagram returns for this profile (~12, Instagram's own per-profile limit on this data source).

## `onlyPostsNewerThan` (type: `string`):

Optional. An absolute date (YYYY-MM-DD) or a relative period like '3 months' or '2 weeks'.

## `modelSize` (type: `string`):

Base is faster and accurate enough for most reels. Small is slower but catches more on noisy audio or accents.

## `wordLevelTimestamps` (type: `boolean`):

Start/end time for every individual word, not just each sentence segment — useful for auto-captioning.

## `translateTo` (type: `string`):

An ISO language code (e.g. 'en', 'es', 'hi') to also get a translated version of the transcript. Leave empty to skip.

## `useWarpForVideoDownload` (type: `boolean`):

Routes the actual video file downloads (the bandwidth-heavy part) through free Cloudflare WARP instead of the paid residential proxy pool, falling back automatically if WARP is refused. Keeps runs cheap. Turn off only if you're seeing repeated download failures.

## `maxConcurrency` (type: `integer`):

Whisper transcription is CPU-heavy — keep this low (1-2) unless you know your run has spare CPU.

## Actor input object example

```json
{
  "channelUsername": "nasa",
  "reelCount": 5,
  "modelSize": "base",
  "wordLevelTimestamps": true,
  "useWarpForVideoDownload": true,
  "maxConcurrency": 2
}
```

# Actor output Schema

## `transcripts` (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 = {
    "channelUsername": "nasa",
    "reelCount": 5,
    "modelSize": "base"
};

// Run the Actor and wait for it to finish
const run = await client.actor("inexhaustible_glass/instagram-reel-transcript-extractor").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 = {
    "channelUsername": "nasa",
    "reelCount": 5,
    "modelSize": "base",
}

# Run the Actor and wait for it to finish
run = client.actor("inexhaustible_glass/instagram-reel-transcript-extractor").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 '{
  "channelUsername": "nasa",
  "reelCount": 5,
  "modelSize": "base"
}' |
apify call inexhaustible_glass/instagram-reel-transcript-extractor --silent --output-dataset

```

## MCP server setup

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

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/G6fMB26MM5H4EiS14/builds/zOneu6TC0M0D5TEUm/openapi.json
