hooks

One hook, every field

One hook with every field: the verbatim opening line, the most quotable line, main idea, why it travelled, on-screen text, transcript, watch_url and the 9:16 player_url. hook_id comes from a run. Free. MCP: get_hook.

get/v1/hooks/{hook_id}

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/hooks/{hook_id}
  • Auth: none declared

Path parameters

hook_idstring uuid required

Headers

authorizationstring nullable

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

Response

Successful Response

hook_idstring required
rankinteger required
hookstring nullable required

the exact opening line; null when the clip had none

catchy_linestring nullable required
main_ideastring nullable required
why_it_travelledstring nullable required
topicstring nullable required
onscreen_textstring nullable required

text burned into the video; on hooks found before 2026-09-26, every slide of a photo post in order

transcriptstring nullable required
transcript_kind'speech' | 'music' | 'none' | 'other' nullable
languagestring nullable

the language or dialect the clip was judged to be in, named in English ("Moroccan Darija", not "Arabic"); null for hooks found before this field

creatorstring required
viewsinteger required
likesinteger nullable required
above_floorboolean required
watch_urlstring required
cover_urlstring nullable required
slide_countinteger nullable required

always null on hooks found since 2026-09-26 (no carousels are delivered); the slide count of a TikTok photo post on older hooks

found_bystring nullable required
captionstring nullable required
verdictstring nullable required
formatstring nullable

what kind of clip it is: talking_head, podcast, interview, stage (a person on camera talking; the main deck), or voiceover, text_on_screen, broll, skit, lipsync, trending_sound, slideshow, call_recording (a recorded call or voicemail), live_interaction (the creator with real people in the scene, not talking to the viewer), other (never delivered since 2026-10-08). Null on hooks found before 2026-09-29. A client should treat an unknown value as other.

section'main'

always "main": the deck of a person on camera talking. Bonus was removed on 2026-10-08, and bonus hooks older runs stored are no longer returned.

creator_countrystring nullable

the country of the creator's TikTok account as an ISO 3166-1 alpha-2 code ("MA"), as TikTok states it on the clip's search row. It is the account's country, not GPS. Always null on Instagram, which states none, and on hooks found before 2026-09-30. Never guessed.

placestring nullable

the name of the place the creator tagged on the post (at most 80 characters), null when untagged, as most posts are. Where it was posted from, not where the creator lives.

place_countrystring nullable

the tagged place's country as an ISO 3166-1 alpha-2 code, only when the platform states it (TikTok usually does, Instagram rarely). Null otherwise; never guessed from the name or the map position.

bannerstring nullable

since 2026-09-30: the banner hook, the title-style text the creator placed on the video to hook the viewer (a headline, a "POV:", a question, a list title), verbatim as one line of at most 200 characters. Null when the clip has none: running subtitles of the speech, usernames, watermarks and a lower third naming the speaker are never a banner. Null on hooks found before 2026-09-30. onscreen_text still holds all the text read on screen.

match'exact' | 'close' nullable

since 2026-09-30, on runs with a language or a country: "exact" when the clip is about the subject itself, "close" when it is about a neighbouring subject with the same intent (general wealth-building advice for "getting wealthy in your 20s"): a close match, delivered after every exact match and to be labelled as one. Null on hooks found before 2026-09-30 and on runs with no language or country, which are judged as before.

style_matchboolean nullable

since 2026-10-04, on a run whose request asked for a kind of opening ("controversial hooks", "question hooks", "storytime"): true when this hook opens that way (its hook_type is one asked), false when it is a strong hook on the subject that opens differently, delivered after the ones that match. Null when no kind was asked.

posted_atstring nullable

when the clip was posted, exact when the platform gives it; null when unknown

age_daysnumber nullable

days since posted_at, at delivery

views_per_daynumber nullable

views divided by age_days

creator_median_viewsinteger nullable

the creator's usual views per video: the median of their recent videos, pinned excluded (TikTok may use likes per video as a proxy, said so in outlier_basis)

outliernumber nullable

views divided by the creator's usual views per video (creator_median_views): 31.2 means 31 times what this creator normally gets. Null when the creator's baseline was not priced for this run.

outlier_basis'median_views' | 'likes_per_video' nullable

what creator_median_views was measured from, or null

duration_sinteger nullable

the clip's length in seconds

paidboolean nullable

an ad, a paid partnership or branded content, as the platform labels it; null when unknown

sound_reuseinteger nullable

videos reusing the clip's sound

own_soundboolean nullable

