I’m Ilias Ism. I build products, and every time I try to post about them on Instagram, I freeze on the first line.
So I stopped guessing. I scraped a creator’s top Reels, saved the transcripts, and built a hook bank I can open in Cursor and actually learn from.
I’m actually using this on my own Instagram, @illyism, starting from zero posts.
In this guide, you’ll learn:
- Why Instagram Reel outlier scanning works
- The Instagram Reel hook workflow
- How to scrape Instagram Reels and transcripts
- How to write Instagram Reel hooks in Cursor
Read on for the step-by-step workflow.
Instagram Reel Outlier Scanning
Most hook advice online is vague. Be curious. Pattern interrupt. Open with a question.
Cool, but that doesn’t tell me what actually stops the scroll for a specific audience. It’s just a vibe.
Here’s what I actually want: outlier scanning. Every creator has an average. Most Reels land somewhere near it. Then every once in a while, one Reel goes 20x, 50x, sometimes 100x their normal number. That gap is not luck. Something in the first three seconds made way more people stop.
If I pull a creator’s whole catalog and sort by plays, the outliers rise straight to the top. I can read the hook, read the mechanism behind it, and steal the pattern (not the words) for my own topic.
That’s the whole point of this. Not “here are 10 hook templates,” but a repeatable way to find what’s actually working for real accounts, right now, so I have creative fuel instead of a blank cursor.
The Instagram Reel Hook Workflow
- Pick one public creator who is good at opening.
- Download their top Reels as transcripts, ranked by plays.
- Extract the first lines into a hook bank.
- Feed the corpus, plus a tight write-reel prompt, into Cursor.
I open-sourced the scraper for steps 1 to 3. The prompt is step 4.
Step 1: Pick an Instagram Creator
I wanted openings that feel like a polished voice note. Personal, specific, slightly imperfect. Not a coach listing eight tips mid-video, not “here’s the secret nobody tells you.”
I used yoniman.mp4, because his hooks are casual and oddly specific. “Today we’re building Fortnite 2 in 60 seconds.” “Two days ago my rent increased from $2,800 a month to $4,900 a month.” No fluff, no “wait for it,” just a fact that makes you want to know more.

One creator is enough for a first pass. Ten creators at once is how you drown in notes and never write anything.
Step 2: Scrape Instagram Reels and Transcripts
Three public endpoints from Scrape Creators get you everything: user id, then reels, then transcript.

