Instagram Reel Transcript Scraper API
Pricing
from $10.00 / 1,000 minute of transcribed audios
Instagram Reel Transcript Scraper API
Transcribe Instagram reels with a large speech model. Every row carries a receipt: the media id, the seconds and bytes transcribed against what the manifest declared, and whether the model heard real speech rather than inventing it. Word timestamps, SRT, WebVTT, translation.
Pricing
from $10.00 / 1,000 minute of transcribed audios
Rating
0.0
(0)
Developer
Shakamize
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
3
Monthly active users
8 hours ago
Last modified
Categories
Share
Turns an Instagram reel into text: the full transcript, timestamped segments, SRT and WebVTT subtitle files, and the detected language. Give it reel URLs or bare shortcodes; no Instagram account is involved at any step.
Priced per minute of transcribed audio, rounded up, at $0.010. Most reels are one minute. A post with no audio - a photo, a carousel, a video with a silent track - is reported as such and never charged.
Two competitors already bill by audio time rather than per reel, and the nearest of them charges the equivalent of $0.06 a minute. Billing this way is what lets a three-minute interview and a ten-second clip both be priced honestly.
What makes this different: the receipt
Transcription actors are easy to write and hard to trust. The complaints on this field's worst-rated listing are
Actor returns cached/incorrect transcripts instead of processing provided URLFirst words missing from transcript,
and neither is something a caller can check from a transcript alone.
A provenance field saying "captions or ASR" would not help, because on Instagram there are no captions: nothing in a reel page carries a subtitle track, so speech recognition is the only path and the label would be a constant.
So every row carries the numbers that make both failures decidable:
| Field | What it settles |
|---|---|
mediaId | Which media this transcript came from |
manifestDurationSeconds | How long Instagram said the media was, before any fetch |
audioSecondsTranscribed | How many seconds the model reported hearing |
manifestAudioBytes | How many bytes of audio Instagram declared |
audioBytesTranscribed | How many bytes were actually downloaded and sent |
model | Which speech model produced the text |
language / languageWasForced | What it heard, and whether you told it what to expect |
If audioSecondsTranscribed is short of manifestDurationSeconds, part of the
reel is missing from the transcript and you can see it. If mediaId is not the
reel you asked for, you can see that too. The first two numbers come from
Instagram's own manifest, read before anything is downloaded.
{"shortcode": "DcozHIETCd9","mediaId": "3974651461224900477","ownerUsername": "nasaadmin","language": "English","languageWasForced": false,"model": "whisper-large-v3-turbo","manifestDurationSeconds": 114.426483,"audioSecondsTranscribed": 114.45256192,"manifestAudioBytes": 1028427,"audioBytesTranscribed": 1028427,"billedMinutes": 2}
Word-level timestamps, segments, SRT and WebVTT
Every transcript can come back four ways at once: as continuous text, as timed segments, as a start and end for every individual word, and as SRT or WebVTT files wrapped at whatever line length your player needs. Word timings are what caption burn-in and word-by-word overlays run on.
{ "start": 0.62, "end": 0.82, "word": "Ladies" }
How to translate an Instagram reel transcript to English
Ask for English and you get English whatever was spoken. Translation runs on a
larger, slower model, because it is the only one that will translate at all, so
a translated run bills under the higher-priced translated-minute event and every
row says translatedToEnglish. Word timings are not available when translating,
because the vendor's translation endpoint does not produce them.
There is no model choice, deliberately. The larger model is not the better one: measured over the same six reels it rendered 56 seconds of English interview as Welsh, and invented text on two quiet reels where the default returned almost nothing. Offering it behind a field labelled "accurate" would have sold a quality claim the measurement contradicts, so it is reached by asking for a translation and by nothing else.
Invented transcripts, and how you can tell
Speech models do not fail quietly on audio with no speech in it. They invent. Measured on real reels:
| Reel | What came back |
|---|---|
| A wildlife trailer, music only | "We are the Yamato! We are the Yamato!" |
| Ambient spacewalk footage | "Copyright (c) 2020 Mooji Media Ltd." |
| A fragrance advert, music only | "you" |
None of that is in the audio. It is the single worst failure a transcript can have, because nothing downstream can distinguish it from a real one - and it is the failure the cheap actors in this field ship silently.
Every row therefore carries the model's own confidence, and a flag derived from it:
{ "speechDetected": false, "meanLogProb": -1.932, "text": "you" }
Measured across real reels, genuine speech runs -0.17 to -0.22 and invented text runs -0.52 to -1.93, so the two do not overlap. Set Omit reels with no real speech to drop those rows entirely.
A large model, and what it still gets wrong
Model size is the difference between a transcript and a guess. On the same reel audio, a small model wrote "yoghurt" for "Jokic" and dropped the first 40 seconds of a clip. This actor runs only large models, and puts the model name on every row.
It is still not right about unusual proper nouns, and you should not assume it is. Measured on our own output, on a reel where every other word is correct and the confidence is healthy:
| Spoken | Returned |
|---|---|
| Reid Wiseman | "Reed Weisman" |
| Victor Glover | "Victor Blummer" |
| Christina Koch | Christina Koch |
| Jeremy Hansen | Jeremy Hansen |
So: sentence structure, ordinary words and timings are reliable. Names,
brands and jargon are not. speechDetected catches a transcript that was
invented wholesale; it cannot catch a single wrong name inside an otherwise
good one, and it will read true on the transcript above. If names matter for
your use, treat them as needing a second source.
We tested biasing the model with a supplied vocabulary list, which is the obvious fix and what a competitor advertises. It made things worse on every reel measured - it never corrected a name, it lowered confidence on 3 of 3, once deleted 28% of a transcript, and once appended a spam URL that was not in the audio. So the actor does not offer it.
Costs are known before anything is downloaded
Instagram serves each reel a DASH manifest that declares the duration and the byte length of an audio-only track - about a thirteenth of the size of the video. This actor reads that manifest first, so:
- Skip reels longer than refuses a long reel without downloading it, and charges nothing for it.
- The audio is fetched straight from Instagram's CDN, with no proxy at all. The proxy only ever carries the page.
Batch input, and no silent drops
Pass as many reels as you like in one run. Every reel you ask for produces exactly one row - a transcript, or a record saying why there is none. A run never returns fewer reels than you asked for while reporting success, and an entry that cannot be read stops the run naming it rather than being skipped.
Costing a run before you start it
Because the manifest declares a reel's duration before anything is downloaded, Skip reels longer than and Skip reels shorter than both cost nothing to apply. A three-second clip still costs a whole billed minute, so the minimum is the field that stops a list of trailers being charged like a list of interviews.
Input reference for every Instagram transcript setting
| Field | What it does |
|---|---|
reelUrls | Reel URLs, post URLs, or bare shortcodes |
maxItems | Stop after this many reels |
maxDurationSeconds | Skip anything longer, without downloading it |
minDurationSeconds | Skip anything shorter, without downloading it |
skipPostsWithoutAudio | Leave photos and carousels out of the dataset entirely |
skipLowConfidence | Leave out reels the model says carry no real speech |
speechConfidenceThreshold | How strict the no-real-speech check is |
language | Force an ISO-639-1 code. Empty means detect |
translateToEnglish | English out, whatever was spoken |
timestampGranularity | Segments, words, both, or neither |
subtitleFormats | SRT, WebVTT, or neither |
subtitleMaxCharsPerLine | Wrap cues at your player's line width |
textFormat | One continuous block, or paragraphs on segment boundaries |
includeCaption | The caption the poster wrote |
includeEngagement | Likes and comments. Hidden comes back null, never zero |
includeCaptionEntities | Hashtags and mentions, pulled out as lists |
includeAltText | Instagram's own description of what is on screen |
includeTopics | Instagram's topic labels, for grouping a batch |
includeLocation | The tagged place, with coordinates |
includeMediaUrls | The audio, video and thumbnail URLs |
includeOwnerProfile | The poster's profile. Personal data, off by default |
includeTaggedUsers | Accounts tagged in the post. Personal data, off by default |
includeCoauthors | Credited co-authors. Personal data, off by default |
maxConcurrency | How many reels to work on at once |
proxyConfiguration | Defaults to Apify Proxy's datacenter pool, which is all this needs |
FAQ
How do I know the transcript is real and not invented?
Read speechDetected. Speech models will confidently produce text for audio that
has no speech in it, and a wrong transcript is worse than no transcript, because
nothing downstream can tell.
On a run on 2026-09-01, a 50-second reel with no speech produced the text
"Thank you. Thank you." across two segments. Its mean log probability was
-0.52, speechDetected came back false, and the run said so:
WARN DcMXl1IPNtB: the model reports no real speech (mean log probability -0.52).The text it returned may be invented; speechDetected is false on the row.
The other reel in the same run, 114.5 seconds of actual speech, scored -0.22
with 27 segments and 289 words. Set skipLowConfidence: true to drop the
doubtful ones instead of receiving them flagged.
How do I work out what a run will cost before paying for it?
The reel page declares the audio duration and byte length before anything is
fetched, so a run can size itself in advance. Both land on the row as
manifestDurationSeconds and manifestAudioBytes, next to what was actually
transcribed.
Billing is per minute of audio, rounded up per reel. In the run above, a 114.5
second reel billed 2 minutes and a 50.2 second reel billed 1, for 3 billed
minutes total, and the run states it: Billed 3 minute(s).
maxDurationSeconds and minDurationSeconds cap it before transcription rather
than after.
Which model does it use, and does the tier matter?
whisper-large-v3-turbo, and the tier matters more than it looks. Smaller
Whisper tiers were tested and rejected: base wrote "yoghurt" for "Jokic", and
small silently dropped the first 40 seconds of a clip. Only large-v3-turbo
was usable.
A hosted large model costs less than a locally run small one, so quality and cost point the same way here.
What formats can I get the transcript in?
Continuous text, per-segment and per-word timestamps, SRT and WebVTT, controlled
by textFormat, timestampGranularity and subtitleFormats. A single run can
emit several at once, and subtitleMaxCharsPerLine sets the subtitle line
width.
What happens to posts with no audio?
They are reported rather than silently dropped. The run's closing line accounts for every input:
INFO Stored 2 record(s): 2 transcript(s), 0 post(s) with no audio, 0 too long,0 too short and 0 omitted for carrying no real speech.
skipPostsWithoutAudio drops them from the output if you would rather not see
them. Note that photo posts have no audio to transcribe at all; in one sample,
14 of 35 Instagram posts were photos.
Do I need a login or cookies?
No. Reel pages and the audio itself are read without an authenticated session.
What it does not do
- Private accounts, stories and highlights. Only public posts are reachable without an account, and this actor never uses one.
- Profiles. It takes reels, not usernames. Profile listing pages need a residential proxy where reel pages do not, so crawling a profile would make every run cost about forty times as much per byte for the listing step.
- Music attribution. Instagram serves
music_infoas null to every client without an account - measured on 12 reels across five accounts - so there is no music field rather than one that is always empty.
A reel with music and no speech transcribes to little or nothing. That is the correct answer for it, and it is still a minute of audio the model listened to.
Telemetry
The Actor reports run health to its maintainer: error codes, the build number, and per-field counts. On a failure it also sends a capped sample of the failed requests, including the Instagram URL you asked for. It carries no personal data, but it is your input, and this section says so rather than leave you to find out. Your proxy configuration and the transcripts themselves are never sent.