# Hook Detector Find short-form hooks that already work. Give a topic, get back real TikTok and Instagram clips with their opening lines and why each one travelled. Base URL: https://api.hookdetector.com MCP: https://api.hookdetector.com/mcp (streamable HTTP; /mcp and /mcp/ both work) OpenAPI: https://api.hookdetector.com/openapi.json ## Every route POST /v1/accounts sign up, no auth GET /v1/me your account and balance POST /v1/research start a run GET /v1/runs your runs, newest first GET /v1/runs/{run_id} one run and its hooks GET /v1/hooks/{hook_id} one hook GET /v1/hooks/{hook_id}/embed playable embed POST /v1/hooks/{hook_id}/decision keep or reject GET /v1/keeps the hooks you kept POST /v1/chat one chat turn GET /v1/conversations your conversations GET /v1/conversations/{conversation_id} one conversation GET /health, /llms.txt, /openapi.json ## Start from nothing curl -X POST https://api.hookdetector.com/v1/accounts Optional body: {"label": ""}. Returns an api_key and free credits. No form, no human step. The key is shown once. Send it on every other call as: Authorization: Bearer hd_... curl https://api.hookdetector.com/v1/me -H "authorization: Bearer $KEY" returns your account_id, credits, key_prefix, label and created_at. ## Find hooks curl -X POST https://api.hookdetector.com/v1/research \ -H "authorization: Bearer $KEY" -H "content-type: application/json" \ -d '{"topic":"short term rental tax strategy","count":10}' Body: topic required, 3 to 200 characters count optional, 1 to 30, default 10 reuse optional, default true: start from rows you already paid for on the same topic, so a second cut is close to free conversation_id optional, one of your conversations (from /v1/chat) to attach the run to Returns 202 with a run_id and credits_reserved straight away. Poll it every 3 to 5 seconds; a run usually takes about 2 minutes: curl https://api.hookdetector.com/v1/runs/$RUN_ID -H "authorization: Bearer $KEY" status goes queued, running, then done or failed. When status is "done", `hooks` holds the result. Each hook has: hook_id use it with the hook routes below hook the exact opening line, as spoken or shown, verbatim catchy_line the most quotable line anywhere in the clip, verbatim main_idea one sentence on what the clip argues why_it_travelled the specific device that made it spread topic three to six words naming the narrow subject onscreen_text text burned into the video, or every slide of a photo post in order transcript the full spoken transcript views, likes, creator, platform, watch_url, cover_url, above_floor, verdict A hook with no transcript and no on-screen text has a null `hook` and `catchy_line`. That is deliberate: there was no opening line to report, and we will not invent one from a caption. GET https://api.hookdetector.com/v1/runs?limit=20 your runs, newest first, limit 1 to 100 GET https://api.hookdetector.com/v1/hooks/{hook_id} one hook, every field ## Watch a clip in your own page curl https://api.hookdetector.com/v1/hooks/$HOOK_ID/embed -H "authorization: Bearer $KEY" Returns official TikTok or Instagram embed HTML. `kind` is "embed", or "fallback" when the creator has disabled embedding, in which case use cover_url and the transcript. ## Keep what you want curl -X POST https://api.hookdetector.com/v1/hooks/$HOOK_ID/decision \ -H "authorization: Bearer $KEY" -H "content-type: application/json" \ -d '{"verdict":"keep"}' curl "https://api.hookdetector.com/v1/keeps?run_id=$RUN_ID" -H "authorization: Bearer $KEY" verdict is "keep" or "reject"; run_id on /v1/keeps is optional. ## Chat POST https://api.hookdetector.com/v1/chat {"message": "...", "conversation_id": ""} GET https://api.hookdetector.com/v1/conversations?limit=30 your conversations, limit 1 to 100 GET https://api.hookdetector.com/v1/conversations/{conversation_id} messages and runs of one A chat turn either asks one clarifying question (action "clarify") or starts a run (action "research", with the run in `run`). Chat turns are limited per account per hour. ## Credits One credit is one provider call. A run reserves up to 200 credits before it spends anything and charges only what it used; the rest is refunded when it finishes. With less than 200 left, a run reserves what you have, down to a minimum (40 by default), and searches within it. A failed run costs nothing. Rerunning the same topic reuses rows you already paid for, so a second cut is close to free. ## Errors 401 missing or invalid API key 402 not enough credits; the message states your balance 404 no such run, hook or conversation on this account 422 invalid input: a bad id, topic length, count, limit or label 429 rate limited (signups per address, chat turns per account); see Retry-After 503 the chat's language model is unavailable; nothing was charged, try again ## MCP The same operations are tools at https://api.hookdetector.com/mcp over streamable HTTP: create_account, find_hooks, get_run, list_runs, get_hook, embed_hook, keep_hook, list_keeps, balance. Send the key as the header Authorization: Bearer hd_... or pass it as the api_key argument. find_hooks takes topic, count, conversation_id and reuse. list_runs returns the same {"runs": [...]} shape as REST. An error is a tool error whose text holds {"error": {"code": , "message": "..."}}. ## Scope TikTok and Instagram only. Clips are ranked above a 50,000 view floor first; when a topic has fewer than you asked for above it, the rest are the highest below it, each marked with above_floor false.