v1 · live

Hooklayer API

REST endpoints under https://hooklayer.dev/api/v1. Bearer auth via hl_live_* keys minted in the dashboard. Same endpoints exposed via MCP at /api/mcp for Claude / Cursor / n8n.

Example prompts

Paste any of these into Claude Desktop (or any MCP client with Hooklayer connected) to see the full evidence-layer output. Each prompt exercises a different combination of the 8 tools.

Example 1 — Creator teardown with cited evidence

analyze_account · score_hook
Use Hooklayer to analyze @humphreytalks on TikTok. Show me the full viral_dna block including viral_dna_signals, replicability_signals, and originality_signals arrays — I want to see the evidence quotes verbatim, not paraphrases. Also surface the would_fail_because field and provenance.video_post_dates so I can confirm the data is recent. Then take the hook from his top video, score it via score_hook, and compare the signals[] between your analyze output and the score output.

Expected output: Returns Humphrey's DNA scores (viral 87 / replicability 85 / originality ~78), 3-5 signals per DNA dimension with cited evidence strings, the closest calibration anchor, and a would_fail_because counterfactual. Total credits: 5 (analyze) + 1 (score) = 6 credits.

Example 2 — Adversarial scoring on a draft script

predict_virality
Use Hooklayer's predict_virality on this draft script: "Hey guys today I want to talk about saving money. So basically you should save more and spend less. That is the whole video bye." Show me BOTH the headline virality_score (adversarial) AND the optimistic_score side by side. Surface the full signals[] array with evidence, the would_fail_because counterfactual, the calibration_check.anchor, and every attack_vectors[] item with its severity and mitigation. If the adversarial_gap is greater than 15, explicitly tell me the optimistic score is unreliable.

Expected output: Shows the cardinal-coupling fix in action: optimistic_score returns the upstream value (~70-75 for this AI-slop script), adversarial_score drops it to the teens, gap of 50-60. attack_vectors[] names 3-5 failure modes (skip_at_3s, no share trigger, generic opener).

Example 3 — Voice metrics as numbers, not vibes

analyze_account · match_voice
Use Hooklayer to analyze @humphreytalks, then call match_voice using his top 3 video URLs as reference_samples and this draft as the input: "I'm going to teach you about index funds." Show me the full voice_metrics block AS NUMBERS — vocab_diversity_ttr, filler_rate_per_100_words, avg_sentence_length_words, and the top 5 signature_phrases with their counts. Compare the qualitative voice_profile labels (which read like vibes) against the deterministic voice_metrics (which are measurable). Then surface the rewritten_draft and tell me if any quality_warnings flagged banned corporate phrases.

Expected output: Returns voice_metrics with concrete numbers (e.g. TTR ~0.62, filler rate ~1.4/100w, signature phrases with frequency counts), the rewritten draft in Humphrey's voice, and a quality.level. If banned phrases like 'leverage' or 'weaponize' slipped in, quality_warnings.phrases lists them. Demonstrates the 'math not vibes' upgrade. Total: 5 + 2 = 7 credits.

Authentication

Every request requires a Bearer token. Mint one in the dashboard. Free tier is auto-minted at signup with 50 lifetime credits.

Authorization: Bearer hl_live_<your-key-here>
POST

/api/v1/account/analyze

5 credits

The agentic anchor. Hand it a TikTok handle, get back deep intelligence + a recommended_chain field telling your AI agent which tool to call next, with parameters pre-filled.

Request
curl -X POST https://hooklayer.dev/api/v1/account/analyze \
  -H "Authorization: Bearer hl_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "handle": "@mrbeast",
    "platform": "tiktok"
  }'
