Instagram Transcript Scraper - Reels & Video
Instagram video to text: paste many reel, post or IGTV links and get each transcript with creator, caption and likes. Reads Instagram captions or uses AI speech-to-text in 29 languages, with optional timestamps per phrase. Export to JSON, CSV or Excel for subtitles and research.
Input schema
Input fields, types, required flags, descriptions, defaults, and prefills come from the published definition. Prefill examples are distinct from defaults.
| Field | Type | Required | Description |
|---|---|---|---|
videoUrls | array | optional | List of Instagram video or reel URLs to transcribe. Supports /p/, /reel/, and /tv/ formats. Provide this, usernames, or both. |
usernames | array | optional | Usernames whose newest posts should be checked for videos. Each entry can be a username (with or without @) or a profile link such as https://www.instagram.com/natgeo/. Every video is transcribed (each video of a carousel on its own); a post without a video gets a record with the status not_a_video. |
maxPosts_per_username | integer | optional | How many of each username's newest posts to check (after the date and pinned-post filters below). Every video among them is transcribed (each video of a carousel on its own); a post without a video gets a record with the status not_a_video. Public profiles need no sign-in, however many posts you ask for; a private profile needs your cookies. |
Show all input fields
| Field | Type | Required | Description |
|---|---|---|---|
videoUrls | array | optional | List of Instagram video or reel URLs to transcribe. Supports /p/, /reel/, and /tv/ formats. Provide this, usernames, or both. |
usernames | array | optional | Usernames whose newest posts should be checked for videos. Each entry can be a username (with or without @) or a profile link such as https://www.instagram.com/natgeo/. Every video is transcribed (each video of a carousel on its own); a post without a video gets a record with the status not_a_video. |
maxPosts_per_username | integer | optional | How many of each username's newest posts to check (after the date and pinned-post filters below). Every video among them is transcribed (each video of a carousel on its own); a post without a video gets a record with the status not_a_video. Public profiles need no sign-in, however many posts you ask for; a private profile needs your cookies. |
newerThan | string | optional | Skip posts published before this date. Leave empty for no date filter. Must be a date from 2000-01-01 up to the day before the run. Applies to usernames only. The date is read from the post's id, so it can be off by up to a day. |
skipPinnedPosts | boolean | optional | Leave out the posts a profile has pinned to the top of its grid. Applies to usernames only. A pinned post that is also the newest post cannot be recognised and stays in. |
transcriptionMethod | string | optional | How to extract transcripts. 'auto' tries native Instagram captions first, then falls back to Whisper AI. 'native' only uses Instagram captions. 'whisper' always uses AI speech-to-text. |
whisperModel | string | optional | Whisper AI model size. Larger models are more accurate but use more memory and time. Only used when transcription method involves Whisper. |
includeSegments | boolean | optional | When enabled, the output will include a 'segments' array with per-segment timestamps and text alongside the full transcript. Each segment represents a distinct phrase with start/end times in seconds. Note: enabling this feature incurs an additional charge per run. |
language | string | optional | Language of the video audio. Leave empty for automatic detection. Only used when Whisper is active. |
cookies | string | optional | Optional. Leave empty to transcribe public videos without signing in. Paste your own Instagram cookies in JSON format to also transcribe age-restricted videos and videos of private accounts your account follows. It is a secret input, so the Apify Console hides and encrypts it. Format: [{"name":"sessionid","value":"...","domain":".instagram.com"}, ...] |
Download the published input schema
View complete JSON
{
"properties": {
"cookies": {
"description": "Optional. Leave empty to transcribe public videos without signing in. Paste your own Instagram cookies in JSON format to also transcribe age-restricted videos and videos of private accounts your account follows. It is a secret input, so the Apify Console hides and encrypts it.\n\nFormat: [{\"name\":\"sessionid\",\"value\":\"...\",\"domain\":\".instagram.com\"}, ...]",
"editor": "textarea",
"isSecret": true,
"title": "Instagram Cookies (Optional)",
"type": "string"
},
"includeSegments": {
"default": false,
"description": "When enabled, the output will include a 'segments' array with per-segment timestamps and text alongside the full transcript. Each segment represents a distinct phrase with start/end times in seconds. Note: enabling this feature incurs an additional charge per run.",
"prefill": false,
"title": "Include Timestamped Segments",
"type": "boolean"
},
"language": {
"default": "",
"description": "Language of the video audio. Leave empty for automatic detection. Only used when Whisper is active.",
"editor": "select",
"enum": [
"",
"en",
"es",
"fr",
"de",
"it",
"pt",
"ru",
"zh",
"ja",
"ko",
"ar",
"hi",
"nl",
"pl",
"tr",
"sv",
"da",
"fi",
"no",
"cs",
"ro",
"hu",
"id",
"vi",
"th",
"uk",
"he",
"fa",
"ms"
],
"enumTitles": [
"Auto-detect",
"English",
"Spanish",
"French",
"German",
"Italian",
"Portuguese",
"Russian",
"Chinese",
"Japanese",
"Korean",
"Arabic",
"Hindi",
"Dutch",
"Polish",
"Turkish",
"Swedish",
"Danish",
"Finnish",
"Norwegian",
"Czech",
"Romanian",
"Hungarian",
"Indonesian",
"Vietnamese",
"Thai",
"Ukrainian",
"Hebrew",
"Persian",
"Malay"
],
"title": "Language",
"type": "string"
},
"maxPosts_per_username": {
"default": 10,
"description": "How many of each username's newest posts to check (after the date and pinned-post filters below). Every video among them is transcribed (each video of a carousel on its own); a post without a video gets a record with the status not_a_video. Public profiles need no sign-in, however many posts you ask for; a private profile needs your cookies.",
"example": 5,
"maximum": 100,
"minimum": 0,
"prefill": 0,
"title": "Max Posts Per Username",
"type": "integer"
},
"newerThan": {
"dateType": "absolute",
"description": "Skip posts published before this date. Leave empty for no date filter. Must be a date from 2000-01-01 up to the day before the run. Applies to usernames only. The date is read from the post's id, so it can be off by up to a day.",
"editor": "datepicker",
"nullable": true,
"title": "Only posts newer than",
"type": "string"
},
"skipPinnedPosts": {
"default": false,
"description": "Leave out the posts a profile has pinned to the top of its grid. Applies to usernames only. A pinned post that is also the newest post cannot be recognised and stays in.",
"title": "Skip pinned posts",
"type": "boolean"
},
"transcriptionMethod": {
"default": "auto",
"description": "How to extract transcripts. 'auto' tries native Instagram captions first, then falls back to Whisper AI. 'native' only uses Instagram captions. 'whisper' always uses AI speech-to-text.",
"enum": [
"auto",
"native",
"whisper"
],
"enumTitles": [
"Auto (recommended)",
"Native captions only",
"Whisper AI only"
],
"prefill": "auto",
"title": "Transcription Method",
"type": "string"
},
"usernames": {
"description": "Usernames whose newest posts should be checked for videos. Each entry can be a username (with or without @) or a profile link such as https://www.instagram.com/natgeo/. Every video is transcribed (each video of a carousel on its own); a post without a video gets a record with the status not_a_video.",
"editor": "stringList",
"example": [
"natgeo",
"@nasa",
"https://www.instagram.com/bbcnews/"
],
"items": {
"minLength": 1,
"type": "string"
},
"maxItems": 100,
"minItems": 0,
"prefill": [],
"title": "Instagram Usernames or Profile Links",
"type": "array"
},
"videoUrls": {
"description": "List of Instagram video or reel URLs to transcribe. Supports /p/, /reel/, and /tv/ formats. Provide this, usernames, or both.",
"editor": "stringList",
"example": [
"https://www.instagram.com/reel/abc123xyz/",
"https://www.instagram.com/p/Dew5IIlNfMW/"
],
"prefill": [
"https://www.instagram.com/p/Dew5IIlNfMW/"
],
"title": "Instagram Video URLs",
"type": "array"
},
"whisperModel": {
"default": "base",
"description": "Whisper AI model size. Larger models are more accurate but use more memory and time. Only used when transcription method involves Whisper.",
"enum": [
"tiny",
"base",
"small"
],
"enumTitles": [
"Tiny (fastest, ~39MB)",
"Base (balanced, ~74MB)",
"Small (most accurate, ~244MB)"
],
"prefill": "base",
"title": "Whisper Model Size",
"type": "string"
}
},
"required": [],
"schemaVersion": 1,
"title": "Instagram Transcript Scraper Input",
"type": "object"
}
Output schema
Published result links and storage locations. This schema is not an exhaustive contract for every field in a dataset record.
| Field | Type | Required | Description |
|---|---|---|---|
transcripts | string | optional | One dataset item per Instagram video URL. Each item includes the full transcript text and complete video metadata. A nested segments array with per-segment timestamps and text is included only when the 'includeSegments' input option is enabled. |
Download the published output schema
View complete JSON
{
"actorOutputSchemaVersion": 1,
"properties": {
"transcripts": {
"description": "One dataset item per Instagram video URL. Each item includes the full transcript text and complete video metadata. A nested segments array with per-segment timestamps and text is included only when the 'includeSegments' input option is enabled.",
"template": "{{links.apiDefaultDatasetUrl}}/items",
"title": "Video Transcripts",
"type": "string"
}
},
"title": "Instagram Transcript Scraper Output",
"type": "object"
}
Dataset schema
Published dataset views and any declared field definitions. A view can select only a subset of the returned record fields.
Download the published dataset schema
View complete JSON
{
"actorSpecification": 1,
"fields": {
"properties": {
"audioUrl": {
"description": "Link to the audio track",
"type": "string"
},
"avatarUri": {
"description": "Link to the creator's profile picture",
"type": "string"
},
"commentCount": {
"description": "Number of comments",
"type": "integer"
},
"createdAt": {
"description": "When the row was created (ISO 8601, UTC)",
"type": "string"
},
"fullText": {
"description": "The whole transcript; empty when the video has no speech",
"type": "string"
},
"id": {
"description": "Instagram's full media id",
"type": "string"
},
"likeCount": {
"description": "Number of likes",
"type": "integer"
},
"pk": {
"description": "Instagram's numeric id of the video",
"type": "string"
},
"postDescription": {
"description": "Caption of the post",
"type": "string"
},
"postUrl": {
"description": "Link to the post or Reel",
"type": "string"
},
"profileUrl": {
"description": "Link to the profile, on a record about a username that gave no posts",
"type": "string"
},
"pubDate": {
"description": "When the video was published (ISO 8601, UTC)",
"type": "string"
},
"segments": {
"description": "Phrases with timestamps in seconds; only present when includeSegments is on",
"items": {
"properties": {
"end": {
"type": "number"
},
"index": {
"type": "integer"
},
"start": {
"type": "number"
},
"text": {
"type": "string"
}
},
"type": "object"
},
"type": "array"
},
"shortCode": {
"description": "The short code in the post link",
"type": "string"
},
"status": {
"description": "success when a transcript was produced (an empty one counts when the video has no speech). Otherwise the reason no transcript was produced: post_age_restricted, post_is_private, post_not_found, blocked, error, invalid_url, not_a_video, no_video_file, no_transcript, charge_limit_reached, no_posts, cookies_unusable, profile_not_found, profile_is_private, profile_age_restricted or profile_restricted. The log explains each one",
"type": "string"
},
"thumbnailUrl": {
"description": "Link to the cover image",
"type": "string"
},
"transcriptionMethod": {
"description": "native (Instagram captions) or whisper (AI speech-to-text)",
"type": "string"
},
"userFullName": {
"description": "Display name of the creator",
"type": "string"
},
"userId": {
"description": "Numeric id of the creator",
"type": "string"
},
"userName": {
"description": "Username of the creator",
"type": "string"
},
"videoIndex": {
"description": "Which video of the post this record is, counting only its videos (1 for a reel or a single video; a carousel with several videos has one record each)",
"type": "integer"
},
"videoUrl": {
"description": "Link to the video file",
"type": "string"
}
},
"type": "object"
},
"title": "Instagram Transcripts",
"views": {
"overview": {
"description": "One row per Instagram video with its transcript and nested segments; a video that could not be transcribed has only its link and a status",
"display": {
"component": "table",
"properties": {
"columns": [
{
"field": "status",
"format": "text",
"label": "Status"
},
{
"field": "userName",
"format": "text",
"label": "Username"
},
{
"field": "pubDate",
"format": "text",
"label": "Posted At"
},
{
"field": "transcriptionMethod",
"format": "text",
"label": "Method"
},
{
"field": "fullText",
"format": "text",
"label": "Full Transcript"
},
{
"field": "likeCount",
"format": "number",
"label": "Likes"
},
{
"field": "commentCount",
"format": "number",
"label": "Comments"
}
]
}
},
"title": "Instagram Transcripts Overview",
"transformation": {
"fields": [
"status",
"postUrl",
"shortCode",
"videoIndex",
"userName",
"userFullName",
"pubDate",
"likeCount",
"commentCount",
"fullText",
"transcriptionMethod",
"segments",
"createdAt"
]
}
}
}
}
Key-value schema
Published key-value store definitions, when provided by this build.
This definition is not present in the default published build. See the published README for available documentation.
Published README
Read the full published documentation
Instagram Transcript Scraper - Reels & Video
Turn the spoken words of Instagram Reels and videos into clean, searchable text. Paste a list of /reel/, /p/ or /tv/ links and get one record per video: the full transcript, the creator, the caption, like and comment counts, and optionally a phrase-by-phrase breakdown with start and end times. You choose whether to rely on Instagram's own captions, on AI speech-to-text (Whisper), or on both. It is built for content teams, researchers, journalists and anyone who needs to read, quote or analyse what is said in short-form video instead of watching it.
What this actor does
- Three transcription methods: Instagram's own captions, AI speech-to-text (Whisper), or
auto, which tries captions first and falls back to Whisper. - Timestamped segments: optionally add a list of phrases, each with start and end time in seconds, for subtitles and quoting.
- Language control: automatic language detection, or pick one of 29 languages for the AI transcription.
- Batch input: transcribe many reels, posts and IGTV videos in a single run, with every record carrying its own status.
- Whole profiles: give usernames or profile links and the actor transcribes the videos among each profile's newest posts. Public profiles need no sign-in, however many posts you ask for.
- Empty fields are omitted: values Instagram does not provide are left out of the record rather than returned as
null.
Output per video
Every successfully processed video produces one record with these fields. A post with several videos (a carousel that mixes photos and videos) gets one record for each video, told apart by videoIndex; the photos in it are ignored.
status—successfor a transcribed video (see the status table below for the failures)postUrl— canonical Instagram URL of the videoshortCode— the short code in the URL that identifies the postvideoIndex— which video of the post this record is, counting only its videos (1for a reel or a single video)pk— Instagram's numeric media IDid— Instagram's combined media IDuserId— numeric ID of the creatoruserName— creator's Instagram handleuserFullName— creator's display nameavatarUri— link to the creator's profile picturepostDescription— the caption written by the creatorpubDate— when the video was posted, ISO 8601 UTC (for example2025-05-10T14:32:03Z)likeCount— number of likes at the time of the runcommentCount— number of comments at the time of the runthumbnailUrl— link to the video's cover imagevideoUrl— link to the highest-quality MP4audioUrl— link to the audio track (only when Instagram exposes one)fullText— the complete transcript as one stringtranscriptionMethod—native(Instagram captions) orwhisper(AI speech-to-text), showing how the transcript was producedsegments— only whenincludeSegmentsis on and phrases are available; a list of objects withindex(starting at 0),startandend(seconds) andtextcreatedAt— when this record was created, ISO 8601 UTC
A video that could not be transcribed gets a short record with only postUrl and a status that names the cause. The explanation, which video it was and what you can do about it, is in the run log, one line per video, followed by a closing Done: summary:
status |
Meaning |
|---|---|
success |
A transcript was produced (an empty one when the video has no speech) |
post_age_restricted |
The video sits behind an age check; it opens only with cookies of an account that may view it |
post_is_private |
The video is in a private account; it opens only with cookies of an account that follows it |
post_not_found |
The post was deleted, never existed, or is visible only to signed-in users |
profile_not_found |
The profile does not exist, or was deleted or suspended |
profile_is_private |
The profile is private; it opens only with cookies of an account that follows it |
profile_age_restricted |
The profile sits behind an age check ("You must be 18 years old or over"); it opens only with cookies of an account that is old enough |
profile_restricted |
Instagram hides the profile from visitors who are not signed in ("unavailable for certain audiences"); it may open with cookies |
blocked |
Instagram kept refusing the request after several tries; run it again later |
error |
Something unexpected went wrong; the log has the details |
invalid_url |
The entry is not an Instagram post link |
not_a_video |
The post is a photo or a photo-only carousel. A post found through a username gets this record too |
no_video_file |
Instagram gave no video file for the post |
no_transcript |
No captions exist and speech-to-text found nothing to transcribe |
charge_limit_reached |
The run stopped at the limit you set |
no_posts |
A profile you listed in usernames has no posts |
cookies_unusable |
A private profile needed your cookies and Instagram did not accept them or could not be reached to check them |
A profile that gives no posts is reported with the profile link as profileUrl (and no postUrl). While the run is going, the status message of the run shows a live count such as Transcribed 12/20 videos - 2 need a sign-in.
A video that has no speech or no audio track is not treated as a failure: you get a normal record with an empty fullText.
Input
| Field | Type | Default | Description |
|---|---|---|---|
videoUrls |
array | – | Instagram video or reel links to transcribe. Supports /p/, /reel/ and /tv/ formats. Provide this, usernames, or both |
usernames |
array | – | Instagram usernames whose newest posts should be checked for videos (up to 100). Each entry can be a username, @username or a profile link such as https://www.instagram.com/natgeo/ |
maxPosts_per_username |
integer | 10 |
How many of each username's newest posts to check. Range 0–100; 0 reads nothing from usernames. Posts left out by the two filters below do not count. Every video among them is transcribed; a post without a video gets a not_a_video record. Public profiles need no sign-in; a private profile needs your cookies |
newerThan |
string | – | Optional date (YYYY-MM-DD). Posts of a username published before it are skipped. Empty means no date filter. It must be from 2000-01-01 up to the day before the run, otherwise it is ignored with a warning in the log. Does not apply to links you give. The date is read from the post's id, so it can be off by up to a day |
skipPinnedPosts |
boolean | false |
Leave out the posts a profile has pinned to the top of its grid. Does not apply to links you give. Instagram does not mark pinned posts for a visitor who is not signed in, so they are recognised by their place and date; a pinned post that is also the profile's newest post cannot be told apart and stays in |
transcriptionMethod |
string | auto |
auto (captions first, then Whisper), native (Instagram captions only) or whisper (AI speech-to-text only) |
whisperModel |
string | base |
Whisper model size: tiny, base or small. Only used when Whisper is involved |
language |
string | empty (auto-detect) | Language of the spoken audio: en, es, fr, de, it, pt, ru, zh, ja, ko, ar, hi, nl, pl, tr, sv, da, fi, no, cs, ro, hu, id, vi, th, uk, he, fa, ms. Only used when Whisper is active |
includeSegments |
boolean | false |
Add a segments list with per-phrase start and end times to each result |
cookies |
string | – | Optional. Your own Instagram cookies as JSON, used for age-restricted videos and videos from private accounts your account follows. See Authentication below |
Example: transcribe a single reel
{
"videoUrls": ["https://www.instagram.com/reel/DV29mBcMQwp/"],
"transcriptionMethod": "auto",
"whisperModel": "base"
}
Example: transcribe the latest videos of two profiles
{
"usernames": ["natgeo", "https://www.instagram.com/nasa/"],
"maxPosts_per_username": 6
}
Each profile's 6 newest posts are checked, and every video or Reel among them is transcribed. Posts without a video get a not_a_video record. Keep the number small until you know what a profile posts.
Example: timestamped transcripts for subtitles
{
"videoUrls": [
"https://www.instagram.com/reel/DV29mBcMQwp/",
"https://www.instagram.com/p/DULBkEngpxg/"
],
"transcriptionMethod": "auto",
"includeSegments": true
}
Example: Instagram captions only, using your own cookies
{
"videoUrls": ["https://www.instagram.com/reel/DV29mBcMQwp/"],
"transcriptionMethod": "native",
"cookies": "<your cookies JSON>"
}
Example output
{
"status": "success",
"postUrl": "https://www.instagram.com/p/DV29mBcMQwp/",
"shortCode": "DV29mBcMQwp",
"pk": "3852537424986049577",
"id": "3852537424986049577_16278726",
"postDescription": "Three quick tips for a calmer morning routine...",
"thumbnailUrl": "https://scontent-iad6-1.cdninstagram.com/v/thumbnail.jpg",
"videoUrl": "https://scontent-iad6-1.cdninstagram.com/v/video.mp4",
"pubDate": "2025-05-11T05:12:03Z",
"likeCount": 16799,
"commentCount": 1159,
"userId": "16278726",
"userName": "sample_wellness",
"userFullName": "Sample Wellness",
"avatarUri": "https://scontent-iad3-1.cdninstagram.com/v/avatar.jpg",
"fullText": "Here are three quick tips for a calmer morning routine. First, ...",
"transcriptionMethod": "whisper",
"createdAt": "2026-06-08T06:09:05.841Z"
}
Transcription methods
Auto (recommended)
Tries Instagram's own captions first and falls back to Whisper when no captions exist. A good balance of speed and coverage for most jobs.
Native captions only
Reads the captions Instagram generated for the video. This is the quickest option and needs no speech recognition, but captions may be missing on older posts, non-Reel content, or videos without speech. If none exist, the record comes back with the status no_transcript instead of a transcript.
Whisper AI
Always runs AI speech-to-text (Whisper) on the video's audio, so any video with speech can be covered regardless of whether Instagram produced captions. Whisper transcripts (transcriptionMethod: "whisper") are machine-generated and may contain errors.
| Model | Size | Best for |
|---|---|---|
tiny |
~39 MB | Fastest results, quick previews |
base |
~74 MB | Balanced speed and accuracy, most uses |
small |
~244 MB | Most accurate: accented speech, technical or specialised vocabulary |
Authentication
Public videos need no sign-in. Instagram does not show every video to logged-out visitors, so some posts (age-restricted ones, or videos from private accounts) need a signed-in session, and only your own cookies can give one. Export your instagram.com cookies as JSON from a logged-in browser session using any cookie-export browser extension, then paste the JSON into the optional cookies field. The field is a secret input, so the Apify Console hides and encrypts it. Before a video is retried with them, the actor asks Instagram whether it recognises the cookies; if they are invalid, expired or signed out, the run log says so. Without cookies, those videos get their status (age_restricted or is_private) and no transcript, and the log says why. The actor does not sign in with any account of its own.
For usernames the same applies: a public profile is always read without signing in, with or without cookies in the input, and any number of its posts can be listed. Only a private profile is read with your cookies, and it opens only if your account follows it. Without cookies a private profile is reported with the status profile_is_private.
If your own cookies expire during a run, export them again from your browser and restart the run.
Cookie format
The cookies field takes a JSON array of cookie objects, the format most cookie-export browser extensions call "JSON". Other export formats are not supported: a Netscape cookies.txt file or a raw Cookie: header string will be rejected. Each cookie needs at least name, value and domain, and the export must include the sessionid and ds_user_id cookies of the signed-in account. A cookie that has an expiry date (expirationDate, in seconds since 1970) must not be expired.
One cookie looks like this (the value shown is a placeholder, paste your own export unchanged):
[
{
"name": "sessionid",
"value": "<your sessionid value>",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": null,
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
}
]
<details> <summary>Show a complete example export (placeholder values)</summary>
[
{
"name": "ps_n",
"value": "1",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": "no_restriction",
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "datr",
"value": "EXAMPLE-datr-value",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": "no_restriction",
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "ig_nrcb",
"value": "1",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": false,
"sameSite": null,
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "ds_user_id",
"value": "1234567890",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": false,
"sameSite": "no_restriction",
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "csrftoken",
"value": "EXAMPLE-csrftoken-value",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": false,
"sameSite": null,
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "ig_did",
"value": "00000000-0000-0000-0000-000000000000",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": "no_restriction",
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "ps_l",
"value": "1",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": "lax",
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "wd",
"value": "1280x720",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": false,
"sameSite": "lax",
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "mid",
"value": "EXAMPLE-mid-value",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": "no_restriction",
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "sessionid",
"value": "<your sessionid value>",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": null,
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "dpr",
"value": "1",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": false,
"sameSite": "no_restriction",
"session": false,
"firstPartyDomain": "",
"partitionKey": null,
"expirationDate": 1893456000,
"storeId": null
},
{
"name": "rur",
"value": "EXAMPLE-rur-value",
"domain": ".instagram.com",
"hostOnly": false,
"path": "/",
"secure": true,
"httpOnly": true,
"sameSite": "lax",
"session": true,
"firstPartyDomain": "",
"partitionKey": null,
"storeId": null
}
]
</details>
Treat the cookies like a password: they give access to your Instagram account, so never share them or post them publicly.
Things to know
- Media links expire.
videoUrl,audioUrl,thumbnailUrlandavatarUriare time-limited Instagram links that stop working after hours or days. Download anything you want to keep soon after the run, and do not treat them as permanent addresses. - Private accounts. A video from a private account can only be transcribed if the session used belongs to an account allowed to view it. Otherwise the record has the status
post_is_private. - Audio quality matters. Whisper is less accurate with loud background music, several people talking at once, or very poor recordings.
- Captions are not guaranteed. Instagram does not generate captions for every video; in
automode those videos fall through to Whisper. - Videos in carousels. Every video of a carousel is transcribed on its own, with its own record. Instagram's own captions exist only for reels and video posts, so videos inside a carousel are always transcribed with speech-to-text.
- Posts without video. A photo or a photo-only carousel, whether you linked it or it was found through a username, returns a record with the status
not_a_video. - Media rights. Videos belong to their creators. The transcript is derived from their speech, so make sure you have the rights or permission before republishing it.
Use cases
- Podcast and video repurposing — turn reels into blog posts, newsletters and quote cards without retyping them.
- Journalists and fact-checkers — search what public figures and news accounts said in short clips and cite it accurately.
- Social media managers — build subtitle files from timestamped segments for reposting in other formats.
- Market and trend researchers — analyse spoken themes, product mentions and slang across a hashtag or niche of reels.
- Language learners and teachers — collect transcripts of native-speaker clips in dozens of languages for study material.
- Accessibility teams — provide text versions of video content for people who cannot listen to it.
Responsible use
Instagram videos are public, but a transcript captures what identifiable people said, in their own voices and words, and that is personal data. Make sure you have a lawful basis (for example under the GDPR) for transcribing and storing it, keep transcripts only as long as you need them, and respect the people who appear in or speak in the videos. Do not use transcripts to profile, track or target minors, and do not extract or infer special categories of personal data from what speakers say, such as health, religion, political opinions or sexual orientation.
FAQ
Do I need an Instagram account?
No, not for public videos. Only age-restricted videos and videos from private accounts need cookies of an account that can view them, which you paste into the optional cookies field.
Do I need to set up a proxy?
No. The actor handles its connection to Instagram automatically. Just add your video links and run it.
Which transcription method should I pick?
Start with auto. Choose native when you only want Instagram's own captions and do not need a transcript for videos that lack them. Choose whisper when you want consistent AI transcription for every video, or when you need to set the spoken language.
Which languages are supported?
You can pick from 29 languages (English, Spanish, French, German, Italian, Portuguese, Russian, Chinese, Japanese, Korean, Arabic, Hindi and more) or leave the field empty to detect the language automatically. The language setting applies to Whisper transcription only.
What happens if a video has no speech or only music?
The record is still returned with an empty fullText. A silent video is not a failure and gets the status success.
How accurate are the transcripts?
Whisper transcripts are machine-generated and can contain mistakes, especially with accents, fast speech, background music or specialised terms. The small model is the most accurate, and setting language explicitly helps with non-English videos. Always review important quotes before publishing.
Can I get timestamps for each phrase?
Yes. Turn on includeSegments and each record gets a segments list with the start and end time of every phrase, in seconds.
Can I transcribe many videos at once?
Yes. Add as many links as you need to videoUrls, or give usernames to transcribe the videos on whole profiles. They are processed one after another, and each gets its own record. Very large batches are subject to your plan limits.
Are the video and audio links in the output permanent?
No. They are signed Instagram links that expire within hours or days. Download the media soon after the run if you need to keep it.
Is this affiliated with Instagram or Meta?
No. This is an independent tool and is not affiliated with, endorsed by or sponsored by Instagram or Meta Platforms.
Python quickstart
Use a schema-derived input and the Python standard library to start a run. An Apify account and token are required for execution.
Source build WNBBQsnWIcfNIJafZ. Documentation is regenerated from the default published build; private drafts are not included.