research

Find hooks on a topic. Returns immediately; wait on the run.

Start a research run across TikTok and Instagram and return its run_id at once. It reserves up to 200 credits (less on a smaller balance, down to 40) and charges only what it used; a failed run costs nothing, and so does a run that finds no hooks, within a per-account allowance (llms.txt has the numbers). A fresh run takes about 2 to 3 minutes (up to about 5 on a dialect request): then GET /v1/runs/{run_id}?wait=55 until status is done or failed. Needs research. A key with a credit_limit reserves at most what is left of it (403 key_credit_limit_reached under the minimum). Any language, dialect or country: set language ("Moroccan Darija", "ar-MA") and country ("MA"), or say it in the topic. Since 2026-10-01: posted_within_days (7, 30, 90 or 365) keeps the search to recent clips, and seed_hook_ids (up to 10 of your hooks) means "find more like these". Hooks carry virality (the v2 score), outlier (views over the creator's usual), posted_at and the other signals; a done run carries patterns, the structures winning in its deck. Since 2026-10-10: platforms (any of "tiktok", "instagram", "youtube"; all three when left out) searches and delivers only those platforms. MCP: find_hooks.

post/v1/research

Request

  • Base URL: https://api.hookdetector.com (the document declares no server; this is the origin it was published from)
  • URL: https://api.hookdetector.com/v1/research
  • Auth: none declared

Headers

Idempotency-Keystring nullable

retry safely: the same key within 24 hours returns the first run and reserves nothing

authorizationstring nullable

Bearer hd_... from POST /v1/accounts or POST /v1/keys

Request body

topicstring required

what the clips are about, 3 to 500 characters. Instructions inside it are fine: a long topic, or one with a language or country, is searched by the subject read out of it, never verbatim.

countinteger

how many hooks to deliver, 1 to 30

conversation_idstring nullable

attach the run to one of your conversations

reuseboolean

start from rows you already paid for

languagestring nullable

optional, up to 60 characters: only clips spoken or written in this language or dialect, in words or as a tag: "Moroccan Darija", "ar-MA", "Egyptian Arabic", "Brazilian Portuguese". Any language works, including a regional variety ("Quebec French", "Flemish", "Catalan") and a mixed, code-switched one ("Hinglish", "Taglish", "Moroccan Darija with French"), or two joined by "or" ("Tagalog or Taglish"). The value is handed to the judges exactly as written; how well they honour a mixed or either-of value is not measured yet. Saying it inside topic works too; this field wins when both are given.

countrystring nullable

optional: only clips from creators in this country, as an assigned ISO 3166-1 alpha-2 code: MA, EG, BR, US (UK is read as GB). For a region that is not a country, send its country's code and name the regional variety in language: Quebec is country CA with language "Quebec French", Flanders BE with "Flemish", Catalonia ES with "Catalan". The country places the TikTok search there; the language judge does the regional filtering, and Instagram reports no country. A country alone does not restrict the language.

posted_within_days7 | 30 | 90 | 365 | null nullable

since 2026-10-01: optional, how recent the clips must be, as days: 7, 30, 90, 365. The search asks the platforms for that window and the floor for a clip under 7 days old uses views per day (10,000 a day passes); null or left out means any time. A clip's posted_at and age_days say what the run found.

seed_hook_idsstring[] nullable

since 2026-10-01: optional, up to 10 hook ids from your runs (a kept hook from GET /v1/keeps, or any hook you can read): "find more like these". The engine reads their lines, topics, creators and languages to steer the search phrases and the creators it expands; a seed is never delivered again. An id that is not one of your hooks is 422.

platformsstring[] nullable

since 2026-10-10: optional, which platforms to search and deliver from, a non-empty list of "tiktok", "instagram" and "youtube" (YouTube Shorts); left out (or all three) searches all three. ["instagram"] delivers Instagram reels only. Names are read without regard to case and a repeat counts once; an empty list or any other name is 422 naming platforms. The run echoes it as platforms.

Example request

{
  "topic": "short term rental tax strategy",
  "language": "Moroccan Darija",
  "country": "MA",
  "posted_within_days": 30,
  "platforms": [
    "instagram"
  ]
}

Response

a replay of an earlier start with the same Idempotency-Key; nothing was reserved

run_idstring required
statusstring required
kindstring

what the run researches: "short" (hooks from TikTok, Instagram and YouTube Shorts, POST /v1/research), "long" (how long-form YouTube outliers open, POST /v1/longform) or "packaging" (their titles and thumbnails, POST /v1/packaging). Every run from before 2026-10-07 is short

topicstring required
requestedinteger required
languagestring nullable

the language or dialect asked for, as sent, or null for any language

countrystring nullable

the country asked for, as an ISO 3166-1 alpha-2 code (upper-cased, UK read as GB), or null for any country

posted_within_daysinteger nullable

the recency window asked for (7, 30, 90 or 365 days), or null

seed_hook_idsstring[] nullable

the seed hooks asked for ("find more like these"), or null

platformsstring[] nullable

the platforms this Short form run searches and delivers from ("tiktok", "instagram", "youtube"): the ones asked for, or all three; null on a long or packaging run

credits_reservedinteger required
created_atstring required

Example response

{
  "created_at": "2026-09-23T10:00:00.000000+00:00",
  "credits_reserved": 200,
  "requested": 10,
  "run_id": "8f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
  "status": "queued",
  "topic": "cold plunge recovery"
}

Changes

No recorded changes to this operation across all 1 revision of this API.