---
title: "Get Public Hooks"
method: POST
path: "/api/v1/research/get-public-hooks"
tags: ["research"]
---

# Get Public Hooks

`POST /api/v1/research/get-public-hooks`

Public hooks feed — one merged, paginated list combining two sources:

- narrative hooks — the curated library (DB), tagged ``source: "narrative_hook"``
- video hooks     — ad hooks from the research OpenSearch index, tagged
                    ``source: "video_hook"``

Every page is split half-and-half between the sources (page_size 20 ->
10 narrative + 10 video, narrative block first) while both have items;
when one source is exhausted the other fills the remainder. ``search``
applies to both sources; the ``narrative_hook_*`` filters scope narrative
hooks, the research filters (category/sub_industries/creative_category/
keyword_value/brand_value) scope video hooks. ``family`` and
``is_organic`` scope both sides: they filter the video hooks in
OpenSearch, and — since the narrative catalog is all TikTok organic —
asking for paid-only or non-TikTok families drops the narrative side
entirely (reported as "filtered" in ``sources``). A failing source reports
"unavailable" in ``sources`` and the other still returns.

``family`` is the research index's own platform field ("META", "TIKTOK",
"YOUTUBE", "LINKEDIN", "INSTAGRAM", "PINTEREST"), and only ``family`` +
``is_organic`` together name a platform — META with ``is_organic`` false is
Meta paid, META with true is Meta organic.

## Headers

- `x-api-key` string, required

## Request body

- PublicHooksRequestDTO — Request for the public combined-hooks feed (video hooks + narrative hooks). All fields are optional. ``search`` and pagination apply to both sources; the ``*_category`` / industry / research filters scope each source.
  - `search` string, nullable
  - `page` integer
  - `page_size` integer
  - `include_video_hooks` boolean
  - `include_narrative_hooks` boolean
  - `category` string[], nullable
  - `sub_industries` string[], nullable
  - `creative_category` string[], nullable
  - `keyword_value` string[], nullable
  - `brand_value` string[], nullable
  - `family` string[], nullable
  - `is_organic` boolean, nullable
  - `narrative_hook_category` string[], nullable
  - `narrative_hook_industry` string[], nullable

## Response `200`

Successful Response

- unknown

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/brandbooster/apis/fastapi.md) · [All operations](https://skmtc.dev/brandbooster/apis/fastapi/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/brandbooster/fastapi/revisions/624917d53409/schema)