Response
{
  "success": true,
  "profile": {
    "handle": "@mrbeast",
    "platform": "tiktok",
    "follower_count": 50000000,
    "avg_views": 25000000,
    "niche": "challenge_videos",
    "region": "US"
  },
  "viral_dna": {
    "viral_dna_score": 87,
    "viral_dna_explanation": "Elite consistency + signature stakes-revelation hook formula.",
    "viral_dna_signals": [
      {"name": "consistency_across_videos", "value": 9, "evidence": "consistency_score 92 — engagement variance below 0.1 CV across top 5"},
      {"name": "signature_hook_pattern", "value": 8, "evidence": "every top video opens with a shock claim followed by stakes reveal within 1.5s"}
    ],
    "replicability_score": 34,
    "replicability_explanation": "Personality-dependent — face + production budget drive the format.",
    "replicability_signals": [
      {"name": "face_dependence", "value": 9, "evidence": "talking-head ratio 0.8 across top 5 — solo creator can't reproduce without his face"},
      {"name": "budget_dependence", "value": 8, "evidence": "every top video features 5+ figure cash prizes — table stakes for the format"}
    ],
    "originality_score": 78,
    "originality_explanation": "Originates the 'shocking premise + verified payout' template.",
    "originality_signals": [
      {"name": "hook_reuse_rate", "value": 7, "evidence": "0.34 Jaccard similarity — recycles partial structure but reinvents specifics"}
    ],
    "consistency_score": 92,
    "hook_reuse_rate": 0.34,
    "audience_fatigue": "stable",
    "would_fail_because": "Without the face + production budget, the stakes-revelation format collapses — viewers don't believe the stakes are real."
  },
  "format_fingerprint": {
    "avg_duration_sec": 47,
    "words_per_second": 3.1,
    "pacing": "Loud open, stakes reveal at 1.5s, pay-off at 30s"
  },
  "recent_videos": [/* 5 with url, views, transcript, hashtags */],
  "performance_summary": {
    "best_performing_hooks": [/* top 2 by engagement */],
    "worst_performing_hooks": [/* bottom 2 by engagement */]
  },
  "steal_map": [
    {
      "what": "Stakes-revelation hook formula",
      "how": "Open with shock claim → reveal stakes in second 1.5 → name the prize",
      "applicability": ["finance", "fitness", "tech_tutorials"],
      "example_remix": "You're losing $4K/yr → here's the 30-second fix that pays for your year of groceries"
    }
  ],
  "content_gaps": ["Never posts long-form (>60s) — saturated market opportunity"],
  "recommended_actions": [
    {
      "action": "Copy the stakes-revelation hook to your niche",
      "expected_lift": "+34% over a generic hook",
      "next_tool": "viral_remix"
    }
  ],
  "recommended_chain": [
    {
      "tool": "match_voice",
      "params": {
        "draft": "your script text here",
        "reference_samples": [
          "https://tiktok.com/@mrbeast/video/750...",
          "https://tiktok.com/@mrbeast/video/748...",
          "https://tiktok.com/@mrbeast/video/745..."
        ]
      },
      "reason": "High-signal voice DNA — consistent across top 5"
    },
    {
      "tool": "trend_pulse",
      "params": { "niche": "challenge_videos" },
      "reason": "Verify their formula maps to current trends"
    },
    {
      "tool": "viral_remix",
      "params": { "source_url": "https://tiktok.com/@mrbeast/video/..." },
      "reason": "Their #2 video has the highest copyable structure"
    }
  ],
  "data_freshness_days": 2,
  "as_of": "2026-05-13T14:21:08Z",
  "provenance": {
    "data_source": "ScrapeCreators TikTok API (public profile data)",
    "videos_analyzed": 5,
    "video_post_dates": ["2026-05-09T18:00:00Z", "2026-05-06T21:30:00Z"],
    "transcripts_processed": 5,
    "rubric_version": "analyze_account.v1"
  },
  "credits_remaining": {"subscription": 4995, "payg": 0, "total": 4995}
}
  • TikTok (full pipeline) and YouTube Shorts (Data API + caption extraction). Pass platform: "tiktok" or "youtube". Instagram ships in v1.2.
  • 1-hour cache per handle. Repeated calls within window are billed but served from cache.
  • recommended_chain is the agent-loop hook: every step has params pre-filled to feed straight into the next tool call.
  • Every score has visible signals[] — agents cite evidence verbatim instead of paraphrasing numbers.
  • would_fail_because names the non-portable element (face/budget/voice/credibility) that blocks replication.
POST

/api/v1/hook/score

1 credit

Score a hook 0–100 against viral patterns. Breakdown categories scored 0–20. Returns 3 rewrites in one call.

Request
curl -X POST https://hooklayer.dev/api/v1/hook/score \
  -H "Authorization: Bearer hl_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "text": "3 things I wish I knew about scaling B2B SaaS",
    "platform": "tiktok",
    "niche": "Finance & Business"
  }'
