Insight Social
GET /v1/threads/search

Threads Search API

Returns Threads posts matching a keyword, each with its text, like count, author, creation time, and the topic tag it was filed under at post.ext.topic_tag, plus a cursor for the next window.

10–340 credits, metered · cursor pagination · failed calls free · 10 free calls to start

curl "https://api.insightsocial.app/v1/threads/search?query=artificial+intelligence" \
-H "x-api-key: $INSIGHTSOCIAL_API_KEY"
200 OKJSON
{
"success": true,
"platform": "threads",
"endpoint": "/v1/threads/search",
"schema_version": "2",
"data": {
"items": [
{
"post": {
"id": "<string>",
"url": "<string | null>",
"kind": "<string | null>",
"content": {
"text": "<string | null>",
"media_urls": "<array | null>",
"thumbnail_url": "<string | null>",
"duration_seconds": "<number | null>"
},
"author": {
"id": "<string | null>",
"username": "<string | null>",
"display_name": "<string | null>",
"avatar_url": "<string | null>",
"verified": "<boolean | null>"
},
"engagement": {
"views": "<integer | null>",
"likes": "<integer | null>",
"comments": "<integer | null>",
"shares": "<integer | null>",
"saves": "<integer | null>"
},
"flags": {
"nsfw": "<boolean | null>",
"spoiler": "<boolean | null>",
"pinned": "<boolean | null>",
"deleted": "<boolean>",
"likes_hidden": "<boolean | null>",
"comments_hidden": "<boolean | null>",
"shares_hidden": "<boolean | null>",
"views_hidden": "<boolean | null>",
"saves_hidden": "<boolean | null>"
},
"published_at": "<string | null>",
"language": "<string | null>",
"ext": "<object | null>"
}
}
]
},
"pagination": {
"next_cursor": "<string | null>",
"has_more": "<boolean>"
},
"unavailable": [],
"credits_used": "<integer>"
}

When to use it

Use it to find posts by topic across Threads. Follow pagination.next_cursor to page deeper, or set limit (up to 100) to collect several windows in one call; start_date and end_date bound the period.

Parameters

Query parameters for GET /v1/threads/search. Send your key in the x-api-key header.

NameRequiredDescription
queryYesSearch keyword or phrase to find Threads posts
start_dateNoInclusive start of the search period (YYYY-MM-DD). Pagination never walks past it, and a relaxed query drops any post older than it. Threads treats the date pair as a ranking hint rather than a filter, so the window is enforced on our side: a post we cannot date is treated as outside it.
end_dateNoInclusive end of the search period (YYYY-MM-DD). Pagination starts here and walks back in time, and a relaxed query drops any post newer than it.
trimNoAsk for a stripped record. This is a real shape change, not just less whitespace: a trimmed row carries only the id, text, shortcode, like count, timestamp and author, so media, reply count, share count, view count, topic tag, pinned flag and quoted post all come back null.
cursorNoOpaque cursor from a prior response's pagination.next_cursor, passed back verbatim, to fetch the next (older) result window. It carries your date bounds, so paging cannot escape the period you asked for. A request that sends a cursor is never query-relaxed.
limitNoCollect AT LEAST this many unique posts in one call (1-100). This is a collection target, not a page size: the API walks whole result windows server-side until it has collected this many (or the query runs dry), so the response usually carries somewhat more than you asked for and never fewer unless the query ran out. Nothing you paid for is trimmed away. Omit for a single window. BUDGET FOR THE WALL CLOCK: the windows run one after another, at roughly 3.4 seconds each, so a high limit is a long request. Measured on production 07/09/2026, cache-cold: no limit 3.5s for 20 posts, limit=30 7.3s for 37, limit=50 10.2s for 55, limit=100 19.5s for 111. If your HTTP client defaults to a 10-second timeout, limit=50 and above will not fit inside it. Either raise the client timeout, or ask for a smaller limit and page with pagination.next_cursor, which costs the same credits for the same posts.
expandNoSet to false to search the exact phrase only. Ignored on a request that carries a cursor.
includeNoSend engagement to fill engagement.views and post.flags.pinned on the first 20 posts by looking each one up on /v1/threads/post in the same call. Adds 3 to 12 seconds, never more than 12. One token only: engagement. Not accepted with a limit above 20; page with the cursor for more.
max_pagesNo1 to 5 (default 1). Walk up to this many pages in one call and return the rows from all of them (after any filter). Each page walked is billed as one call to this endpoint; the whole walk counts once against your rate limit.

Response fields

The same unified schema every platform returns, so code written for Threads works on the other eight. A field the platform did not provide is null and listed in unavailable.

FieldTypeNotes
idstringAn identifier, always a string. Never parse it as a number: several platforms use ids above 2^53.
urlstring | null
kindstring | nullThe format of the post. Format words only, never a platform name. short = short-form vertical video (a reel, a TikTok, a YouTube Short).
content.textstring | null
content.media_urlsarray | null
content.thumbnail_urlstring | null
content.duration_secondsnumber | null
author.idstring | null
author.usernamestring | null
author.display_namestring | null
author.avatar_urlstring | null
author.verifiedboolean | null
engagement.viewsinteger | nullA count. null when the platform does not expose it; 0 only when it is really zero.
engagement.likesinteger | nullA count. null when the platform does not expose it; 0 only when it is really zero.
engagement.commentsinteger | nullA count. null when the platform does not expose it; 0 only when it is really zero.
engagement.sharesinteger | nullA count. null when the platform does not expose it; 0 only when it is really zero.
engagement.savesinteger | nullA count. null when the platform does not expose it; 0 only when it is really zero.
flags.nsfwboolean | null
flags.spoilerboolean | null
flags.pinnedboolean | null
flags.deletedboolean
flags.likes_hiddenboolean | null
flags.comments_hiddenboolean | null
flags.shares_hiddenboolean | null
flags.views_hiddenboolean | null
flags.saves_hiddenboolean | null
published_atstring | nullISO-8601 timestamp in UTC, ending in Z.
languagestring | nullThe content's language as the platform states it, e.g. en, pt-BR. Detected languages come later (§7.1).
extobject | nullPlatform-specific fields, snake_case.

Every field, error and example is in the Threads Search API reference.

How much does the Threads Search API cost?

Metered: 10–340 credits a call. The ceiling is reserved when the call starts and you are charged what it actually read.

  • Failed calls are free

    A call that errors or finds nothing costs 0 credits.

  • Know the price first

    Add dry_run=1 and the response quotes the call without making it. Nothing is charged.

  • One balance

    API calls and Chrome extension exports share the same credits, on the free plan too.

Threads Search API: frequently asked questions

Send GET /v1/threads/search with the query parameter and your key in the x-api-key header. Returns Threads posts matching a keyword, each with its text, like count, author, creation time, and the topic tag it was filed under at post.ext.topic_tag, plus a cursor for the next window.