Instagram Reels Keyword Search Scraper — Reels Search to Text
Pricing
from $0.60 / 1,000 reels
Instagram Reels Keyword Search Scraper — Reels Search to Text
Instagram reels keyword search: type a keyword and get the matching reels with captions, engagement, media links and owner — plus the spoken words of each reel as a transcript, on request. No login. From $0.60 per 1,000 reels, transcripts $0.006 each. An undelivered reel is never charged.
Pricing
from $0.60 / 1,000 reels
Rating
0.0
(0)
Developer
Steadyfetch Team
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
a day ago
Last modified
Categories
Share
Type the phrases you want and get the reels Instagram ranks top for each: caption, hashtags, mentions, engagement, media links, owner and the permalink — and, on request, the spoken words of every reel as a timestamped transcript. No login, no cookies, no proxy to configure. Your result limit is exact — set 30 and you get 30, and a reel we could not deliver is never charged. A transcript is charged only when it was actually produced. Nothing is charged for starting a run.
Using an AI agent? Pin this actor in Apify's MCP server with one link: https://mcp.apify.com?tools=steadyfetch/instagram-keyword-reels-scraper
- Actor id:
steadyfetch/instagram-keyword-reels-scraper - Input:
{ "keywords": ["sourdough bread"], "includeTranscripts": true, "resultsLimit": 30 }—"keywords"is the one field you have to set;"includeTranscripts"adds the spoken words. - Cap the bill: set
maxTotalChargeUsdon the run (a run option, not Actor input), e.g.0.50— the run stops when it reaches it, and the last row says what it did not deliver. - Price: from $0.60 per 1,000 reels on Gold and above, $2.40 per 1,000 on the Apify free plan; a transcript is a flat $0.006, and only when one was actually produced. No start fee, and a reel we could not deliver is never charged. Full table below.
- How often it changes: Instagram re-ranks a keyword continuously, so the same phrase tomorrow is mostly reels you have not seen — and the ones you already have are skipped rather than charged again, so a daily schedule pays only for what is new.
Unofficial. Not affiliated with, endorsed by, or sponsored by Instagram or Meta Platforms, Inc.
What you get
One row per reel, with everything the reel exposes at one price — there is no second charge for "details":
| Column | What it holds |
|---|---|
shortCode · url | the reel's own code and its permalink |
caption · hashtags · mentions | the caption, and the tags and @handles pulled out of it |
takenAt | when it was posted, ISO-8601 UTC |
productType · isVideo · hasAudio | it is a reel (clips), and whether the video carries an audio track |
likeCount · commentCount · playCount · videoDuration | engagement, and the length of the reel |
ownerUsername · ownerFullName · ownerId · ownerIsVerified | who posted it |
displayUrl · videoUrl · videoUrlExpiresAt | the media links, and when the signed link stops working |
transcript · transcriptLanguage · transcriptSegments | the spoken words, the language detected, and the timestamped segments |
transcriptStatus · transcriptReason · transcriptCharged | whether a transcript was produced, why not when it was not, and whether it billed |
keyword · input · source | which of your phrases found it (source is always instagram) |
charged · chargedEvents · status · statusReason | whether this row was billed and for which events, so your invoice reconciles from the dataset itself |
Media links are signed and time-limited by Instagram: videoUrlExpiresAt tells you exactly how long each one stays fetchable, so download what you need in the same session. The requesting network address is stripped out of every link before it reaches your dataset.
What a row looks like
One delivered row from a real run — the phrase latte art, 2026-09-12. This row charges one reel; the transcript is a second event and this run did not ask for one, so transcriptCharged is false. Media links are signed and time-limited, so they are shown here as placeholders.
{"postId": "3975943623665444663","shortCode": "DctY6kHjuc3","url": "https://www.instagram.com/p/DctY6kHjuc3/","type": "video","productType": "clips","caption": "#learnbarista #barista #LearnWithBBTA #CareerGrowth #baristaacademy #baristacourse #baristaskill #professionalbaristacourse #coffeepassion #baristatrainingdhaka #latteart #BaristaLife","hashtags": ["learnbarista","barista","learnwithbbta","careergrowth","baristaacademy","baristacourse","baristaskill","professionalbaristacourse","coffeepassion","baristatrainingdhaka","latteart","baristalife"],"mentions": [],"takenAt": "2026-08-31T15:17:49.000Z","takenAtTimestamp": 1788189469,"likeCount": 44379,"commentCount": 50,"playCount": 2947422,"videoDuration": 21.799999237060547,"displayUrl": "https://…","videoUrl": "https://…","videoUrlExpiresAt": "2026-09-14T07:11:13.000Z","carouselCount": null,"dimensionsWidth": 1080,"dimensionsHeight": 1920,"ownerId": null,"ownerUsername": "bbta.bd","ownerFullName": "Bangladesh Barista Training Academy-BBTA","ownerIsVerified": false,"taggedUsers": [],"coauthors": [],"locationName": null,"locationId": null,"isPinned": false,"isSponsored": false,"postSource": "keyword-search","profileHandle": null,"profileFullName": null,"profileFollowers": null,"profileIsVerified": null,"profilePostCount": null,"source": "instagram","keyword": "latte art","isVideo": true,"hasAudio": true,"transcript": null,"transcriptLanguage": null,"transcriptDurationSeconds": null,"transcriptSegments": null,"transcriptStatus": "not_requested","transcriptRetryable": false,"transcriptReason": "Transcripts were not requested on this run — switch on \"Include transcripts\" to add the spoken words.","transcriptCharged": false,"input": "latte art","sourceIndex": 0,"scrapedAt": "2026-09-12T20:43:40.500Z","repeat": false,"charged": true,"chargedEvents": {"reel":1,"reel-transcript":0},"status": "delivered","retryable": false,"statusReason": null,"#k": "3975943623665444663","#ce": {"reel":1},"#ask": {"delivered":1}}
Price
Two charged events, and each lands only on work that was actually delivered.
reel — one per delivered reel row, tiered by your Apify plan:
| Apify plan | Per reel | Per 1,000 reels |
|---|---|---|
| Free plan | $0.0024 | $2.40 |
| Bronze | $0.0014 | $1.40 |
| Silver | $0.0009 | $0.90 |
| Gold and above | $0.0006 | $0.60 per 1,000 reels |
reel-transcript — $0.006 per reel whose spoken words were actually produced, the same on every plan. It is off by default; switch on Include transcripts to get it. A reel with no speech, no audio track, an expired media link, or longer than the 180-second transcript ceiling is still delivered as a reel row with an explicit null transcript and a reason — and no transcript charge.
Platform usage is included in both prices — there is no separate compute bill on top, and no start fee. Set maxTotalChargeUsd on the run and it is a hard ceiling: with transcripts on, a reel and its transcript are reserved together, so the run stops cleanly under your maximum rather than half-billing a unit.
Honest rows: what "not charged" actually means
Every run closes its own books. A reel that was not delivered leaves an uncharged row saying which of seven things happened, and none of them is billed:
no_reels— the ask was not filled, and the row says WHICH of three endings closed the search: Instagram had nothing more to give, or this actor stopped at its own ceiling on how deep one search is read, or its own backstop closed a search whose later pages only re-served reels you already have. Instagram's reel search re-ranks rather than paging cleanly, so the last two are bounds of ours over a feed still serving — the row names them as ours and says what you can change, rather than calling a full shelf an empty one.stopped_at_limit— one of your own limits, your maximum total charge, or the run clock stopped it first. The row names which.vendor_unavailable— the read did not go through. Temporary, says nothing about your phrase, and a re-run is the fix. If the search had already delivered reels when it stopped answering, the row opens with how many you were handed and charged for, and asks for the re-run only on the rest.source_refused— Instagram would not run that phrase as a search at all. The refusal is the same every time, so the row says plainly that re-running cannot change it, and there was no result fee.unsupported_shape— Instagram answered in a shape this actor does not read yet. That is on us, not on your phrase; the answer is the same every time, so the row asks you to tell us the phrase rather than asking you to re-run. No result fee.vendor_budget— this actor reached its own monthly collection allowance and stopped rather than collecting more.user_input— a value that is not a search phrase (a profile link, a reel link, several phrases pasted into one line). The row names the mistake and, where another actor of ours takes that value, names that actor too.
On a delivered reel, transcriptStatus carries the same honesty for the transcript leg: no_speech, no_audio_stream, expired, transcript_too_long, failed_download, asr_failed, asr_unavailable. Each is an explicit null transcript with a reason on the row, and none of them is charged.
The last row of every run is a receipt: delivered, asked for, transcripts produced, what was skipped, what stopped it, and the charged-event totals for both events.
How often this data changes
Instagram's keyword search re-ranks continuously: the same phrase asked twice an hour apart returns an overlapping but different slice, and popular phrases take new reels every few minutes. Re-running the same phrase therefore buys mostly new reels — but it would also re-buy the ones you already have, so it does not. Every run remembers what it delivered to your account, in the key-value store ig-keyword-reels-account in your own Apify account, and a later run skips those: not delivered again, not charged, and the slot goes to the next new reel instead, so you still get the number you asked for. The memory is a key-value store in your own Apify account, so a run started with a scoped API token in restricted-access mode needs key-value store Read, Write and Create permission (Write is what lets the run remember what it delivered; without it every run pays again) or Actor runs set to Full access; without it the run says so on its status line and on an uncharged row, and cannot skip the reels you already have. That makes a daily schedule cost only what is new, and — as long as the token the schedule runs on can open that store — it never re-transcribes a reel you already paid a transcript for. Switch Include reels you already have on to get them back anyway, marked repeat: true and still uncharged, and use Skip reels in this dataset to carry the same memory across accounts.
Reliability
The reels come from a licensed data feed rather than from scraping Instagram's own web pages, which is why there is nothing to log into and nothing to configure. When that feed cannot answer, the run says so on an uncharged row and finishes successfully — a failed read is never billed and never dressed up as an empty search. The transcripts are produced by a speech-recognition service from the reel's own audio; when it cannot answer, the reel is still delivered and only the transcript is left null.
Related actors
- One reel you already have the link to, transcribed: Instagram Reel Transcript Scraper — https://apify.com/steadyfetch/instagram-reel-transcript-scraper
- Posts and reels under a hashtag: Instagram Hashtag Scraper — https://apify.com/steadyfetch/instagram-hashtag-scraper
- One account's own posts: Instagram Profile Posts Scraper — https://apify.com/steadyfetch/instagram-profile-posts
Limits and good manners
Max reels and Max run seconds take any number you type: this actor delivers at most 2,000 reels in one run and runs for at most an hour (and for at least 30 seconds), so a bigger ask runs at the ceiling instead of being refused, and one uncharged row says what was asked for and what was used.
Only public reels are returned. Instagram's keyword search serves a ranked slice rather than a complete archive — you can see the same surface yourself at https://www.instagram.com/explore/search/keyword/ — so a very deep ask on one phrase runs out around 60-100 distinct reels and the run says so instead of padding. Transcripts are capped at reels of 180 seconds or less. This actor may stop working if Instagram changes how the data is served; if it does, failed items are never charged.
Support
Something off, or a column you need that is not here? Open an issue on the Issues tab — we usually reply within a couple of hours.
If it earned its keep, a rating helps other buyers find it, and saving the actor keeps it one click away.