Response
{
  "success": true,
  "score": 42,
  "percentile": 38,
  "weak_seconds": [],
  "pattern_match": "Generic",
  "rewrites": [
    "I lost $14k in 3 months trying this. Here's the receipt.",
    "Nobody told me this until I was 28 and broke.",
    "If you're a 30-something founder, this hook works."
  ],
  "why": "Closer to the 50 anchor — generic listicle opener, no specific stake or proof.",
  "breakdown": {
    "hook_strength": 7,
    "script_structure": 10,
    "retention_pattern": 8,
    "cta_effectiveness": 12,
    "shareability": 8
  },
  "signals": [
    {"name": "specificity", "value": 2, "evidence": "no concrete numbers or proper nouns — '3 things' is meaningless"},
    {"name": "emotional_stake", "value": 1, "evidence": "no implied consequence — passive curiosity at best"},
    {"name": "scroll_stop_velocity", "value": 3, "evidence": "starts with a number which helps slightly, but '3 things' is overused"},
    {"name": "credibility_signal", "value": 2, "evidence": "'I wish I knew' implies the speaker learned but no proof attached"},
    {"name": "pattern_freshness", "value": 2, "evidence": "listicle hooks are the most saturated pattern on TikTok"},
    {"name": "share_trigger", "value": 1, "evidence": "no contrarian claim or share-prompt"}
  ],
  "would_fail_because": "Drop 'I wish I knew' and this becomes a pure listicle — score lands in the 20s.",
  "strengths": ["Clear topic"],
  "weaknesses": ["No specific stake", "No proof"],
  "as_of": "2026-05-13T14:22:51Z",
  "provenance": {
    "rubric": "Viral-pattern matcher across 11 archetypes; 5-category breakdown 0-20 each",
    "scoring_model": "Claude Sonnet (PRO tier)",
    "rubric_version": "score_hook.v2"
  },
  "credits_remaining": {"subscription": 4999, "payg": 0, "total": 4999},
  "from_subscription": 1,
  "from_payg": 0
}
POST

/api/v1/remix

3 credits

URL or transcript → fresh script that mirrors the original viral DNA.

Request
curl -X POST https://hooklayer.dev/api/v1/remix \
  -H "Authorization: Bearer hl_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "source_url": "https://www.tiktok.com/@user/video/1234567890",
    "my_topic": "B2B SaaS pricing tiers"
  }'
Response
{
  "success": true,
  "extracted_formula": {
    "hook_type": "Result First",
    "structure": "Result reveal → backstory → method → CTA",
    "pacing": "PEAK-MEDIUM-RISING-WARM",
    "emotional_triggers": ["surprise", "social proof", "curiosity"],
    "why_it_works": "..."
  },
  "fresh_script": {
    "hook": "...",
    "scenes": [
      {
        "section": "HOOK",
        "voiceover": "...",
        "camera": "front camera selfie mode",
        "action": "creator holds phone, shocked expression",
        "text_overlay": "47% conversion. Here's how."
      }
    ],
    "cta": "..."
  },
  "camera_shots": ["..."],
  "overlays": ["..."],
  "hook_score": 88,
  "credits_remaining": {"subscription": 4996, "payg": 0, "total": 4996}
}
  • Pass either source_url OR transcript. Direct transcript drops latency by ~50%.
  • For complex/blocked URLs, post the transcript directly.
GET

/v1/templates?niche=...

1 credit

Proven viral templates in a niche with hook patterns, format structures, and example URLs.

Request
curl "https://hooklayer.dev/v1/templates?niche=Finance%20%26%20Business&min_views=100000" \
  -H "Authorization: Bearer hl_live_..."
Response
{
  "success": true,
  "niche": "Finance & Business",
  "templates": [
    {
      "title": "Stakes-revelation hook + 3-step proof",
      "hook_pattern": "I lost $X in Y months. Here's the receipt.",
      "format": "Talking head + receipts B-roll + CTA",
      "avg_views": 248000,
      "examples": [
        "https://www.tiktok.com/@user/video/...",
        "https://www.tiktok.com/@user/video/..."
      ]
    }
  ],
  "generated_at": "2026-05-11T12:34:56.789Z",
  "credits_remaining": {"subscription": 4994, "payg": 0, "total": 4994}
}
  • Optional min_views filter — only return templates with example videos above this view threshold.
  • Pulled from a corpus of 100K+ analyzed viral videos, ranked by niche fit.
