Give this endpoint a keyword and it returns the Reels Instagram is currently surfacing for that term, as an array of JSON objects with view and like counts attached. Billing is per result returned, at 1 credit each, so a 20-result search costs 20 credits. No login, no Graph API app review, no headless browser to babysit.
| parameter | type | description |
|---|---|---|
| query | string, required | The keyword, hashtag, place, id or URL this endpoint reads. |
| limit | integer | Items per page, up to 50 synchronously. Above that the call becomes a job. |
| cursor | string | meta.next_cursor from the previous page. |
| fresh | boolean | Skip the stored copy and read live, at the same price. |
| fields | string | Comma-separated field paths to keep. |
| format | json, csv | CSV flattens each item to one row. |
1 credit per result. Failed calls are never charged, and empty results are free up to 25 a day. Stored copies are age-aware, 15 minutes to 7 days.
An array. Each element is one Reel: its shortcode, its permalink, the caption, the engagement counters, how long the clip runs, when it went up, a thumbnail URL and the account that posted it. The shape is identical to what the other Instagram post endpoints emit, so a search result and a post pulled from a profile feed can go into the same table without a translation layer.
Ordering comes from Instagram's own popularity ranking for the keyword, not from a date sort and not from anything we compute. That has a practical consequence worth internalising: the same query run tomorrow can return a different set in a different order. This is a discovery tool, not a stable index. If you need to follow specific Reels over time, take the ids out of a search once and then poll those ids directly.
One keyword goes in per call. There is no boolean syntax, no AND/OR, no field qualifiers, no date filter. Instagram's search box is what is underneath, and it takes plain terms.
curl "https://api.instadata.dev/v1/instagram/reels-search?query=home%20workout&limit=10" \ -H "Authorization: Bearer ik_live_..."
{
"data": [
{
"id": "v_77120",
"url": "https://example-result-url",
"caption": "How I plan a week of posts in 30 minutes",
"author": {
"handle": "plannerpro"
},
"metrics": {
"views": 88210,
"likes": 5120
},
"posted_at": "2026-07-08T16:20:00Z"
},
{
"id": "v_771201",
"url": "https://example-result-url",
"caption": "How I plan a week of posts in 30 minutes",
"author": {
"handle": "plannerpro"
},
"metrics": {
"views": 88210,
"likes": 5120
},
"posted_at": "2026-07-08T16:20:00Z"
}
],
"meta": {
"count": 2,
"limit": 20,
"item": "result"
},
"request_id": "req_01JZX4M8Q2TE9W"
} | field | type | note |
|---|---|---|
| id | string | The Reel's shortcode (the segment after /reel/ in the URL). Stable for the life of the post; use it as your primary key. |
| url | string | Permalink to the Reel on instagram.com. |
| type | string|null | Instagram's own media/product type label for the item. Null when the platform does not report one. |
| caption | string|null | Caption text as written, hashtags and line breaks included. Null when the Reel was posted without one. |
| views | number|null | Public play count. Null on items where Instagram is not publishing a view figure. |
| likes | number|null | Public like count. Null when the account has hidden likes on the post. |
| comments | number|null | Count of comments, not the comment text. Pull the text with the Instagram Comments API using this id. |
| shares | null | Always null on Instagram — a literal null, not a number. The key exists so the response shape matches the other post endpoints; Instagram does not expose a public share count. |
| duration_sec | number|null | Clip runtime in seconds. Null when the platform omits it. |
| posted_at | string|null | ISO 8601 UTC publish timestamp. Use it to age-filter results client-side, since the query itself cannot take a date range. |
| author | object | Nested { handle, name } for the posting account. Either key can be null. Follower counts are not here — that is the Instagram Channel Stats API. |
| thumbnail | string|null | URL of the cover frame. Instagram's CDN links expire, so download or re-fetch rather than hotlinking in a UI. |
| hashtags | string[]|null | Hashtags associated with the Reel as bare strings. Null when the platform returns none for the item. |
Billing is 1 credit per item in the array, not 1 per call. A search that returns 20 Reels costs 20 credits, roughly 10 cents on the monthly plan. Set your limit deliberately rather than accepting a default and being surprised by the bill on a crawl of 500 keywords.
Instagram may return fewer items than you ask for on a narrow term. You are only charged for what actually comes back.
Popularity ranking shifts through the day. Two calls with the same keyword an hour apart will overlap heavily but not exactly, and something ranked third in the morning can be absent by evening. Do not build a test that asserts on a specific result position.
If your job needs a fixed set, snapshot the ids once and treat the search as the seed step rather than as the source of truth.
One plain keyword or phrase per call. Operators are not supported and will be treated as literal characters — a search for "yoga AND pilates" looks for that string, not for the intersection. Run separate calls and merge on id if you need boolean logic.
Non-English terms work, and language is inferred from the query rather than settable. Very generic single words tend to return broad, low-relevance results; two or three word phrases are usually better.
Instagram is inconsistent about which counters it publishes on search surfaces. Expect a meaningful share of results with a null views or likes value, and write your ranking code so a null sorts rather than throws. shares is null on every Instagram item without exception.
Searches sit in the fast cache class, so re-running an identical query inside the window returns in milliseconds and sets x-cache: hit. Cached responses are billed the same as fresh ones. Pass fresh=true when you specifically need to bypass the cache, such as the first call of a scheduled trend run.
Send a GET to /v1/instagram/reels-search with a query parameter and your API key. Instagram's Graph API has no public keyword search for Reels at all — it only reaches media on accounts that have authorised your app — which is why keyword discovery generally cannot be built on it. This endpoint reads the same public search results you would see logged out, and returns them as JSON.
1 credit per result returned. Ask for 20 Reels and you spend 20 credits; ask for 5 and you spend 5. Credits are $0.005 each on monthly billing and $0.0045 on annual, so 20 results is about 10 cents. Failed calls are not charged, and a search that returns fewer items than requested only bills for the items you got.
You set the limit on the request. Instagram controls the actual ceiling for any given term and often returns fewer items than asked for on narrow or niche keywords. Because billing is per result, a high limit on a broad term is the expensive case to watch. Start at 10 to 20 while you are calibrating a query.
Because the ordering is Instagram's live popularity ranking, which moves throughout the day as engagement accumulates. The endpoint does not sort or filter — it returns what the platform surfaces at call time. For repeatable work, run the search once, keep the ids, and fetch those specific Reels afterwards instead of re-searching.
Not in the query. The endpoint takes a keyword and nothing else — no date range, no minimum views, no operators. Every result carries posted_at and views, so filter client-side after the call. Be aware that you are billed for results before you filter them, so a tight keyword beats a broad one plus aggressive post-filtering.
No. Only public content that appears in logged-out search is reachable. Private accounts, deleted Reels and region-restricted posts do not appear in results. We do not log in, do not bypass anything, and do not have access to anything you could not open in an incognito window yourself.
Reels search starts from a topic and returns Reels from accounts you have never heard of, ranked by Instagram. Channel posts starts from a handle you already know and returns that account's recent posts in order. Discovery versus monitoring. Most pipelines use search to find accounts, then switch to channel posts to track the ones that matter.