Instagram Content discovery API

Track posts under an Instagram hashtag in keyword, each with media_type, like_count, view_count and the author's follower count. Up to 200 per call, async, $0.56 per 1,000 calls.

Instagram Content discovery lists public posts under one hashtag, which you pass as keyword, and returns each post's caption in text, its media_type (image, video or carousel), like, comment and view counts, the author's handle, display name and follower count, the publish time and location text. Marketers and trend researchers use it to see what people post under a tag, which formats draw engagement and which accounts post under it most.

keyword is a hashtag word such as coffee, with or without the leading #, not a free-text search phrase. Leave out results_type for regular posts, or set it to reel or reels for short-video results. The capability is async: the call returns a job_id instead of rows, and you fetch the results with that ID later. A null like_count, comment_count or view_count means the number was not disclosed, not that it is zero.

  • Returns 202 and a job_id
  • Poll the job for the posts
  • No charge for failed or empty results

API health

24h health
96%
24h average time
38.67 s
  • Healthy / normal
  • Available
  • Limited
  • Mostly down
Healthy

Last 24 hours

Last 30 days

  1. 1Request

    POST /api/v1/social
    {
      "platform": "instagram",
      "action": "discover",
      "params": {
        "keyword": "coffee"
      }
    }
  2. 2JSON response

    {
      "results": [
        {
          "text": "Some days I wake up a baddie, and some days I wake up a saddie.
    .
    .
    .
    .
    .
    .
    #fyp #instamood #burberry #coffee #cafe @••• @••• @••• @••• @•••",
          "post_id": "De4za3DANzi",
          "media_type": "image",
          "like_count": -1
        },
        …
      ],
      "count": 18
    }
  3. 3Rows

    textpost_idmedia_typelike_count
    Some days I wake up a baddie, and some days I wake up a saddie. . . . . . . #fyp #instamood #burberry #coffee #cafe @••• @••• @••• @••• @•••De4za3DANziimage-1
    ♥️🌎🌎👌🏻👌🏻. . . . . . . . . . . . #لايك #الكحلي #coffee #flowers #venezuelaDe4zXldkb3jimage1
  4. 4CSV

    instagram-discover-sample.csv post_id,url,text,media_type,like_count,comment_count,view_count,author_username,author_name,posted_at,location,id,image_url,video_url,author_id,width,height,is_comments_disabled,author_follower_count,hashtags,top_comments

A request with keyword (a hashtag word) and optional results_type and limit goes in and returns 202 with a job_id. You poll the jobs endpoint for the post rows, which become table rows and a CSV file.

What data you get

The table shows rows from a real call for the hashtag coffee, captured October 24, 2026 at 18:28 (UTC), that returned 18 rows. Gray bars mark removed personal information (••• in the CSV). Your own calls first return a job_id; once the job finishes, you get these fields as listed in the field reference.

post_idurltextmedia_typelike_countcomment_countview_countauthor_usernameauthor_nameposted_atlocationidimage_urlvideo_urlauthor_idwidthheightis_comments_disabledauthor_follower_counthashtagstop_comments
De4za3DANzihttps://www.instagram.com/p/De4za3DANzi/Some days I wake up a baddie, and some days I wake up a saddie. . . . . . . #fyp #instamood #burberry #coffee #cafe @••• @••• @••• @••• @•••image-10null2026-10-24T18:43:18+00:00nullhttps://scontent-cph2-1.cdninstagram.com/v/t51.82787-15/865668555_18501136627099477_1202278696858241993_n.jpg?stp=dst-jpg_e35_p1080x1080_sh2.08_tt6&_nc_cat=102&ig_cache_key=NDAxNTE4NDU5MzExMTA0MDM5MQ%3D%3D.3-ccb7-5&ccb=7-5&_nc_sid=58cdad&efg=eyJ2ZW5jb2RlX3RhZyI6IkNBUk9VU0VMX0lURU…null24793305nullnull["fyp","instamood","burberry"]null
De4zXldkb3jhttps://www.instagram.com/p/De4zXldkb3j/♥️🌎🌎👌🏻👌🏻. . . . . . . . . . . . #لايك #الكحلي #coffee #flowers #venezuelaimage10null2026-10-24T18:42:51+00:00nullhttps://scontent-cph2-1.cdninstagram.com/v/t51.82787-15/863292678_17970790107172812_3863795868010461481_n.webp?stp=dst-webp_p1080x1080_sh2.08&_nc_cat=102&ig_cache_key=NDAxNTE4NDUzNjc5NDMwNjU5MQ%3D%3D.3-ccb7-5&ccb=7-5&_nc_sid=58cdad&efg=eyJ2ZW5jb2RlX3RhZyI6IkNBUk9VU0VMX0lURU0ueHBp…null14401920nullnull["لايك","الكحلي","coffee"]null

