Instagram Reel Transcript Scraper — Reels to Text Transcription avatar

Instagram Reel Transcript Scraper — Reels to Text Transcription

Pricing

from $5.00 / 1,000 reel transcripts

Go to Apify Store
Instagram Reel Transcript Scraper — Reels to Text Transcription

Instagram Reel Transcript Scraper — Reels to Text Transcription

A creator's reels as text: full speech-to-text, the first-3s hook, language and timestamps, one row per reel with its date, plays and likes. Handle in, or paste reel links, or chain a dataset ID. No login, any length. Music-only, private and failed reels are never charged.

Pricing

from $5.00 / 1,000 reel transcripts

Rating

0.0

(0)

Developer

Steadyfetch Team

Steadyfetch Team

Maintained by Community

Actor stats

0

Bookmarked

22

Total users

16

Monthly active users

16 hours ago

Last modified

Share

Instagram Reel Transcript Scraper — Reels & Video Transcription

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 — the first 3 minutes of each video are included, and longer videos add a small per-started-minute surcharge. Paste zachking (or a profile URL) and the actor lists that creator's reels itself and transcribes them, in one box. Just want to see it work? Click Start with nothing set — or send an empty input from the API or an agent — and the run is a 2-reel sample of zachking's latest reels, transcribed and charged like any run. Changed only an option — the on-screen-text toggle, a cap, New reels only, a watchlist name — and named nothing? Those settings are applied to the same sample and the run goes ahead, charged like any run, with one uncharged sample_note row saying which settings were yours; a cap smaller than the sample is honoured exactly, a bigger one never grows it. 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. Running the same creators again? A reel already delivered to your account is handed back from that run and not charged a second time — automatically, however it arrives. Following creators over time? Name a watchlist and re-run on a schedule: with New reels only you get only what is new (see Watch creators on a schedule).

Instagram Reel Transcript Scraper input form in the Apify console: the Instagram creators list set to one handle with max reels per creator 2, above the reel links, media URL and dataset chaining fields

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 itYou get back
An Instagram handle (nasa, @nasa, or a profile URL)transcript — full speech-to-text, any length (first 3 minutes included, then a small per-minute surcharge)
…or plain reel links (instagram.com/reel/… / instagram.com/p/…)hook3s — the reel's opening line, plus hookStartSeconds
…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 rowsthe reel's shortCode, postUrl, ownerUsername, caption, takenAt, isPinned, plays, likes, comments, thumbnailUrl, urlExpiresAt
…plus a watchlist name (optional)isNew and firstSeenAt on every row — and, with New reels only, nothing you already paid for

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):

Dataset table of a real Instagram Reel Transcript Scraper run: two transcribed reels with their opening hook, full transcript, duration, short code and post URL

statuschargedhook3shookStartSecondstranscriptlanguagedurationSeconds
transcribedtrueI think we got my mom the perfect Mother's Day gift this year, and I'm so excited.0I 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…English61.09
transcribedtrueI am just a girl on a healthy hair journey of over eight years and one of the things that I've0…realized is that most people tend to focus on the hair itself and forget to take care of the scalp…English51.15
transcribedtrueWhat I eat in a day to serve a look.0What 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…English110.41

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