| Job | Endpoint |
|---|---|
| Profile + user id | Instagram Profile |
| Paginated Reels | User Reels |
| Speech-to-text | Media Transcript |
Auth is one header, x-api-key. Base URL is https://api.scrapecreators.com. No login, no cookies, no browser automation on your machine.
First, the profile. You mainly want the numeric user id, since it makes the Reels call faster than passing a handle every time:
const handle = "yoniman.mp4";
const res = await fetch(
`https://api.scrapecreators.com/v1/instagram/profile?handle=${handle}&trim=true`,
{
headers: {
"x-api-key": process.env.SCRAPE_CREATORS_API_KEY,
},
},
);
const { data } = await res.json();
const userId = data.user.id;
Then the Reels list. Use user_id when you have it, it’s faster. One important gotcha: don’t use trim=true on this call if you plan to paginate. The trimmed response drops paging_info.more_available, so your loop thinks there’s nothing left and stops after page one. I lost twenty minutes to that on my first run:
const url = new URL("https://api.scrapecreators.com/v1/instagram/user/reels");
url.searchParams.set("user_id", userId);
// url.searchParams.set("max_id", page.paging_info.max_id); // next page
const page = await fetch(url, {
headers: { "x-api-key": process.env.SCRAPE_CREATORS_API_KEY },
}).then((r) => r.json());
const reels = page.items.map((item) => ({
shortcode: item.media.code,
plays: item.media.play_count ?? item.media.ig_play_count ?? 0,
url: item.media.url || `https://www.instagram.com/reel/${item.media.code}/`,
}));
Keep paginating with max_id until more_available is false, then sort everything by plays. That sorted list is your outlier scan, done in code instead of by scrolling for an hour.
Last, the transcript for each Reel you actually want to read:
const reelUrl = "https://www.instagram.com/reel/SHORTCODE/";
const data = await fetch(
`https://api.scrapecreators.com/v2/instagram/media/transcript?url=${encodeURIComponent(reelUrl)}`,
{
headers: { "x-api-key": process.env.SCRAPE_CREATORS_API_KEY },
},
).then((r) => r.json());
const text = data.transcripts?.map((t) => t.text).filter(Boolean).join("\n\n");
const hook = text?.match(/^(.{1,140}?[.!?])(?:\s|$)/)?.[1] || text?.slice(0, 120);
Give it 10 to 30 seconds per call, it’s running real speech-to-text, not reading a caption. Over 120 seconds, you get a 400 with Video is too long for AI transcription. No speech in the clip, you get empty text. Both are completely normal, not bugs.
If you want the full API map for every platform Scrape Creators supports, the llms.txt file is built for pasting straight into an LLM or a coding agent.
Step 3: Build an Instagram Hook Bank
Sort everything by play count. Keep the top 25 to 50. For each transcript, store the shortcode, the play count, the hook (first spoken line), and the full text.
When I ran this on Yoniman, the top of the bank looked like this:
| Plays | Hook | Reel |
| ---: | --- | --- |
| 6986122 | It's my impression of a 27-year-old that doesn't know what they're doing with their life. | [DO-CHKyEdYk](https://www.instagram.com/reel/DO-CHKyEdYk/) |
| 2653632 | Today we're building Fortnite 2 in 60 seconds. | [DHKrvF_OB05](https://www.instagram.com/reel/DHKrvF_OB05/) |
| 306761 | Two days ago, my rent increased from $2,800 a month to $4,900 a month. | [DLtOyEBPve7](https://www.instagram.com/reel/DLtOyEBPve7/) |
Notice the pattern already, just from three rows. A confession about being a mess. A silly, specific challenge (“build X in 60 seconds”). A blunt personal number. None of them are clever wordplay. They’re just concrete.
I also save one giant all-transcripts.md with every full transcript in it. That single file is what I actually drop into Cursor, because the LLM needs the whole script, not just the first line, to understand what made the hook land.

Step 4: Write Instagram Reel Hooks in Cursor
Open the scraper folder in Cursor. @ mention all-transcripts.md or hooks.md in a chat.
First pass: extract mechanisms only, no copying lines. I run prompts/extract-hooks.md against the corpus and get back a table with mechanism, proof type, and close style for each of the top Reels. That’s the actual research step. It turns “this Reel did well” into “this Reel worked because it’s a confession plus a specific number.”

Second pass: write my own Reel, with my own proof, using prompts/write-reel.md.
Voice I’m going for: personal, honest, slightly imperfect, like a polished voice note. Not creator-coach, not Hormozi.
Structure that holds for 45 to 75 seconds:
- Hook (first line, first 3 seconds)
- One proof (a number, a story, a screen, a real example)
- One lesson
- A soft close (day N, time capsule, “more of this”)
Things I explicitly ban in the prompt:
- listing eight content ideas mid-video
- fake CTAs like “comment DAY ONE”
- anything that reads like a LinkedIn thought leadership post
The Instagram Reel Hook Prompt
Write a 45–75s Instagram Reel from this hook.
Voice: personal, honest, slightly imperfect, like a polished voice note. Not creator-coach. Not Hormozi hype.
Structure:
1. Hook (first line / first 3 seconds)
2. One proof (number, story, screen, or real example)
3. One lesson
4. Soft close (Day N / time capsule / "more of this")
Do NOT:
- list 8 content ideas mid-video
- add fake CTAs like "comment DAY ONE"
- sound like LinkedIn thought leadership
Hook: [PASTE]
Topic angle: [1 sentence]
Proof I can use: [number / site / story]
Fill the three brackets with something real. A weak proof makes a weak Reel, no matter how good the hook is.
Example Instagram Reel Script From a Hook
Here’s an actual run. I gave it the hook “Today we’re building Instagram Reel Scraper in 60 seconds,” borrowing Yoniman’s “build X in 60 seconds” mechanism but pointed at this exact project, plus the topic angle and proof:

It comes back with the hook, the topic angle, the proof, and then a shot-by-shot script: what’s on screen, what I’m saying, in order, ending on a soft close instead of a fake CTA. That’s the loop working end to end. Real hook mechanism in, real product context in, an actual usable script out. Not “10 hook ideas for your niche,” one specific script I could film today.
Clone the Instagram Reel Scraper
I packaged the pipeline so nobody has to glue these three endpoints together by hand:
👉 github.com/Illyism/instagram-scraper
git clone https://github.com/Illyism/instagram-scraper.git
cd instagram-scraper
cp .env.example .env # paste SCRAPE_CREATORS_API_KEY
# get a key: https://app.scrapecreators.com
npm run scrape -- yoniman.mp4 --top 50 --pages 20
You get in output/<handle>/:
hooks.md, first-line table ranked by playsall-transcripts.md, pasteable corpus for Cursortranscripts/*.md, one file per Reelindex.jsonandprofile.json
Plus prompts/write-reel.md, prompts/extract-hooks.md, and a Cursor rule under .cursor/rules/.
But don’t stop at Instagram. Scrape Creators has the exact same shape of API for TikTok, YouTube, Twitter, LinkedIn, Facebook, Threads, and a dozen more platforms. Same auth header, same JSON style. Once you understand this scraper, you can clone it, swap the three endpoints for TikTok’s video transcript or YouTube’s transcript API, and build the exact same outlier scanner for a different platform. The full endpoint list is long, and most of it is just sitting there waiting for someone to build on top of it.
👉 Get a free Scrape Creators API key
👉 Instagram transcript docs
👉 Clone instagram-scraper