the sound is the creator's own

hashtagsstring[] nullable

the post's hashtags, at most 20, without the #

viralitynumber nullable

since 2026-10-01: how viral the clip is, 0 to 1 (0.58 is 58 out of 100), since 2026-10-02 on one fixed scale: the same clip scores the same in every run. Built from the outlier (views over the creator's usual, when known), freshness, travel (shares and saves per 1,000 views), own-sound reuse and a paid penalty; null on hooks found before this field.

virality_whystring nullable

one short line naming the strongest signal behind virality ("31x this creator's usual", "1.2M views in 4 days"); never empty when virality is set; null when unknown

hook_typestring nullable

since 2026-10-02: the device the opening uses, one of curiosity_gap, contrarian_claim, specific_number, identity_callout, stakes_threat, promise_payoff, pattern_interrupt, story_open, question, direct_command, other (then hook_type_other names it in two to five words). Null on older hooks and when the write-up gave none. A client should treat an unknown value as other.

hook_type_otherstring nullable

two to five words naming the device when hook_type is other, else null

mechanismstring nullable

since 2026-10-02: why the opening stops the scroll, in at most two short sentences: what the first three seconds make the viewer think or feel, quoting the clip's own words (every quote is checked word for word against what was said or shown), and the open question the clip then pays off. Never a view or follower count. why_it_travelled carries the same text. Null on older hooks.

visual_hookstring nullable

since 2026-10-02: one sentence on what the banner or other on-screen text adds to the spoken opening; null when no on-screen text hooks

audiencestring nullable

since 2026-10-02: the specific viewer this opening stops, a few words

templatestring nullable

since 2026-10-02: the hook as a fill-in structure of at most 20 words, its subject words replaced by {placeholders}

steal_itstring nullable

since 2026-10-02: one sentence on how a creator in another niche reuses this exact move

video_idstring nullable required
player_urlstring nullable required

a 9:16 iframe src (TikTok's player, Instagram's reel embed, YouTube's embed); null for an unusable id or a photo post found before 2026-09-26

aspectstring required
still_urlstring required

the card image as a JPEG, served by this API; no key needed

media_urlstring nullable

our own player's source: put it in a <video src>; it redirects to the clip's original file on TikTok's or Instagram's CDN (no key, nothing stored). null for YouTube (use player_url) and photo posts; a 404 or 503 from it means show player_url instead

Example response

{
  "above_floor": true,
  "age_days": 3.5,
  "aspect": "9:16",
  "audience": "people who already cold plunge",
  "banner": "STOP DOING 10 MINUTES",
  "caption": "cold plunge tips",
  "catchy_line": "Two minutes is the whole trick.",
  "creator": "someone",
  "creator_country": "US",
  "creator_median_views": 38000,
  "duration_s": 41,
  "format": "talking_head",
  "found_by": "search",
  "hashtags": [
    "coldplunge",
    "recovery"
  ],
  "hook": "Nobody tells you this about cold plunges.",
  "hook_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "hook_type": "contrarian_claim",
  "language": "English",
  "likes": 90000,
  "main_idea": "Short exposure beats long.",
  "mechanism": "\"Nobody tells you this\" promises a secret about a routine the viewer already does. The clip pays it off with the two-minute rule.",
  "onscreen_text": "STOP DOING 10 MINUTES",
  "outlier": 31.2,
  "outlier_basis": "median_views",
  "own_sound": true,
  "paid": false,
  "platform": "tiktok",
  "player_url": "https://www.tiktok.com/player/v1/7412345678901234567?autoplay=1",
  "posted_at": "2026-09-28T10:00:00+00:00",
  "rank": 1,
  "section": "main",
  "sound_reuse": 1200,
  "steal_it": "Name a routine your viewers already do and promise the thing nobody says about it.",
  "template": "Nobody tells you this about {routine}.",
  "topic": "cold plunge timing",
  "transcript": "Nobody tells you this...",
  "transcript_kind": "speech",
  "video_id": "7412345678901234567",
  "views": 1200000,
  "views_per_day": 342857.1,
  "virality": 0.91,
  "virality_why": "31x this creator's usual",
  "visual_hook": "The banner \"STOP DOING 10 MINUTES\" adds an order that contradicts the usual advice.",
  "watch_url": "https://www.tiktok.com/@someone/video/7412345678901234567",
  "why_it_travelled": "\"Nobody tells you this\" promises a secret about a routine the viewer already does. The clip pays it off with the two-minute rule."
}

Changes

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