{
"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.",
"hookStartSeconds": 0,
"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 → — 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 inside the listing the actor already reads, at no extra charge.

With a watchlist name set, every row also carries the two fields the list adds — "isNew": true for a reel the list had not answered before, "isNew": false for one it had, and "firstSeenAt", the moment it was first answered (this run's clock for a new reel, the original sighting for an old one). Without a watchlist both read null.

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 retryabletrue only when another run could plausibly get a different answer, so you can re-run the rows worth re-running and leave the rest.

Newest first means newest by date. A creator's reels come back in the order they were posted, most recent first — not in the order Instagram's grid shows them, which leads with the reels the creator pinned. A pinned reel is still delivered, in its real date position, and every handle-mode row carries isPinned so you can tell it apart or filter it out (null on rows that did not come from a handle). Reels transcribe several at a time, but the rows are written in that order regardless of which one finishes first. Pasted links and chained dataset rows come back in the order you supplied them, so you can join them back to your own list by position.

Every handle-mode row says which Instagram surface listed it. postSource is "profile-page" for the creator's profile — its listing, or the reels shown on the profile page itself — and "feed" for the deeper post feed a bigger ask walks. Pasted links and chained dataset rows leave it null.

If Instagram walls the post feed, the profile page still delivers. When Instagram refuses a creator's post feed on every connection the run tries, the actor reads the reels shown on that creator's profile page and transcribes those instead — the newest of the 12 posts that page shows. Runs that used to come back with nothing now come back with transcripts, charged exactly like any other. The profile page publishes less than the feed does, so those rows carry the caption, thumbnail and the posted date to the day, while plays, likes and comments come back null. If no reel can be read at all, the creator's row is uncharged and says to re-run.

The last row of every run is an uncharged _summary receipt: attempted, delivered, unchargedMisses, chargedRows, chargedEvents (per priced event), stoppedBy and the run's one-line verdict. It is built from the rows above it, so chargedRows always equals the number of rows marked charged: true — your invoice reconciles from the dataset itself.

Non-delivered rows carry status + statusReason instead and are never charged:

statuswhat it means
no_reels_founda real public profile with no video posts in the reels we read
private_accountthe creator's posts are not publicly readable
not_foundno public Instagram profile with that handle
unavailable_schemaInstagram's own profile service errors on that handle (their bug, not yours)
rate_wall / rate_limited / source_unavailable / resolve_unavailabletemporary — nothing was charged, re-run
resolve_signin_wallInstagram served a sign-in page instead of the reel page — about this run, not about the reel; nothing was charged, re-run
unavailable_expireda signed media URL that expired before we fetched it — and, when the row carried a reel shortcode, a fresh copy could not be fetched from the reel page either
private_or_removeda pasted link Instagram has no post for at all — private, removed, or the shortcode is wrong
no_video_in_posta pasted link to a photo post, or to a carousel whose every item is a photo — there is no video on it to transcribe; uncharged
resolve_blockedInstagram marks that reel copyright-blocked for embeds and will not serve its video
resolve_unexplainedInstagram served the page and it carried no video and no reason we recognise — temporary, nothing charged, re-run
no_speechthe reel has audio but nobody speaks in it — music-only or silent (never sold as a transcript)
no_onscreen_textwith on-screen text switched on: a silent reel with no readable copy on screen either — uncharged
demothe sample row a run with no input returns
run_summary / stopped_at_limitthe closing _summary receipt — the second form when a limit you set (max reels, max cost, run timeout) ended the run early, naming which one
no_audio_streamvideo-only stream — pass the audioUrl field too
no_video_foundimage post: its metadata ships with no result fee
skipped_deadlinethe run was near its time limit, so this lookup was skipped — uncharged; re-run, or raise the run timeout
input_errorwith guidance naming the fix
failed_*after bounded retries; also listed in the run's ERRORS record

Watch creators on a schedule — pay only for new reels

You never pay for the same reel twice. Every run remembers the reels it answered for your account — in a key-value store called ig-reels-watch-account in your own Apify account — under every identity the reel has (its short code and its media file). Run the same creators, reel links, chained rows or media URLs again and the reels you already have come back from the run that delivered them: repeat: true, firstSeenRunId, not downloaded, not transcribed, not charged. The status line counts them (2 of these you already had: handed back, not charged) and OUTPUT.repeats holds the number. Delete that store to forget everything; entries older than 90 days are no longer treated as repeats.

Following a creator is rarely a one-off: the question is usually what did they post since last week? A watchlist answers that with only the new reels.

  1. Put the creators in Instagram creators (reel links, media URLs and chained runs work too).
  2. Give the run a Watchlist name, e.g. acme-creators, and turn on New reels only.
  3. Save the input as a Task, put the Task on an Apify Schedule (daily fits most creators), and add an integration or a webhook on run succeeded — a Google Sheet, Slack, n8n, Make, or your own endpoint.
{
"handles": ["zachking", "nasa"],
"maxReelsPerHandle": 10,
"watchlistId": "acme-creators",
"newReelsOnly": true
}

Each scheduled run then delivers only the reels the list has not answered before, each with isNew: true and its firstSeenAt. Reels already on the list are skipped before anything is downloaded — not fetched, not transcribed, not charged — and the run's status line says exactly what happened, for example: watchlist "acme-creators": 2 new reels this run, 18 already on the list were skipped (not fetched, not charged); 20 on the list now. The same numbers sit in the run's OUTPUT record under watchlist, newItems and skippedSeen, and in the _summary receipt as skippedSeen.

Some details worth knowing:

  • The list lives in your account, in a named key-value store called ig-reels-watch-<your name> (one record, SEEN). Open it in Storage → Key-value stores to see every reel the actor has answered under that name, or delete the record to start the list over. This actor runs with limited permissions and touches nothing else in your account.
  • Only answered reels go on the list. A delivered transcript or on-screen text counts, and so does a final uncharged verdict such as no speech. An expired URL, a failed download, a creator Instagram would not serve this minute, or a reel your cost cap left out is not remembered, so the next run tries it again.
  • What "new" compares against. The actor lists each creator's most recent reels (up to Max reels per creator) and checks those against the list — so a daily run with the default 10 catches anything posted since, and a creator who posts more than that a day just needs a higher number.
  • Leave New reels only off and every reel runs as usual — you still get isNew / firstSeenAt on each row, which is the way to build a full picture while still knowing what is fresh.
  • New reels only without a watchlist name compares against your account's memory instead: reels already delivered to your account are skipped before download. Only when neither a list nor the memory can be read does the run stop with one uncharged row, instead of charging you for reels you may already have. A named watchlist it cannot open stops the run the same way, before any spend.
  • If your account's memory cannot be read, the run still runs: it delivers and charges as usual, and the status line and the charged rows say the repeat check was unavailable (repeatCheck: "unavailable").
  • One reel, one sighting, however it arrives — the same reel listed from a handle, pasted as a link, or arriving as a freshly minted media URL is one entry and one charge.

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 +
opening 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; every field is optional and
accepts null, read as "use the default"):
{
"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 (instagram.com/reel/… or /p/…; not instagram.com/share/… links)
"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 */ } ],
"watchlistId": "acme-creators", // optional: remember answered reels under this name (your own account)
"newReelsOnly": false, // ON: skip reels already on the list (or already delivered to your account) before download
"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 — newest first by date from a handle, and in the
order you supplied them from links or a chained dataset:
status, charged, retryable,
statusReason, handle, shortCode, postUrl, ownerUsername, caption,
transcript, onScreenText, hook3s, hookStartSeconds, language, durationSeconds,
segments[], takenAt, isPinned, postSource, plays, likes, comments,
thumbnailUrl, videoUrl, audioUrl, urlExpiresAt.
Last row: an uncharged `_summary` receipt (attempted, delivered,
chargedRows, chargedEvents, stoppedBy) that reconciles with the
per-row `charged` flags.
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_speech 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.
  • Hook as data, and never blank. hook3s is the reel's first 3 seconds of speech — the line creators and buyers actually study — as its own field, with full segment timestamps beside it. Reels that open on music or a title card are common here, so when nothing is said in the first 3 seconds you get the first 3 seconds of speech from wherever speech actually begins, and hookStartSeconds tells you which second that is (0 when the reel opens speaking). A reel with no speech at all leaves both null — this field is never an empty string, so "the reel opens silent" and "the reel opened talking, we lost it" can't be confused. Sort by hookStartSeconds to see which creators make you wait for the point.
  • Post metadata rides along at no extra charge. Every handle-mode row carries takenAt, isPinned, plays, likes, comments, caption, thumbnailUrl and postSource (which Instagram surface the reel was listed from) — 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 creatorsnasa, @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. Chained rows get the same rescue: when a row's signed URL is dead but the row carries the reel's shortcode (every major Instagram scraper exports one), the actor fetches a fresh copy from the reel page before giving up, so a stale dataset still delivers. A link Instagram has no post for comes back as an uncharged private_or_removed row, one it marks copyright-blocked for embeds as resolve_blocked, and a photo post or an all-photo carousel as no_video_in_post — each with the reason stated; a page that came back with no video and no reason we recognise comes back as a retryable resolve_unexplained row, a lookup Instagram simply would not answer on this run as a retryable resolve_unavailable row, one where it served a sign-in page instead of the reel comes back as a retryable resolve_signin_wall row, and one the run's own time limit left no room for comes back as skipped_deadline — 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.

JobApprox. 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.
  • Building the input from a template? Every field of this actor is optional and accepts an explicit null, read as "use the default" — so a body rendered once per run with the fields you left unset set to null runs exactly as if you had left them out. No field of this actor has to be removed from the body.
  • 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". One-click pin: https://mcp.apify.com?tools=steadyfetch/instagram-reel-transcript-scraper (add it as an MCP server URL and this actor is the only tool the client sees).
  • n8n: a free ready-made template, no community nodes needed — Instagram Reel 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. A row with no media URL still works if the row itself says it is a reeltype: "video", productType: "clips", or its own instagram.com/reel/… link, together with the post's short code: this actor fetches the media from the reel's own page. Some scrapers read a surface that publishes no media URL at all, and those rows used to come back empty. A row that is genuinely not a reel — a photo post, a carousel of photos — is still answered instantly with no result fee and no lookup spent on it. Verified shapes on this store:

ScraperWhere the media URL lives in its output
apify/instagram-scrapervideoUrl (posts), latestPosts[].videoUrl (profiles)
apify/instagram-reel-scrapervideoUrl + audioUrl
apify/instagram-post-scrapervideoUrl, childPosts[].videoUrl
apify/instagram-api-scrapervideoUrl + 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 — or say they are reels and carry a short code — it works the same way, and a row that is neither comes back as an uncharged no_video_found with its metadata intact.

Coming from another transcript actor in this suite? Its list field is called urls; here the same values go in Instagram reel links (reelUrls) or Reel video/audio URLs (videoUrls). You can paste your input across unchanged — this actor reads urls as well and places each value by its shape, with one uncharged row naming the fields this form uses.

Steadyfetch Instagram suite

Handle in, structured rows out. All-inclusive pay per event, nothing charged for starting a run, charged only on delivery. From 16 September 2026 profile posts adds one profile lookup of $0.003 per profile that delivers posts; a profile that delivers nothing pays nothing.

What you wantActor
Reels turned into text, with the 3-second hookthis actor
A profile's recent posts, capped where you sayInstagram Profile Posts Scraper — Exact Limit, No Login

The rest of the steadyfetch shelf — same contract everywhere: all-inclusive pay per event, nothing charged for starting a run, charged only on delivery (three actors add a small delivery-conditional fee from 16 September 2026: keyword volume's fresh lookup, profile posts' profile lookup, Google Jobs' search fee — each README states it).

FamilyActors
Ad creative intelligenceFacebook · Google Ads video · TikTok · LinkedIn · Google Ads text & OCR
Trends & keywordsGoogle Trends · Trends Now · Breakout keywords · Autocomplete keywords · Keyword volume & CPC · Social trends
YouTube transcriptsYouTube videos · YouTube channels
InstagramReel transcripts · Profile posts
JobsIndeed · Career sites by domain · Glassdoor · Multi-board · Google Jobs
AmazonProducts · Search · Bestsellers · Sellers
Any media fileSpeech to Text · any link or file

Free n8n workflow templates for this actor are listed on our profile website (link on our Apify profile).

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 — by date, so a reel the creator pinned to the top of their grid never takes a slot a newer reel owns; it is delivered in its real date position and flagged isPinned. 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_speech 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 reel's on-screen copy 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 usually reply within a couple of hours, always within a day. Feature requests welcome. If this actor earned its keep, a rating helps other buyers find it, and saving it keeps it one click away in your console.