Skip to content

Search

POST /v1/search runs a single search and returns a ranked set of matching Instagram posts in the same response. You describe what you are looking for in natural language; the API works out the intent — topic, time range, language, format, and any exclusions — and returns the best matches.

Reminder: a typical request takes 30–60 seconds. Call this endpoint from your backend with a read timeout of at least 90–120 seconds. See Latency.

POST https://api.sociable.how/v1/search
  • Authorization: required. Bearer sk_live_<YOUR_API_KEY>.
  • Content-Type: required. application/json.
{
"query": "content on finance apps that isn't too promotional from the last 90 days",
"limit": 12
}

Fields

  • query: required natural-language description of the content you want. 2–500 characters.
  • limit: optional cap on the number of results returned, between 1 and 12. Defaults to 12.

Unknown fields are rejected with 422. Malformed JSON returns 400.

The query is read as natural language — write it the way you would describe the content to a person, not as keywords or boolean syntax. Both short topic phrases and full sentences work:

  • grilling
  • body positive fashion
  • soccer tutorial content from the last 30 days
  • content on finance apps that isn't too promotional

What helps:

  • Name the topic clearly. soccer tutorial content matches better than a single broad word like soccer.
  • Add a time window in wordsfrom the last 7 days, in the last 90 days, from all time. If you don’t specify one, the default is the last 30 days.
  • Add tone or format when it mattersfunny, tutorial, vlog, POV.
  • State exclusions in plain languagethat isn't too promotional, no try-on hauls. These are honored.
  • Specify language or region if relevantin Korean, from the US.

What to avoid:

  • Don’t stack many constraints into one long sentence. Heavily over-constrained queries — several negatives plus a very specific scenario — routinely return nothing. Start broad, then narrow.
  • Don’t ask for content older than the recent corpus. The index covers recent posts; a query like from 2017 will return little or nothing.
  • Niche or long-tail brands and B2B / technical topics (a little-known product, or something like SOC2 compliance) often have no matching creator content.
  • Real-time platform trend status can’t be verified. Instead of what's trending on Instagram right now, search by topic and time — e.g. popular fashion content from this week.

Only Instagram content is indexed today.

{
"query": "content on finance apps that isn't too promotional from the last 90 days",
"interpretation": {
"timeRange": "the last 90 days",
"language": "English",
"region": null,
"mode": "search_results"
},
"message": "I have gathered English-language posts from the last 90 days focused on finance apps and money management tools. My search prioritized educational, analytical, and practical content while filtering out promotional material, referral-heavy posts, and generic advertisements.",
"suggestions": [],
"totalCount": 8,
"nextCursor": null,
"results": [
{
"id": "1f158f47-d5f2-6d59-a389-0d6aeb322a9b",
"platform": "Instagram",
"url": "https://www.instagram.com/reel/DYnrGcgPQRl/",
"caption": "Just opened a Fidelity Roth IRA with $50 and had NO idea what to do next. So I'm walking through the whole thing 👇🏾",
"thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.../thumbnail.jpg",
"mediaUrl": "https://scontent.cdninstagram.com/o1/v/t2/.../video.mp4",
"creatorHandle": "@financiallyintentional",
"metrics": { "likes": 36700, "comments": 1944 },
"matchLabel": "Fidelity app investment tutorial and walkthrough",
"matchHighlights": [
{
"time": "0:15",
"seconds": 15,
"title": "Fidelity App Walkthrough",
"explanation": "The creator demonstrates how to navigate the Fidelity app interface."
},
{
"time": "0:30",
"seconds": 30,
"title": "Zero-Fee Index Funds",
"explanation": "The creator identifies specific zero-fee investment options available within the app."
},
{
"time": "0:53",
"seconds": 53,
"title": "Placing an Order",
"explanation": "Step-by-step demonstration of executing a trade for a specific index fund."
},
{
"time": "1:04",
"seconds": 64,
"title": "Automating Investments",
"explanation": "The creator shows how to set up a recurring monthly investment in the Fidelity app."
}
]
},
{
"id": "27c4722f-d0df-4236-934c-2b14a04f877c",
"platform": "Instagram",
"url": "https://www.instagram.com/reel/DYftBg_PmDf/",
"caption": "idk what type of life y'all be living frl 🤨 #gemini #millennial #comedy #reels #netflix",
"thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.../thumbnail.jpg",
"mediaUrl": "https://scontent.cdninstagram.com/o1/v/t2/.../video.mp4",
"creatorHandle": "@alikaye999",
"metrics": { "likes": 17000, "comments": 513 },
"matchLabel": "Manual subscription management versus budgeting apps",
"matchHighlights": [
{
"time": "0:29",
"seconds": 29,
"title": "Budgeting App Ad",
"explanation": "The speaker reacts to a budgeting-app ad, which prompts their take on managing money manually."
},
{
"time": "1:26",
"seconds": 86,
"title": "Manual Subscription Management",
"explanation": "The speaker explains tracking subscriptions with email alerts and locking their card."
}
]
}
]
}
  • query: the query you sent, echoed back.
  • interpretation: how the API read your query. Useful to show the user what was actually searched.
    • timeRange: the time window applied, e.g. the last 90 days. Defaults to the last 30 days when you don’t specify one.
    • language: the language the results were drawn from.
    • region: the region applied, or null if none.
    • mode: search_results for a normal query, or top_results for broad “most viral / top content” browse queries. May be absent.
  • message: a short, plain-language summary of how the query was interpreted and what was returned. Safe to display to the user as helper text.
  • suggestions: 0–3 alternative queries to try. Populated only when a search returns thin results (see Thin results).
  • totalCount: the number of results in results.
  • nextCursor: reserved for pagination. Always null today (see Pagination).
  • results: the ranked matches, best first.