POST

/v1/voice/match

2 credits

Extract a creator's voice DNA from 3+ reference samples and rewrite a draft in their voice. Two phases bundled in one call.

Request
curl -X POST https://hooklayer.dev/v1/voice/match \
  -H "Authorization: Bearer hl_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "draft": "Today I want to talk about cold outreach for B2B SaaS",
    "reference_samples": [
      "https://www.tiktok.com/@alexhormozi/video/...",
      "https://www.tiktok.com/@alexhormozi/video/...",
      "https://www.tiktok.com/@alexhormozi/video/..."
    ]
  }'
Response
{
  "success": true,
  "voice_profile": {
    "energyLevel": 7,
    "humorStyle": "none",
    "personality": "direct, authoritative",
    "vocabularyLevel": "plain-spoken",
    "sentenceLength": "short, punchy",
    "signatureMoves": ["names a number", "rejects soft framing", "ends with a directive"],
    "favoriteWords": ["receipts", "actually", "literally"],
    "avoidedWords": ["maybe", "perhaps", "kinda"],
    "audienceRelationship": "older brother giving advice"
  },
  "prompt_instructions": "<reusable system-prompt-ready voice spec>",
  "rewritten_draft": "Cold outreach is dead — but only the way you're doing it. Here's the 3-step receipt...",
  "credits_remaining": {"subscription": 4992, "payg": 0, "total": 4992}
}
  • reference_samples accepts URLs (TikTok/YouTube/Instagram — transcripts auto-extracted) and/or raw text. Minimum 3 items.
  • The prompt_instructions field is reusable — feed it into your own LLM calls to maintain the voice without re-running this endpoint.
POST

/v1/predict

2 credits

Score a draft script for viral potential BEFORE publishing. Returns viral DNA breakdown, retention diagnosis, target emotion, and the share trigger.

Request
curl -X POST https://hooklayer.dev/v1/predict \
  -H "Authorization: Bearer hl_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "script": "I tried 3 cold email tools so you don'\''t have to. The winner saved my Q3 pipeline. Here'\''s the breakdown...",
    "niche": "Finance & Business"
  }'
Response
{
  "success": true,
  "virality_score": 78,
  "viral_dna": {
    "hook_type": "Stakes + Verdict",
    "structure": "Promise → Verdict → Proof → CTA",
    "pacing": "PEAK-MEDIUM-RISING-WARM",
    "emotional_triggers": ["curiosity", "FOMO", "social proof"]
  },
  "retention_diagnosis": {
    "first_3_seconds": "strong — stakes named with a number",
    "weak_seconds": [12, 22],
    "drop_off_risk": "moderate — payoff at 0:14 might land too late"
  },
  "target_emotion": "validated curiosity",
  "share_trigger": "Saves the viewer time on a B2B decision",
  "recommended_changes": [
    "Move the verdict to 0:08 instead of 0:14",
    "Add a callback to the hook at the end"
  ],
  "credits_remaining": {"subscription": 4990, "payg": 0, "total": 4990}
}
  • Pass either a raw script or a video URL (transcript auto-extracted).
  • Use this BEFORE score_hook if you want a full-script verdict; use score_hook alone for just the opening hook.

MCP server

All endpoints exposed as MCP tools at https://hooklayer.dev/api/mcp. Drop into any MCP client config:

{
  "mcpServers": {
    "hooklayer": {
      "url": "https://hooklayer.dev/api/mcp",
      "transport": "http",
      "headers": {
        "Authorization": "Bearer hl_live_..."
      }
    }
  }
}

Tools exposed: analyze_account, score_hook, viral_remix, trend_pulse, find_viral_template, match_voice, predict_virality. analyze_account is the agentic anchor — its recommended_chain field tells your agent which tool to call next, with params pre-filled.

Errors

  • 401 — missing or invalid Bearer
  • 402 — insufficient credits (response body includes credits_required + credits_available)
  • 403 — wrong product (e.g. hm_live_ key) or missing tool permission
  • 422 — input validation failed
  • 429 — rate-limited; respectRetry-After header (seconds)
  • 500/502/503 — internal failure; no credits charged — safe to retry

Rate limits

Per API key, sliding 60-second window:

  • FREE — 30 req/min
  • STARTER — 60 req/min
  • PRO — 300 req/min
  • AGENCY — 1,000 req/min