Use cases

  • Pull a batch from a tag

    Fetch up to 200 posts under a hashtag in one job, then analyze posted_at and like_count in bulk once it finishes.

  • Compare formats

    Group rows by media_type and compare like_count and comment_count for images, videos and carousels.

  • See who posts

    Read author_username and author_follower_count to see who posts under the tag and how big they are.

  • Reels versus posts

    Run the same keyword once without results_type and once with reels, then compare view_count across the two batches.

Hashtag Search vs EveryInfra

Here is how Instagram's official Hashtag Search and EveryInfra discover compare on scope, recency and access.

ComparedHashtag SearchEveryInfra
Scope"Find public IG Media that has been tagged with specific hashtags."keyword is a hashtag word. A leading # is removed, and it is not a full-text search of any text.
RecencyEdge recent_media: "Only returns media objects published within 24 hours of query execution."Each row has the publish time posted_at. One call returns at most 200 rows, 30 by default.
Access you needApp Review: "In order to use this API, you must undergo App Review and request approval for:" "the Instagram Public Content Access feature"One EveryInfra API key in the Authorization: Bearer header. No Instagram login or Instagram access token is needed.

Quotes are from Meta's developer documentation, checked 2026-11-09. Official sources: Hashtag Search (updated 2026-08-17) · IG Hashtag Recent Media (updated 2026-08-17)

Limits and gotchas

  • The call is async by default: it returns 202 and a job_id, and you poll GET https://api.everyinfra.com/api/v1/jobs/<job_id> until the job finishes and returns the post rows.
  • keyword is required and is a hashtag word; a leading # is removed. It looks up that tag and is not a full-text search.
  • limit is an integer from 1 to 200 and defaults to 30; larger values return 422 before any charge.
  • There is no page parameter. One call returns at most 200 rows and can return fewer than limit.
  • Leave out results_type for regular posts, or pass reel or reels for short videos; any other value returns 422.
  • The results do not explain Explore ranking or prove a trend.

Pricing

You pay $0.000556 per call, not per row, and one call reads up to 200 posts. This holds for async jobs too. Failed calls and empty results are not charged.

CallsCost
10,000$5.56
100,000$55.56
1,000,000$555.56

Totals use the list price per call.

Code samples

#
bash
curl -X POST 'https://api.everyinfra.com/api/v1/social' \
  -H "Authorization: Bearer $EVERYINFRA_API_KEY" \
  -H 'Content-Type: application/json' \
  --data-raw '{
  "platform": "instagram",
  "action": "discover",
  "params": {
    "keyword": "coffee"
  }
}'

OpenAPI definition (JSON)Samples read the key from the EVERYINFRA_API_KEY environment variable; copied code never contains your key.

API reference

See the parameters, response fields, errors and billing for discover, and copy the page or open it as Markdown for an AI assistant.

POST

AI prompt

#
Please help me write a data collection script with the EveryInfra Instagram Content discovery endpoint (instagram/discover).

How the endpoint works:
- Request: POST https://api.everyinfra.com/api/v1/social with the header Authorization: Bearer <API key>. Read the key from the EVERYINFRA_API_KEY environment variable and never hard-code it.
- In the request body, set platform to instagram and action to discover, and put the parameters inside params.
- Required parameters:
  - keyword: Specifies the target hashtag string for the discover action, automatically stripping leading # symbols.
- Optional parameters:
  - results_type: Selects the content type for discover and hashtag: omit it for regular posts, or pass reel or reels for short videos. posts cannot be passed explicitly, and any other value returns 422. (allowed: reel / reels)
  - limit: The most rows to return in this call, an integer from 1 to 200. The default applies when you leave it out, and a call can return fewer rows. Larger values return 422 before any charge. (default: 30)
