Instagram Reels Transcript Scraper: Reel to Text, Timestamps
Pricing
from $10.00 / 1,000 transcripts
Instagram Reels Transcript Scraper: Reel to Text, Timestamps
Instagram reel and video transcripts, no login: reel links or creator handles in, the spoken words out (speech-to-text of the audio, not the caption) with the exact date, caption, duration, plays, likes, comments and owner. Optional timestamps, SRT/WebVTT subtitles, comments, the audio file.
Pricing
from $10.00 / 1,000 transcripts
Rating
0.0
(0)
Developer
Hyperbach
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Instagram reel transcripts, no login: reel links or creator handles in, the spoken words out. Speech-to-text of the reel's audio, never the caption, with the exact posting date to the second, the caption, duration, likes, comments and owner on every row, the app play counter named as such on a creator run, and the sound's attribution. Add timed segments, timed words, SRT and WebVTT with the language by the timing model; the first page of comments; the audio or video file with a link that does not expire. A creator's newest reels by date, with a pinned reel in its real place and a date window; a watchlist that delivers only new reels. A reel without speech is an honest free row, and so is every miss. A reel transcribed once is served again from a shared cache by its own id. Private accounts, missing reels, bad values: free rows that say why.
Why this reel transcript scraper
- The words, not the caption. The reel's audio-only stream (about 9 % of the video's bytes) goes to a speech model that answers empty on music where others invent text: in our test of 12 Instagram transcript actors on the same reel, three dated it 35 hours late and two invented words on a music-only reel. Here a music-only reel is a free
no_speechrow, every row names which reel its words came from (shortcode,media_id), and the transcript is never a cached text of another reel. - Exact metadata on every input form. The posting date to the second (
taken_at), the caption, duration, likes, comments and owner come with every reel link and every creator run; a pasted reel link gets them too (the leader returns none on a pasted link). The play counter is Instagram's app counter, named as such (play_count_source): on every creator run, and on a pasted reel among its creator's 12 newest; null where Instagram serves none to a visitor — never a wrong number (72 of the lane's buyer complaints are about counts). - A creator's newest reels, by date. A handle gives its newest reels by posting date, up to
maxReelsPerHandle, inside a date window; a reel pinned to the top of the grid stays in its real place and is flaggedis_pinned(or skipped).onlyNewturns a scheduled creator task into a feed of new reels only: a reel delivered before keeps its place in the count and is never charged again. - Timestamps when you want them.
timestampsadds the timed segments to the end of the reel, the timed words, SRT and WebVTT that drop into an editor, the speech seconds, the hook's start second and the spoken language by the timing model — charged per started minute on top of the transcript. Off, the row carries the words, the first 8 words ashook_3s, and the language detected from the text, labelled as such. - Honest and bounded. No start fee, no platform usage billed to you, no plan cap: a FREE account runs 100 reels. The log says the most a run can cost before the first request,
maxItemsis exact, the charge limit is kept before the model is called, and a run cut by its own timeout delivers what it read and names what it did not. Every miss — a removed reel, a private account, a bad value, an audio the CDN refused — is a free row withstatusandreason. - Fast and plain. No browser, no login, no cookies: one query per reel, one audio read, one model call; a creator's 12 reels list in one call. The audio is read from the worker's own address where Instagram's CDN serves it, so a reel costs a fraction of a cent of traffic.
Who it's for
- Creators, agencies and ghostwriters — the scripts of a creator's latest reels with the hook, the date and the plays, to study what works and write the next one.
- Researchers and analysts — what is said across many reels, with exact dates, counts and the spoken language, from reel links or whole creators.
- Content and ad teams — subtitles in SRT or WebVTT, the timed words and the audio file of a reel, ready for an editor.
- Developers and agents — one row shape, typed fields, a free labelled row for every reel without a transcript, a run summary, and a dataset-chaining input for a pipeline.
Quick start
One reel, the words
{"reelUrls": ["https://www.instagram.com/reel/DealHY4D2Yy/"]}
A creator's five newest reels
{"handles": ["zachking"],"maxReelsPerHandle": 5}
Timestamps, SRT and WebVTT
{"reelUrls": ["https://www.instagram.com/reel/DealHY4D2Yy/"],"timestamps": true}
A creator's reels of the last 30 days, with comments
{"handles": ["garyvee"],"maxReelsPerHandle": 50,"dateFrom": "30 days","includeComments": true}
Chain another scraper's dataset
{"datasetId": "<the dataset id of an Instagram scraper run>"}
Output
One row per reel: the transcript and its labels, the reel's metadata, the options you asked for — or, for a reel without a transcript, the same row with status and reason saying why (free):
| field | meaning |
|---|---|
status | ok = the row carries a transcript (charged). Otherwise free, with reason saying why: no_speech, not_found, private, no_reels, no_video, unavailable, invalid, audio_too_large, audio_failed, transcription_failed, refused, skipped, failed. |
reason | Why the row has no transcript, in words (null on ok rows). |
input | The value you gave that brought the reel into the run (a reel link, a shortcode, a media link, a creator's handle). |
input_kind | What the input was read as: reel, media_url, share, handle, invalid. A creator's listed reels carry reel with the handle in input. |
input_index | The input's position in your list (1 = first); null for a reel that came from a dataset. |
shortcode | The reel's shortcode (the code in its link). Deduplicate on this, or on media_id. |
media_id | Instagram's media id of the reel (the shortcode decoded; stable for the reel's life). |
reel_url | The reel's link. |
owner_username | The creator's username. |
owner_id | The creator's user id. |
owner_full_name | The creator's display name. |
owner_is_verified | True when the creator's account is verified. |
taken_at | When the reel was posted, to the second (ISO 8601, UTC). |
taken_at_timestamp | The posting time as a Unix timestamp. |
caption | The reel's caption, as written (not the transcript). |
duration_s | The reel's length in seconds (from Instagram's record; from the audio file or the timing model where the record has none). |
play_count | Instagram's app play counter, on a creator run (read from the creator's reels list). Null on a pasted reel link: Instagram's reel record carries no counter for a visitor. |
play_count_source | Which counter play_count is: app (Instagram's app play counter). Null where no counter was served. |
like_count | Likes, exact, at the time of the run. |
comment_count | Comments, exact, at the time of the run. |
is_pinned | On a creator run: true when the reel is pinned to the top of the creator's grid (it is still delivered in its real date position). Null on a pasted link. |
has_audio | Instagram's own flag on the reel's record. Not a speech test: the model decides (status no_speech). |
audio_source | Which file carried the audio: dash_heaac (the reel's audio-only stream), progressive_mp4 (the video file, for a licensed-music reel muted on the web), media_url (a CDN link you gave). |
audio_title | The sound's title: the licensed track's, or "Original audio". |
audio_artist | The sound's artist: the track's display artist, or the creator of the original audio. |
is_original_audio | True for an original sound, false for a licensed track. |
is_muted_on_web | True when Instagram mutes the reel's licensed music on the web (the audio is read from the video file then). |
carousel_index | For a /p/ carousel: which item (1-based) is the video that was transcribed. |
carousel_count | For a carousel: how many items it has. |
thumbnail_url | The reel's cover image (Instagram's CDN; expires). |
video_url | The reel's video file on Instagram's CDN (signed; expires at url_expires_at). |
audio_url | The audio file that was transcribed, on Instagram's CDN (signed; expires at url_expires_at). |
url_expires_at | When the first of the signed CDN links on the row (video_url, audio_url) expires, decoded from the links themselves. |
transcript | The spoken words of the whole reel, as one text. |
word_count | Words in transcript. |
language | The spoken language's code (ISO 639-1): by the timing model with timestamps, else detected from the text (see language_source). Null when there is too little text to judge. |
language_name | The spoken language in words ("English"). |
language_source | Where language came from: whisper-1 (the timing model, with timestamps) or text-detection (a detector over the transcript's text). |
hook_3s | The opening hook: the words spoken in the first 3 seconds of speech (with timestamps), else the transcript's first 8 words. |
hook_start_s | With timestamps: the second the first word is spoken at. |
hook_source | How the hook was cut: timed_words (the first 3 s of speech) or first_words (the first 8 words). |
segments | With timestamps: the timed segments, start and end in seconds and text, to the end of the reel (OpenAI whisper-1). |
segment_count | With timestamps: how many timed segments the transcript has. |
words | With timestamps: every word with its start and end in seconds. |
srt | With timestamps: the transcript as SRT subtitles. |
vtt | With timestamps: the transcript as WebVTT subtitles. |
speech_seconds | With timestamps: seconds of the reel that carry speech (the segments' lengths summed). |
transcript_model | The speech model that wrote the words (gpt-4o-mini-transcribe-2025-12-15). |
timing_model | With timestamps: the model that timed the segments and words (whisper-1). |
transcript_from | live = transcribed in this run; cache = served from the shared transcript cache by the reel's media id (the metadata on the row is still this run's). |
transcribed_at | When the words were transcribed (UTC): this run's time, or the cached answer's. |
long_video_minutes | Started minutes of audio past the third on this row (the long_video_minute events charged); null when none. |
timestamp_minutes | With timestamps: started minutes of audio on this row (the timestamps events charged); null when none. |
comments | With includeComments: the reel's first page of comments (up to 15): id, text, created_at, like_count, username, and gif_url for a GIF reply (its text is empty). |
media_files | With downloadMedia: the files written to the run's key-value store, each with kind, key, url, bytes, content_type, source_url, reused. |
audio_file_url | With downloadMedia: audio: a link to the stored audio file that does not expire. |
video_file_url | With downloadMedia: video: a link to the stored video file that does not expire. |
is_new | On a memory run (onlyNew or stateStoreName): true when no earlier run of this memory delivered the reel. |
first_seen_at | On a memory run: the day this memory first saw the reel. |
notes | Anything the row could not carry in full, in words (which egress read the audio, a timing model that did not answer, a field exception beside the record). |
scraped_at | When the row was read (UTC). |
Example record:
{"status": "ok","reason": null,"input": "https://www.instagram.com/reel/DealHY4D2Yy/","input_kind": "reel","input_index": 1,"shortcode": "DealHY4D2Yy","media_id": "4006678053967062578","reel_url": "https://www.instagram.com/reel/DealHY4D2Yy/","owner_username": "garyvee","owner_id": "1697296","owner_full_name": "Gary Vay-Ner-Chuk","owner_is_verified": true,"taken_at": "2026-10-13T01:02:10Z","taken_at_timestamp": 1791853330,"caption": "Listen very carefully to this video -\nAnd share it with someone you know needs it …. ❤️❤️❤️‼️\n\n#lifeadvice #inspiration #garyvee","duration_s": 50.837,"play_count": null,"play_count_source": null,"like_count": 67049,"comment_count": 361,"is_pinned": null,"has_audio": true,"audio_source": "dash_heaac","audio_title": "Original audio","audio_artist": "garyvee","is_original_audio": true,"is_muted_on_web": false,"carousel_index": null,"carousel_count": null,"thumbnail_url": "https://scontent-msp1-1.cdninstagram.com/v/t51.82787-15/844630243_18647662234033297_8717659524241395620_n.jpg?stp=dst-jpg_e15_tt6&_nc_cat=106&ig_cache_key=NDAwNjY3ODA1Mzk2NzA2MjU3ODE4NjQ3NjYyMjMxMDMzMjk3.3-ccb7-5&ccb=7-5&_nc_sid=58cdad&efg=eyJ2ZW5jb2RlX3RhZyI6IkNMSVBTLnhwaWRzLjE0NDAuc2RyLnZpZGVvX2RlZmF1bHRfY292ZXJfZnJhbWUuQzMifQ%3D%3D&_nc_ohc=gBWX7gy0QpMQ7kNvwHPS9k_&_nc_oc=AdrgcQE-Y6ylP3K8Hx6TKI9MUIesOjjNIS91STgVl5TrdCT6zzB3GupEBN4JjazOTcw&_nc_zt=23&_nc_ht=scontent-msp1-1.cdninstagram.com&_nc_gid=u5LSPtaR1OiWzW1g-x6dYQ&_nc_ss=7ea8c&oh=00_AQPS4xy4TVLeicWxq8ajcrUH_lV7QjE1If3dtr30mYJk-g&oe=6AD6C9B5","video_url": "https://scontent-msp1-1.cdninstagram.com/o1/v/t2/f2/m86/AQOOSRfWZXwhveP5Go3hsoHn4l4L3Hknl9vcZhM7QLX99egE2IXDMMesun9Zer6M8gNkn1ZEKvCImdbnAXa8G2ZQd29LBFAkCMtsYJI.mp4?_nc_cat=111&_nc_sid=5e9851&_nc_ht=scontent-msp1-1.cdninstagram.com&_nc_ohc=jibGagR9UvMQ7kNvwFTjt37&efg=eyJ2ZW5jb2RlX3RhZyI6Inhwdl9wcm9ncmVzc2l2ZS5JTlNUQUdSQU0uQ0xJUFMuQzMuOTYwLmRhc2hfYmFzZWxpbmVfMV92MSIsInhwdl9hc3NldF9pZCI6MTg2NDc2NjE1MjAwMzMyOTcsImFzc2V0X2FnZV9kYXlzIjoyLCJ2aV91c2VjYXNlX2lkIjoxMDA5OSwiZHVyYXRpb25fcyI6NTAsInVybGdlbl9zb3VyY2UiOiJ3d3cifQ%3D%3D&ccb=17-1&vs=63de6ba4ce3b6d04&_nc_vs=HBksFQIYUmlnX3hwdl9yZWVsc19wZXJtYW5lbnRfc3JfcHJvZC9GQ0JDRjQzNDNGOTI0OUUyQjRDRkE0NDJEMjcyOUY0RF92aWRlb19kYXNoaW5pdC5tcDQVAALIARIAFQIYUWlnX3hwdl9wbGFjZW1lbnRfcGVybWFuZW50X3YyL0IxQjQyNjFCQUMwRjRFRjE5MjY4RkM5NDA0Q0I0MTQ0X2F1ZGlvX2Rhc2hpbml0Lm1wNBUCAsgBEgAoABgAGwKIB3VzZV9vaWwBMRJwcm9ncmVzc2l2ZV9yZWNpcGUBMRUAACai2NiM4fyfQhUCKAJDMywXQElok3S8an8YEmRhc2hfYmFzZWxpbmVfMV92MREAdf4HZeadAQA&_nc_gid=u5LSPtaR1OiWzW1g-x6dYQ&_nc_ss=7ea8c&_nc_zt=28&oh=00_AQP28XX_aWT847ax3RYRlyIDJQf4k99oJGzZhRfMKxlVhg&oe=6AD2F3C8","audio_url": "https://scontent-msp1-1.cdninstagram.com/o1/v/t2/f2/m78/AQOBx3rD1mrc5rYjtMB8ud3FWsbUCAlH1UwGifdzjtM3qipFmerlE5VQhS9RqSTv8NFvYPAaLbMxNuOgnW9JLRGv6sTkOaWGN0ZS0hc.mp4?_nc_cat=103&_nc_sid=9ca052&_nc_ht=scontent-msp1-1.cdninstagram.com&_nc_ohc=9YHm8ny4UAkQ7kNvwEqRAe2&efg=eyJ2ZW5jb2RlX3RhZyI6ImlnLXhwdmRzLmNsaXBzLmlnd3d3LUMzLmRhc2hfbG5faGVhYWNfdmJyM19hdWRpbyIsInZpZGVvX2lkIjpudWxsLCJvaWxfdXJsZ2VuX2FwcF9pZCI6OTM2NjE5NzQzMzkyNDU5LCJjbGllbnRfbmFtZSI6ImlnIiwieHB2X2Fzc2V0X2lkIjoxODY0NzY2MTUyMDAzMzI5NywiYXNzZXRfYWdlX2RheXMiOjIsInZpX3VzZWNhc2VfaWQiOjEwMDk5LCJkdXJhdGlvbl9zIjo1MCwiYml0cmF0ZSI6NjcwMjEsInVybGdlbl9zb3VyY2UiOiJ3d3cifQ%3D%3D&ccb=17-1&_nc_gid=u5LSPtaR1OiWzW1g-x6dYQ&_nc_ss=7ea8c&_nc_zt=28&oh=00_AQO-KeioQZBL-DsxFhGwvBd4wLpgZ4DpGOgPu1o_jr6t1Q&oe=6AD2FD70","url_expires_at": "2026-10-17T04:04:24Z","transcript": "Everybody calls me a fucking loser and a sibling to you. No, no, but what do you call yourself? I made every wrong mistake a human being could make. But... I almost died from alcohol overdose, almost killed people, drank drunk a hundred times. Of course, but what about... I would be in prison right now. But what about the but? But I'm still alive. And? I didn't die. Most people die, overcame addiction. And? Overcame the alcoholism, right? Do you know how big of a fucking win that is? I admire you for you to be able to have all that adversity and be standing in front of me. What about somebody born with everything advantage, one percent? How about somebody that was born with everything advantage, fucked up for 30 years of it, and then decided at 33 to fucking build, and then at 50 was happy and content and successful and teaching the world that it's okay to fuck up your first 30 years of your life and that you could still go and win. How about that person? Who's that person? That's you.","word_count": 187,"language": "en","language_name": "English","language_source": "text-detection","hook_3s": "Everybody calls me a fucking loser and a","hook_start_s": null,"hook_source": "first_words","segments": null,"segment_count": null,"words": null,"srt": null,"vtt": null,"speech_seconds": null,"transcript_model": "gpt-4o-mini-transcribe-2025-12-15","timing_model": null,"transcript_from": "live","transcribed_at": "2026-10-15T17:22:08Z","long_video_minutes": null,"timestamp_minutes": null,"comments": [{"id": "18642133480049108","text": "Who the F**k is this Gary Vee guy? 🥹🥹🥹","created_at": "2026-10-15T17:00:38Z","like_count": 0,"username": "chibugram"},{"id": "18119401360955382","text": "Nice🔥","created_at": "2026-10-15T17:00:07Z","like_count": 0,"username": "darren_o_rian"},{"id": "18227441983329688","text": "Your past may explain where you started, but your actions determine how far you go. Stop waiting for perfect clarity take action, learn from the results, and let every setback become fuel for the next move.","created_at": "2026-10-15T16:46:27Z","like_count": 0,"username": "the_apex_sk"}],"media_files": null,"audio_file_url": null,"video_file_url": null,"is_new": null,"first_seen_at": null,"notes": ["audio read proxy"],"scraped_at": "2026-10-15T17:22:08Z"}
Pricing
Pay only for the transcripts a run delivers, with no start fee and no platform usage billed to you. Prices fall with your Apify plan.
| per 1,000 | Free | Starter | Scale | Business |
|---|---|---|---|---|
Transcript (transcript) | $20.00 | $17.00 | $14.00 | $10.00 |
Media file (media_file) | +$10.00 | +$8.50 | +$7.00 | +$5.80 |
| per unit | Free | Starter | Scale | Business |
|---|---|---|---|---|
Long video minute (long_video_minute) | +$0.009 | +$0.0087 | +$0.0087 | +$0.0087 |
Timestamps, per minute (timestamps) | +$0.02 | +$0.0185 | +$0.0185 | +$0.0185 |
A transcript is $20.00 per 1,000 reels on the Free plan ($0.02 a reel) and $10.00 on Business; it covers the whole reel up to three minutes of audio. + fees are charged only on a row that carries the thing: a long-video minute per started minute of audio past the third; timestamps per started minute of audio on a row that carries the timed segments (with timestamps on); a media file per audio or video file written to the run's store this run (with downloadMedia). A reel without speech, a removed or private reel, a creator with no reels, a bad value, an audio the CDN refused, a model failure and a reel onlyNew skipped are labelled rows and free; so are the comments and a run that failed. maxItems counts transcripts and is exact; before the first request the log says the most the run's transcripts can cost at your plan's prices and names the per-unit fees of the options you switched on. Enterprise plans have their own rates — the Actor's Pricing tab shows the price for your plan.
Usage patterns
- A creator feed — Save a task with a creator,
onlyNewandmaxReelsPerHandle, and schedule it daily: each run lists the creator's newest reels and delivers and charges only those it has not delivered before — a day without a new reel delivers nothing. A reel without speech is remembered too (its verdict is final); a reel that could not be read is tried again on the next run. Apify's integrations send the rows to a sheet, a webhook or Slack. - Subtitles and files —
timestamps: truegivessegments,words,srtandvtton the row;downloadMedia: "audio"or"video"writes the file to the run's key-value store with a link that does not expire (audio_file_url,video_file_url). Instagram's own media links on the row (video_url,audio_url) expire within days:url_expires_atsays when. - From another scraper — Give
datasetIdthe dataset of an Instagram scraper run (apify/instagram-scraper, instagram-reel-scraper, instagram-post-scraper and the like): every row is scanned for a reel link, a shortcode or a media link, and the reels are transcribed with their metadata read live. With Apify's 'Connect actor' integration the id is filled automatically. - Many reels — Paste any number of reel links, shortcodes or creators;
maxItemsbounds the charged rows across every input. The run reads reels on several exits at once and transcribes them in parallel; the log line at the start says the most the run can cost at your plan's prices.
Input configuration
| field | type | default | what it does |
|---|---|---|---|
reelUrls | array | [] | Instagram reels, one per line, in any form: https://www.instagram.com/reel/DealHY4D2Yy/, a /p/ or /tv/ link, a link with the owner's handle in it, a bare shortcode (DealHY4D2Yy), a share link (instagram.com/share/…, followed to the reel it lands on), or an Instagram CDN media link (scontent-….cdninstagram.com/….mp4: the file is transcribed, no metadata). A creator's handle pasted here (nasa, @nasa) is read as a creator. The same reel given several ways is one row. A /p/ carousel is transcribed from its first video. |
handles | array | [] | Instagram creators, one per line: nasa, @nasa or https://www.instagram.com/nasa/. The Actor lists each creator's newest reels by date (a reel pinned to the top of the grid stays in its real date position, flagged is_pinned) and transcribes up to maxReelsPerHandle of them. A private account, a missing handle or a creator with no reels is a free row. |
datasetId | string | "" | The dataset id of another Instagram scraper's run (apify/instagram-scraper, instagram-reel-scraper, instagram-post-scraper and the like): every row is scanned for a reel link, a shortcode or a media link and transcribed. Empty = none. |
maxReelsPerHandle | integer | 10 | How many of each creator's newest reels to transcribe, newest by date. A reel without speech counts (it is a free row); a reel outside the date window does not. |
dateFrom | string | "" | Creators only: reels posted on or after this date (2026-09-01), or a span back from today (30 days, 2 weeks, 6 months). The walk stops at the first reel older than this. |
dateTo | string | "" | Creators only: reels posted on or before this date (same forms as dateFrom). |
skipPinned | boolean | false | Creators only: leave out the reels pinned to the top of the grid. Off = a pinned reel is delivered in its real date position, flagged is_pinned. |
timestamps | boolean | false | Add the timed segments (segments: start, end, text), the timed words (words), srt and vtt, the speech seconds and the hook's start second, and the spoken language as named by the timing model (OpenAI whisper-1). Charged per started minute of audio on top of the transcript. Off = the words alone, with the language detected from the text. |
includeComments | boolean | false | Add the reel's first page of comments (up to 15: id, text, time, likes, username; a GIF reply with its GIF link) to each row. Free: they come with the reel's record. |
downloadMedia | none / audio / video | "none" | Store the reel's audio stream or its video file in the run's key-value store, with a link that does not expire on the row (audio_file_url / video_file_url). Charged per file written. Instagram's own media links on the row expire within days (url_expires_at). |
maxItems | integer | 0 | The most transcripts this run delivers (and charges). 0 = no limit. Free rows (no speech, not found, private) do not count. |
onlyNew | boolean | false | Skip reels this task delivered in an earlier run: run a creator daily and get only the new reels. A reel without speech is remembered too (its verdict is final); a reel that could not be read is tried again next run. Turns the memory on. |
stateStoreName | string | "" | Name of the memory between runs (onlyNew, is_new, first_seen_at). Empty = derived from your reels and creators, so the same task always meets its own memory. |
proxyUrl | string | Optional. Your own proxy as scheme://user:pass@host:port, used in front of the Actor's own exits. Leave empty to use the maintained exits (recommended). |
Errors
A run does not fail because of your input. When an input cannot be used — a date that is not a date, an id in the wrong form, two settings that contradict each other — the run ends Succeeded, charges nothing, and says what to change:
- the status message starts with
INPUT REJECTED; - the dataset holds one row,
{"error": true, "code": "…", "message": "…"}, and no results; - the key-value store record
ERRORholds the same object.
From code, check error on the first row before reading results.
A search that matches nothing is not an error: the dataset is empty and nothing is charged. A run that ends Failed is a fault on our side, never your input; it charges nothing, and we are alerted.
FAQ
Is it the caption or the spoken words?
The spoken words: the reel's audio goes to a speech model. The caption is on the row too, as caption, clearly apart.
What about a music-only or silent reel?
A free no_speech row with the reel's metadata. The speech model this Actor uses answers empty on music where other models invent text ("Thanks for watching!" and the like); a reel the model hears no words in is never charged.
Which play counter is this?
Instagram's app play counter (play_count, with play_count_source = app), read from the creator's reels list. A pasted reel link takes it from its creator's newest reels page (one extra request per creator in a run) when the reel is among the 12 newest; an older pasted reel gets null: Instagram's reel record carries no counter for a visitor, so the field is null rather than a wrong number. Likes and comments are exact on every row.
Why no shares, saves, reposts, or a keyword search?
Instagram shows shares, saves and reposts to logged-in viewers only, and its keyword and hashtag search is login-only. This Actor reads what a visitor sees, with no account and no cookie, so it does not promise them.
What is never charged?
A reel without speech, a removed or private reel, a creator with no reels, a bad value, a share link that lands nowhere, an audio the CDN refused, a model failure, a reel skipped by onlyNew, a reel the time limit cut before its transcription, the comments, the metadata, and a run that failed before its first row. A run that stops early (a timeout, an abort) is charged for the rows it delivered.
Are the timestamps exact?
With timestamps: true the timing model (OpenAI whisper-1) gives each segment's and each word's start and end in seconds; the last segment ends at the end of the speech. SRT and WebVTT are built from those segments with valid timecodes. Without the option the row carries the words only.
Which language?
With timestamps the timing model names the spoken language (language, language_name, language_source = whisper-1). Without it the language is detected from the transcript's text and labelled text-detection; on a very short transcript it stays null rather than a guess.
How long can a reel be?
Any length Instagram allows: the whole audio goes to the model in one call (its upload limit is 25 MB, about 45 minutes of a reel's audio stream). The first three minutes are in the transcript price; each started minute past the third is a long_video_minute event.
What does the transcript cache do?
A reel transcribed once is kept on our side by its own media id and model: a later run of the same reel, by anyone, gets the same words with no new transcription (transcript_from = cache, transcribed_at = when it was read). The metadata on the row is always this run's live read; a cached plain answer never serves a timestamps ask.
Can an AI agent use it (MCP)?
Yes. Apify's MCP server (https://mcp.apify.com) offers Store Actors as tools to Claude, Cursor and other MCP clients: add this Actor to the server's tool list and the agent sends reelUrls or handles and gets the rows back. The synchronous API (run-sync-get-dataset-items) does the same in one HTTP call.
Integration
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('hyperbach/instagram-reels-transcript-scraper').call({"reelUrls": ["https://www.instagram.com/reel/DealHY4D2Yy/"]});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('hyperbach/instagram-reels-transcript-scraper').call(run_input={'reelUrls': ['https://www.instagram.com/reel/DealHY4D2Yy/']})items = client.dataset(run['defaultDatasetId']).list_items().items
CLI
$apify call hyperbach/instagram-reels-transcript-scraper --input '{"reelUrls": ["https://www.instagram.com/reel/DealHY4D2Yy/"]}'
REST
curl -X POST "https://api.apify.com/v2/acts/hyperbach~instagram-reels-transcript-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H 'Content-Type: application/json' -d '{"reelUrls": ["https://www.instagram.com/reel/DealHY4D2Yy/"]}'
Support
This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.