# Instagram Reels to Text · @handle (`steadyfetch/instagram-reel-transcript-scraper`) Actor

Handle in, transcripts out: a creator's recent reels turned into text with a 3-second hook. Music-only, private and failed reels are never charged. No login, any length, one box — every row also carries the post's date, plays and likes. Or paste reel links, or chain a dataset ID.

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

## Pricing

from $5.00 / 1,000 reel transcripts

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Instagram Reel Transcript Scraper — @handle in, reels to text with 3-second hooks

**A creator's handle in, their reels back as text** — full speech-to-text, the first-3-seconds hook, language and timestamped segments, one row per reel. No scraper, no login, any length. Paste `zachking` (or a profile URL) and the actor lists that creator's reels itself and transcribes them, in one box. You can still paste reel links, pass CDN media URLs, or chain any Instagram scraper by dataset ID. **You are charged only when a transcript is delivered** — private accounts, missing handles, expired URLs, music-only reels and image posts charge nothing. (Optional: switch on **Read on-screen text on silent reels** and a music-only reel's on-screen copy is read from its own frames and delivered instead, charged like a transcript.)

This is a **transcript of what is said in the audio** — not the caption text under the post.

*Unofficial. Not affiliated with, endorsed by, or sponsored by Instagram or Meta Platforms, Inc.
This actor reads publicly available reels; Instagram is a trademark of Meta Platforms, Inc.*

| You give it | You get back |
|---|---|
| An Instagram **handle** (`nasa`, `@nasa`, or a profile URL) | `transcript` — full speech-to-text, any length |
| …or plain reel links (`instagram.com/reel/…` / `instagram.com/p/…`) | `hook3s` — what's said in the first 3 seconds |
| …or reel video/audio URLs (`videoUrl` / `audioUrl` from any Instagram scraper) | `language`, `durationSeconds`, timestamped `segments` |
| …or your scraper run's **dataset ID** (one-click chaining), or pasted dataset rows | the reel's `shortCode`, `postUrl`, `ownerUsername`, `caption`, `takenAt`, `plays`, `likes`, `comments`, `thumbnailUrl`, `urlExpiresAt` |

### Output

One reel in, one JSON row out. Delivered rows carry the transcript and `charged: true`; anything that could not be delivered carries a `status` saying why, and `charged: false`. Real rows from the live example run below (long text trimmed with … for the page):

| status | charged | hook3s | transcript | language | durationSeconds |
|---|---|---|---|---|---|
| `transcribed` | `true` | I think we got my mom the perfect Mother's Day gift this year, and I'm so excited. | I think we got my mom the perfect Mother's Day gift this year, and I'm so excited. There's nothing like gifting a good gift. I'm not going to lie. I haven't always hit the nail on… | English | 61.09 |
| `transcribed` | `true` | I am just a girl on a healthy hair journey of over eight years and one of the things that I've | …realized is that most people tend to focus on the hair itself and forget to take care of the scalp… | English | 51.15 |
| `transcribed` | `true` | What I eat in a day to serve a look. | What I eat in a day to serve a look. The Sephora savings event is happening and everything is on sale at Sephora. This only happens, by the way, two times a year… | English | 110.41 |

The first row above in full, exactly as it sits in the example dataset (transcript trimmed with … for the page):

```json
{
  "status": "transcribed",
  "charged": true,
  "retryable": false,
  "statusReason": null,
  "videoUrl": "https://instagram.fruh4-1.fna.fbcdn.net/o1/v/t2/f2/m86/AQMZN…",
  "audioUrl": null,
  "urlExpiresAt": "2026-08-23T03:49:55.000Z",
  "shortCode": null,
  "postUrl": null,
  "ownerUsername": null,
  "caption": null,
  "transcript": "I think we got my mom the perfect Mother's Day gift this year, and I'm so excited. There's nothing like gifting a good gift…",
  "onScreenText": null,
  "hook3s": "I think we got my mom the perfect Mother's Day gift this year, and I'm so excited.",
  "language": "English",
  "durationSeconds": 61.09,
  "segments": [{ "start": 0, "end": 3.72, "text": " I think we got my mom the perfect Mother's Day gift this year, and I'm so excited." }],
  "chargeEvents": { "transcript": 1, "surchargeMinutes": 0 }
}
```

**[Browse the full live example dataset →](https://api.apify.com/v2/datasets/YAuCFUAdqANc0RKWY/items?clean=true\&format=json)** — real output from a verified run. That run was fed direct media URLs, which is why `shortCode`, `postUrl`, `ownerUsername` and `caption` come back `null` above. **Run it with a handle instead and every one of those columns is filled** — plus `takenAt`, `plays`, `likes`, `comments` and `thumbnailUrl`, which ride along free inside the listing the actor already reads.

Every field is always present (explicit `null` over silent omission). Delivered rows are `transcribed`, or `onscreen_text_extracted` when the optional on-screen-text switch is on and a silent reel's copy was read from its frames (that row carries `onScreenText` instead of a transcript). Every row also carries `retryable` — `true` only when another run could plausibly get a different answer, so you can re-run the rows worth re-running and leave the rest. Non-delivered rows carry `status` + `statusReason` instead and are never charged:

| status | what it means |
|---|---|
| `no_reels_found` | a real public profile with no video posts in the reels we read |
| `private_account` | the creator's posts are not publicly readable |
| `not_found` | no public Instagram profile with that handle |
| `unavailable_schema` | Instagram's own profile service errors on that handle (their bug, not yours) |
| `rate_wall` / `rate_limited` / `source_unavailable` | temporary — nothing was charged, re-run |
| `unavailable_expired` | a signed media URL that expired before we fetched it |
| `private_or_removed` / `resolve_blocked` | a pasted link to a private/removed post, or a reel Instagram won't expose to embeds |
| `no_audio` | music-only reel (never sold as a transcript) |
| `no_onscreen_text` | with on-screen text switched on: a silent reel with no readable copy on screen either — uncharged |
| `demo` | the sample row a run with no input returns |
| `no_audio_stream` | video-only stream — pass the `audioUrl` field too |
| `no_video_found` | image post: its metadata ships with no result fee |
| `input_error` | with guidance naming the fix |
| `failed_*` | after bounded retries; also listed in the run's `ERRORS` record |

### For AI agents & LLMs — copy this block

```
Actor:   steadyfetch/instagram-reel-transcript-scraper  (Apify Store)
Does:    An Instagram handle -> that creator's reels -> full audio transcript +
         first-3-seconds hook + language + timestamped segments + post metadata.
         One JSON row per reel, any video length. No Instagram login or cookies.
Run:     POST https://api.apify.com/v2/acts/steadyfetch~instagram-reel-transcript-scraper/run-sync-get-dataset-items?token=APIFY_TOKEN
Input    (any ONE of these fields is enough):
  {
    "handles": ["nasa"],          // handle, @handle or profile URL - the actor
                                  // lists that creator's reels itself
    "maxReelsPerHandle": 10,      // optional, best-effort, hard cap 500
    "reelUrls": ["https://www.instagram.com/reel/DX7lzTOJ1p6/"],
                                  // plain reel/post links, exactly as copied from the app
    "videoUrls": ["https://scontent-....cdninstagram.com/....mp4"],
                                  // videoUrl / audioUrl from any Instagram scraper
    "datasetId": "<dataset id of any Instagram scraper run>",
    "datasetItems": [ { /* pasted scraper rows, any shape */ } ],
    "includeOnScreenText": false, // optional: read a SILENT reel's on-screen
                                  // text from its frames and deliver that
                                  // instead (charged as a transcript)
    "maxItems": 1000,             // optional cap on transcribable reels
    "maxRunSeconds": 3600         // optional wall-clock bound, 30-3600
  }
Output   one row per reel: status, charged, retryable, statusReason, handle,
         shortCode, postUrl, ownerUsername, caption, transcript, onScreenText,
         hook3s, language, durationSeconds, segments[], takenAt, plays, likes,
         comments, thumbnailUrl, videoUrl, audioUrl, urlExpiresAt
Pricing  pay per event, platform usage INCLUDED, no start fee:
  reel-transcript       $0.015 -> $0.005 per delivered transcript (falls with your Apify plan tier)
  long-video-surcharge  $0.005 per started minute past the first 3 minutes
  Charged only on delivery — private accounts, missing handles, expired links,
  music-only reels, image posts and failures cost $0. With includeOnScreenText
  on, a silent reel WITH readable on-screen text is delivered and charged one
  reel-transcript event; one with no readable text stays uncharged.
  Cap any run with maxTotalChargeUsd (minimum $0.05).
MCP:     reachable through Apify's MCP server; ask for "instagram reel transcripts".
```

### Why this Instagram transcript scraper?

- **The whole chain in one box.** Handle in, transcripts out: the actor finds the creator's reels, gets each one's video, and transcribes it. No scraper to run first, no dataset to copy between actors, no login and no cookies.
- **A transcript, not a caption.** Some tools sell the post caption as a "transcript". This actor downloads the reel's audio and transcribes the actual speech — the caption ships alongside it, clearly labeled, so you can compare.
- **Charged only on delivery.** A transcript either lands in your dataset or the row carries no result fee. Expired URL → uncharged row that says so. Music-only reel → uncharged row that says so. No "it ran and charged me but returned nothing."
- **Music-only detection.** Speech-recognition models hallucinate filler text ("Thank you.") on music. We detect that and return an honest, uncharged `no_audio` row instead of selling you a fake transcript — on a music-heavy platform, this fires a lot, and it's the point.
- **Optional: the silent reels, too.** About 1 in 6 reels is music-only, and its message is on the screen rather than in the audio. Switch on **Read on-screen text on silent reels** and those reels come back with the on-screen copy read from the reel's own frames — no second download, no extra event, charged at the same per-transcript price. Leave it off (the default) and nothing changes: silent reels stay uncharged.
- **Any video length.** Long-form videos transcribe fine — the first 3 minutes are included, longer videos add a small per-started-minute surcharge instead of failing or being cut off.
- **Post metadata rides along free.** Every handle-mode row carries `takenAt`, `plays`, `likes`, `comments`, `caption` and `thumbnailUrl` — they arrive inside the same listing the actor already reads, so they cost you nothing extra.
- **Works with any scraper's output.** The input deep-scans your dataset rows for the reel media URLs and metadata (including reels nested inside profile results) — no field mapping, no glue code.
- **Knows when your URLs expire.** Every row includes `urlExpiresAt`, decoded from the signed URL itself — so you can see at a glance whether a dataset is still transcribable before spending anything.

This actor may fail when the platform changes things — failed items are never charged.

### How to transcribe a creator's Instagram reels (no code)

1. Type the creator's handle into **Instagram creators** — `nasa`, `@nasa`, or `https://www.instagram.com/nasa/`. Add as many creators as you like.
2. Set **Max reels per creator** (default 10) and click **Start**.
3. Each reel comes back as one JSON row: transcript + hook + post metadata. That's the whole flow — no scraper, no dataset ID, no login.

**Max reels per creator is best-effort.** Instagram serves a creator's reels 12 at a time and sometimes stops part-way; when that happens the run keeps what it listed, says so in the run message, and charges only for transcripts it delivered.

Already holding links? Paste them into **Instagram reel links** instead. Coming from a scraper you already run? Paste that run's **dataset ID** here (or use Apify's *Connect Actor* integration to chain it automatically), or paste `videoUrl` / `audioUrl` values into **videoUrls**. Mixing modes is fine — a reel supplied twice is delivered and charged once. Export as JSON/CSV, or read it via API.

### Why do Instagram video URLs expire?

Instagram's CDN signs every media URL with an expiry (typically **1–3 days** from when your scraper ran). **Transcribe soon after scraping** — a dataset from last week will have dead links. Expired rows come back as uncharged `unavailable_expired` with the exact expiry time, so you can re-scrape and re-run just those. Every row's `urlExpiresAt` field tells you how long you have.

Pasted reel links don't have this problem — the actor resolves each link to a fresh media URL at run time and transcribes it immediately. A link that can't be resolved (private, removed, or embed-restricted post) comes back as an uncharged `private_or_removed` or `resolve_blocked` row with the reason stated — never a silent charge.

### How much does it cost to transcribe Instagram reels?

**One result = one reel's full transcript payload** (transcript + hook + language + segments + metadata). The first 3 minutes of each video are included; longer videos add a small per-started-minute surcharge. No start fee, no subscription, no third-party API key to buy.

| Job | Approx. cost |
|---|---|
| One creator's last 10 reels | ≈ $0.15 |
| 100 reels from a creator's profile | ≈ $1.50 |
| 1,000 reels (a serious content teardown) | ≈ $15 |
| Apify free plan ($5 credit) | ≈ **330 reel transcripts** |

Platform usage (compute + transfer) is **included in the event price** — the per-transcript price you see is the whole price. Rows that don't deliver a transcript carry no result fee. Cap any run with **Maximum cost per run** (any amount from $0.05 up) and it stops cleanly before your ceiling.

### Use it via API, MCP, and integrations

- **API**: standard Apify run API — `POST .../acts/steadyfetch~instagram-reel-transcript-scraper/runs` with `{ "handles": ["nasa"] }`, `{ "reelUrls": ["https://www.instagram.com/reel/…/"] }`, `{ "datasetId": "..." }`, or `{ "videoUrls": ["..."] }`. Python/Node clients work as with any actor.
- **MCP**: works from Claude, Cursor, and any MCP client through Apify's MCP server — give it a handle, reel links or a dataset ID and ask for "instagram reel transcripts".
- **n8n**: a free ready-made template, no community nodes needed — **[Instagram Reel Transcripts →](https://github.com/steadyfetch/n8n-templates#instagram-reel-transcripts--scrape-a-profiles-reels--hooks--transcripts)** (scrape a profile's reels → transcribe by dataset ID → spreadsheet-shaped rows, 3-minute setup).
- **Make / Zapier**: call it as a regular Apify actor step right after your Instagram scraper node.

### Works with — Instagram scrapers you can chain from

This actor reads the **media URL value** in each row (any Instagram CDN `.mp4` link), not a fixed field name, so it works with any Instagram scraper that exports direct media links. Verified shapes on this store:

| Scraper | Where the media URL lives in its output |
|---|---|
| [apify/instagram-scraper](https://apify.com/apify/instagram-scraper) | `videoUrl` (posts), `latestPosts[].videoUrl` (profiles) |
| [apify/instagram-reel-scraper](https://apify.com/apify/instagram-reel-scraper) | `videoUrl` + `audioUrl` |
| [apify/instagram-post-scraper](https://apify.com/apify/instagram-post-scraper) | `videoUrl`, `childPosts[].videoUrl` |
| [apify/instagram-api-scraper](https://apify.com/apify/instagram-api-scraper) | `videoUrl` + `audioUrl` (same output shape as the reel/post scrapers) |

**How to chain:** run the scraper → copy the run's **dataset ID** into this actor's *Dataset ID* field, or use Apify's *Connect Actor* integration to pass it automatically → Start. Using a scraper that isn't listed? If its rows contain the Instagram CDN media link, it works the same way — and if a row doesn't, it comes back as an uncharged `no_video_found` with its metadata intact.

### Steadyfetch Instagram suite

Handle in, structured rows out. All-inclusive pay per event, no start fee, charged only on delivery.

| What you want | Actor |
|---|---|
| Reels turned into text, with the 3-second hook | **this actor** |
| A profile's recent posts, capped where you say | [Instagram Profile Posts · Capped](https://apify.com/steadyfetch/instagram-profile-posts) |

**The rest of the steadyfetch shelf** — same contract everywhere: all-inclusive pay per event,
no start fee, charged only on delivery.

| Family | Actors |
|---|---|
| Ad creative intelligence | [Facebook](https://apify.com/steadyfetch/facebook-ads-transcript-scraper) · [Google Ads video](https://apify.com/steadyfetch/google-ads-video-transcript-scraper) · [TikTok](https://apify.com/steadyfetch/tiktok-ads-transcript-scraper) · [LinkedIn](https://apify.com/steadyfetch/linkedin-ads-transcript-scraper) · [Google Ads text & OCR](https://apify.com/steadyfetch/google-ads-creative-text-scraper) |
| Trends & keywords | [Google Trends](https://apify.com/steadyfetch/google-trends-scraper) · [Trends Now](https://apify.com/steadyfetch/google-trends-now-scraper) · [Breakout keywords](https://apify.com/steadyfetch/breakout-keywords-scraper) · [Autocomplete keywords](https://apify.com/steadyfetch/google-keyword-suggest-scraper) · [Keyword volume & CPC](https://apify.com/steadyfetch/keyword-search-volume-scraper) · [Social trends](https://apify.com/steadyfetch/social-trends-scraper) |
| YouTube transcripts | [YouTube videos](https://apify.com/steadyfetch/youtube-transcript-scraper) · [YouTube channels](https://apify.com/steadyfetch/youtube-channel-transcripts) |
| **Instagram** | [Reel transcripts](https://apify.com/steadyfetch/instagram-reel-transcript-scraper) · [Profile posts](https://apify.com/steadyfetch/instagram-profile-posts) |
| Jobs | [Indeed](https://apify.com/steadyfetch/indeed-jobs-scraper) · [Career sites by domain](https://apify.com/steadyfetch/company-jobs-by-domain) · [Glassdoor](https://apify.com/steadyfetch/glassdoor-jobs-scraper) · [Multi-board](https://apify.com/steadyfetch/multi-job-board-scraper) · Google Jobs |
| Amazon | [Products](https://apify.com/steadyfetch/amazon-product-scraper) · [Search](https://apify.com/steadyfetch/amazon-search-scraper) · Bestsellers · Sellers |
| Any media file | [Speech to Text · any link or file](https://apify.com/steadyfetch/media-transcriber) |

Unlinked names are publishing shortly on the same account — search **steadyfetch** on Apify Store.

All free n8n templates in one place: **[github.com/steadyfetch/n8n-templates](https://github.com/steadyfetch/n8n-templates)** — no community nodes needed.

### FAQ

**Is this the same as the caption?** No. The caption is text the creator typed under the post; the transcript is what's actually said in the video's audio. You get both, clearly labeled.

**Do I need a scraper at all?** No. Give it a handle and it lists that creator's reels itself, then transcribes them. Links you already have go into **Instagram reel links**. A separate scraper still earns its keep for jobs this actor doesn't do — hashtags, search, or a full post archive — and you can chain its run here by dataset ID.

**What if a creator has no reels, or the account is private?** You get one uncharged row per creator saying exactly that (`no_reels_found`, `private_account`, `not_found`). A creator we could not read is never a failed run and never a charge.

**How deep does it go?** As deep as **Max reels per creator** (up to 500), newest first. Instagram serves reels 12 at a time, so deeper asks take a few more upstream calls; the run stops cleanly and tells you if Instagram cut it short.

**Music-only reels?** You get an honest, uncharged `no_audio` row. We never sell hallucinated filler as a transcript. If those reels matter to you, switch on **Read on-screen text on silent reels**: the actor reads the copy off five frames of the reel and delivers it as `onScreenText`, charged like a transcript. A silent reel with no readable text on screen is still uncharged.

**What does `no_audio_stream` mean?** Some scrapers export a video-only stream (no audio track) plus a separate `audioUrl`. If we get the video-only stream, the row says so — pass the `audioUrl` field too and the audio path is used automatically.

**Languages?** Whisper-class multilingual speech recognition — Spanish, Portuguese, Arabic, Japanese, and ~90 more transcribe out of the box; the detected `language` ships on every row.

**Is it legal to transcribe Instagram reels?** The reels are public content, and your scraper already collected the media URLs. US courts have held that logged-out collection of public Meta data does not breach Meta's terms (Meta v. Bright Data, 2024). As always, how you use the data is on you.

**What happens on a failed download?** Bounded retries, then an uncharged `failed_download` row plus an entry in the run's `ERRORS` record. This actor may fail when the platform changes things — failed items are never charged.

### Feedback & support

Found an issue? Open it on the **Issues tab** — we respond within one business day. Feature requests welcome.

# Actor input Schema

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

Handles or profile URLs — nasa, @nasa or https://www.instagram.com/nasa/. The actor lists that creator's most recent reels itself and transcribes them; no scraper and no login needed. Private accounts, missing handles and creators with no reels come back as uncharged rows with the reason stated.

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

How many of each creator's most recent reels to transcribe. Best-effort: if Instagram stops serving more part-way through, the run keeps what it listed, says so, and charges only for delivered transcripts.

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

Plain Instagram links — instagram.com/reel/…/ or instagram.com/p/…/ — exactly as copied from the app or browser. The actor resolves each reel's video itself; links that can't be resolved (private, removed, or embed-restricted posts) come back as uncharged rows with the reason stated.

## `videoUrls` (type: `array`):

Instagram CDN media links (.mp4 on scontent-*.cdninstagram.com, instagram.f*.fna.fbcdn.net, or video.\*.fbcdn.net) — the videoUrl / audioUrl field from any Instagram scraper result. These signed URLs expire in about 1–3 days, so transcribe soon after scraping; expired rows come back uncharged.

## `datasetId` (type: `string`):

The default dataset ID of a finished Instagram scraper run (works with apify/instagram-scraper, instagram-reel-scraper, instagram-post-scraper, instagram-api-scraper and others). With Apify's 'Connect actor' integration this is filled automatically — the cleanest way to chain.

## `datasetItems` (type: `array`):

Paste rows from your Instagram scraper run. The actor deep-scans each row for reel video/audio URLs + metadata (creator, caption, short code) — works with any scraper's output shape, including nested posts.

## `includeOnScreenText` (type: `boolean`):

OFF (default): a reel with no speech is never charged. ON: music-only and silent reels have their on-screen text read from the reel's own frames and delivered as `onScreenText`, charged like a transcript. Reels with no readable on-screen text stay uncharged either way. About 1 in 6 reels is music-only.

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

Safety cap on how many reels/videos to transcribe in one run, across every input above.

## `maxRunSeconds` (type: `integer`):

Wall-clock bound for the whole run, counted from when the run started. Reels still waiting when it is reached come back as uncharged rows saying so, and the run finishes cleanly instead of being cut off.

## Actor input object example

```json
{
  "handles": [
    "zachking"
  ],
  "maxReelsPerHandle": 3,
  "includeOnScreenText": false,
  "maxItems": 1000,
  "maxRunSeconds": 3600
}
```

# Actor output Schema

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

One row per reel/video: transcript, first-3s hook, creator, caption, duration, post metadata (posted date, plays, likes, comments) and a status (transcribed / no\_audio / no\_audio\_stream / unavailable\_expired / no\_reels\_found / not\_found / private\_account / …). Only 'transcribed' rows are charged.

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

Delivered count, uncharged misses, failures, and the honest status message.

## `errors` (type: `string`):

Present only when downloads/transcription failed after all retries: media URL and reason.

# 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 = {
    "handles": [
        "zachking"
    ],
    "maxReelsPerHandle": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyfetch/instagram-reel-transcript-scraper").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 = {
    "handles": ["zachking"],
    "maxReelsPerHandle": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("steadyfetch/instagram-reel-transcript-scraper").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 '{
  "handles": [
    "zachking"
  ],
  "maxReelsPerHandle": 3
}' |
apify call steadyfetch/instagram-reel-transcript-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/5NPYjuQRaRckuFXRI/builds/Rwj4oi52Y1BXgr8D4/openapi.json