- Returns a list of records. Main fields of each record: post_id, url, text, media_type, like_count, comment_count, view_count, author_username, author_name, posted_at, location, id; 21 fields in total, full list at https://api.everyinfra.com/api/v1/social/catalog?platform=instagram.
- Example request body:
{
  "platform": "instagram",
  "action": "discover",
  "params": {
    "keyword": "coffee"
  }
}
- Price: $0.56 per 1,000 requests; failed and empty results are not charged.
- This endpoint is asynchronous by default: it returns 202 and a job_id, then you poll GET https://api.everyinfra.com/api/v1/jobs/{job_id} until the status is succeeded or failed.
- On 422, fix the request using the suggested parameter names and allowed values in the error; on 429 or 503, wait for Retry-After and try again.

Before writing code, ask me which targets I need, how many, which fields, and what output format I want; then confirm the plan and the rough cost with me.

Request parameters

#
NameInTypeRequiredDefaultDescription
AuthorizationheaderstringYes-Bearer followed by your API key. Create it in the console; never put it in a URL or a code repository.
platformbodystringYesinstagramPlatform identifier, fixed value.
actionbodystringYesdiscoverCapability identifier, fixed value.
keywordbody.paramsstringYes-Specifies the target hashtag string for the discover action, automatically stripping leading # symbols. This parameter queries hashtags rather than executing general full-text searches, and differs from the tag parameter in the hashtag action.
results_typebody.paramsstring (enum)No-Selects the content type for discover and hashtag: omit it for regular posts, or pass reel or reels for short videos. posts cannot be passed explicitly, and any other value returns 422. It does not choose the response file format.Allowed valuesreelreels
limitbody.paramsinteger (1–200)No30The most rows to return in this call, an integer from 1 to 200. The default applies when you leave it out, and a call can return fewer rows. Larger values return 422 before any charge.

Response example

#
Captured October 24, 2026 at 18:28 (UTC) by calling this API with the parameters in the code sample above. results and count are that call's real response with personal information (names, handles, avatars, profile links, contact details) removed; the list keeps the first 2. id, billing and quota differ on every call, so only their shape is shown.
json
{  "id": "req_…",  "platform": "instagram",  "action": "discover",  "results": [    {      "post_id": "De4za3DANzi",      "url": "https://www.instagram.com/p/De4za3DANzi/",      "text": "Some days I wake up a baddie, and some days I wake up a saddie.\n.\n.\n.\n.\n.\n.\n#fyp #instamood #burberry #coffee #cafe @••• @••• @••• @••• @•••",      "media_type": "image",      "like_count": -1,      "comment_count": 0,      "author_username": "•••",      "author_name": "•••",      "posted_at": "2026-10-24T18:43:18+00:00",      "id": "•••",      "image_url": "https://scontent-cph2-1.cdninstagram.com/v/t51.82787-15/865668555_18501136627099477_1202278696858241993_n.jpg?stp=dst-jpg_e35_p1080x1080_sh2.08_tt6&_nc_cat=102&ig_cache_key=NDAxNTE4NDU5MzExMTA0MDM5MQ%3D%3D.3-ccb7-5&ccb=7-5&_nc_sid=58cdad&efg=eyJ2ZW5jb2RlX3RhZyI6IkNBUk9VU0VMX0lURU…",      "author_id": "•••",      "width": 2479,      "height": 3305,      "hashtags": [        "fyp",        "instamood",        "burberry"      ]    },    {      "post_id": "De4zXldkb3j",      "url": "https://www.instagram.com/p/De4zXldkb3j/",      "text": "♥️🌎🌎👌🏻👌🏻.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n#لايك #الكحلي #coffee #flowers #venezuela",      "media_type": "image",      "like_count": 1,      "comment_count": 0,      "author_username": "•••",      "author_name": "•••",      "posted_at": "2026-10-24T18:42:51+00:00",      "id": "•••",      "image_url": "https://scontent-cph2-1.cdninstagram.com/v/t51.82787-15/863292678_17970790107172812_3863795868010461481_n.webp?stp=dst-webp_p1080x1080_sh2.08&_nc_cat=102&ig_cache_key=NDAxNTE4NDUzNjc5NDMwNjU5MQ%3D%3D.3-ccb7-5&ccb=7-5&_nc_sid=58cdad&efg=eyJ2ZW5jb2RlX3RhZyI6IkNBUk9VU0VMX0lURU0ueHBp…",      "author_id": "•••",      "width": 1440,      "height": 1920,      "hashtags": [        "لايك",        "الكحلي",        "coffee"      ]    }  ],  "count": 18,  "billing": {    "charged": …,    "charged_usd": …,    "balance_after_usd": …,    …  },  "quota": { … }}