Each item in results is a post:

  • id: the post identifier. Use it with GET /v1/posts/:id to fetch full detail.
  • platform: the source platform. Currently always Instagram — the indexed corpus is Instagram-only today.
  • url: the public URL of the post.
  • caption: the original caption text.
  • thumbnailUrl: a still image for the post.
  • mediaUrl: a direct media URL for the post.
  • creatorHandle: the creator’s handle, including the leading @.
  • metrics: engagement counts captured for the post.
    • likes: like count.
    • comments: comment count.
  • matchLabel: a short label describing why this post matched. May be null.
  • matchHighlights: notable moments in the post relevant to the query. May be an empty array. Present on roughly half of results.
    • time: human-readable timestamp, e.g. 0:15.
    • seconds: the same moment in seconds.
    • title: a short title for the moment.
    • explanation: why the moment is relevant.

thumbnailUrl and mediaUrl are time-limited, signed Instagram CDN links. Fetch or cache them promptly — they expire and will later return 403.

When a search is too narrow and comes back with few or no results, the API returns up to three suggestions — complete alternative queries that relax an over-specific constraint while keeping your broad intent. The message field explains, in plain language, why the search was narrow.

{
"query": "viral kpop dance content from 2017",
"interpretation": {
"timeRange": "the last 90 days",
"language": "English",
"region": null,
"mode": "search_results"
},
"message": "This search may be too narrow for the available content. The index covers recent posts, so a 2017 time frame returns very little. Try broader wording or a wider time range.",
"suggestions": [
"viral kpop dance content from the last 90 days",
"popular kpop dance covers",
"viral kpop dance challenges"
],
"totalCount": 0,
"nextCursor": null,
"results": []
}

To act on a suggestion, send it as the query of a new POST /v1/search request. Each suggestion is a complete, standalone query.

A search returns a single ranked page of up to 12 results, and nextCursor is always null. Cursor-based pagination is planned: when it ships, responses with more results will return a nextCursor token to fetch the next page.

Need bulk export over historical data instead? Use the bulk Search API.

Terminal window
curl -sS -X POST "https://api.sociable.how/v1/search" \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
--max-time 120 \
-d '{
"query": "content on finance apps that isn'\''t too promotional from the last 90 days",
"limit": 12
}'