Response fields

#

Business data is in results. The table lists the fields a record can contain; values the platform does not show are never made up.

FieldMeaning
post_idKeeps the platform's own meaning
urlLink to the record on the platform.
textBody text with HTML removed, returned in full and never cut short (on a few platforms the list results themselves carry only an excerpt; the platform's field notes say so).
media_typeKeeps the platform's own meaning
like_countLikes. null means the platform or this capability does not disclose it; it is not 0.
comment_countComments. null means not disclosed, not 0.
view_countViews or plays. null means not disclosed, not 0.
author_usernameAuthor's username (@handle), usually usable in URLs.
author_nameAuthor's display name.
posted_atPublish time in ISO 8601, UTC (for example 2026-08-07T12:34:56+00:00). Non-standard strings from the platform are passed through as is, so parse defensively. null means the platform does not disclose it.
locationLocation description passed through as is; the format varies by platform.
idThe record's unique ID on the platform. Unique only within one platform; IDs can repeat across platforms.
image_urlImage link. Capabilities with several images may return an image_urls array.
video_urlKeeps the platform's own meaning
author_idAuthor's unique ID on the platform.
widthKeeps the platform's own meaning
heightKeeps the platform's own meaning
is_comments_disabledKeeps the platform's own meaning
author_follower_countAuthor's follower count. null means not disclosed.
hashtagsHashtags in the text, in order of appearance; absent when there are none.
top_commentsKeeps the platform's own meaning

Errors and billing

#
401
Missing or invalid key.
402
Insufficient balance. Top up first.
422
Invalid parameter name or value. Fix it using the suggestions in the error. No charge.
429
Per-minute request limit reached. Wait for Retry-After, then try again.
503
Could not complete. The held charge is returned to your balance. If the outcome is unknown, verify it before you retry.
200 empty
No data. No charge.

Errors

FAQ

How do I get the results of an async discovery call?

Instagram Content discovery is async, so the call answers with a job_id rather than rows. Store that ID and use it to fetch the results later; your code makes two steps, submitting the hashtag and then collecting the rows. Keep the keyword and results_type you sent beside the job_id, so each result set stays tied to its request.

Is keyword a full-text search?

No. In Instagram Content discovery, keyword is a hashtag: a leading # is removed and the tag itself is looked up, so coffee and #coffee make the same request. Words that appear only in captions are not searched. The Instagram Hashtag capability also lists a tag's posts or reels, synchronously and under a different parameter name.

How do I get Reels instead of regular posts?

Set results_type to reel or reels; both switch Instagram Content discovery to short-video results. Leave the parameter out for regular posts: posts is not a value you can send, and any other value is rejected with a 422 error when parameters are checked. The parameter picks the kind of content, not an output format such as JSON or CSV.

What does the Instagram content discovery API return?

It returns posts under the hashtag: text, media_type, like_count, view_count, author_follower_count and posted_at. The call returns 202 and a job_id first.

How many posts can one call return, and how do I get them?

limit is 1 to 200 and defaults to 30. One call returns at most 200 rows, possibly fewer, with no page parameter. You poll the jobs endpoint with the job_id to get the rows.

How much does it cost?

It costs $0.000556 per call, or $0.56 per 1,000 calls, billed per call and not per row. Async jobs are billed the same way. Failed calls and empty results are not charged.

Do I need an Instagram login?

No. You send one EveryInfra API key in the Authorization: Bearer header. No Instagram login or Instagram access token is needed.

What is the difference between discover and hashtag?

For the same tag the fields are mostly the same. discover takes keyword, runs async and returns up to 200 rows. hashtag takes hashtag, answers in the same response and returns up to 100 rows.

You can call the other Instagram endpoints with the same key, such as reading a hashtag's content synchronously or a post by its link.

Our own visit stats are always on. Google Analytics loads only if you choose “Allow analytics”. Privacy policy