---
title: "Make it mine, or Write my intro: written from this find"
method: POST
path: "/v1/finds/{find_id}/remix"
tags: ["long form", "packaging"]
---

# Make it mine, or Write my intro: written from this find

`POST /v1/finds/{find_id}/remix`

## 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/finds/{find_id}/remix`
- Auth: none declared

Write my intro: body {"mode": "intro", "video_brief": "<your video in a few
sentences, 10 to 600 characters>"} (a long find only; niche and n are not used) writes
your own intro in this real opening's structure: one entry in `written` holding a
`beat` for each beat of the real opening, in order, each with its seconds (from_s,
to_s) and words_budget taken from the real opening's own timing, the words to `say`
with {placeholders} for what only you know, and suggested_on_screen and suggested_broll
(suggestions, never part of what is said). A number you did not write becomes {number}
(numbers_to_placeholders counts them). Same price and rules as below: 1 credit, labelled
as written, 422 remix_not_possible when the model copied the real opening or broke a
budget.

Otherwise write up to n (1 to 5, default 3) new openings or packages for your niche
that keep this one real find's structure. From a long find: `written` holds openings (hook, then,
kept_structure) built on its template and its order of beats. From a packaging find:
packages (title, thumbnail, thumbnail_text, kept_structure) built on its title
template and its thumbnail's composition. Body: {"niche": "teeth whitening", "n": 2}.
Every answer carries `label`: these are written, never found; one that is the real
find's own words is dropped; they are never added to a run, a keep or an export. Costs
1 credit per call, taken before the model is asked and refunded if it does not answer
(503). 404 for a find that is not yours. Limited per account per hour (429). Needs
research. The answer carries remix_id; GET /v1/finds/{find_id}/remixes and GET
/v1/remixes/{remix_id} read it back, free. MCP: remix_find.

## Path parameters

- `find_id` string, uuid, required

## Headers

- `Idempotency-Key` string, nullable: retry safely: the same key and body within 24 hours answer the saved remix (Idempotent-Replayed: true) and charge nothing; the same key with another body is 422 idempotency_key_reused
- `authorization` string, nullable: Bearer hd_... from POST /v1/accounts or POST /v1/keys

## Request body

- RemixFindIn: POST /v1/finds/{find_id}/remix. Openings or packages: niche and n. Write my intro (a long find): mode "intro" and video_brief; niche and n are not used.
  - `niche` string: your niche, product or audience, as you would say it (1 to 120 characters)
  - `n` integer: how many lines to write, 1 to 5 (default 3)
  - `mode` 'openings' | 'intro' | 'null', nullable: optional: "openings" (the default) writes openings or packages for a niche; "intro" is Write my intro: your own timed intro for the video you describe in video_brief, in this long-form opening's structure. Only a long find has an intro (a packaging find is 422); niche and n are not used in intro mode
  - `video_brief` string, nullable: required for mode "intro", 10 to 600 characters: what your video is about, in a few sentences, in your own words and language. The intro uses only the facts and numbers you write here; anything else becomes a {placeholder}

## Response `200`

Successful Response

- RemixFindOut
  - `find_id` string, required
  - `kind` string, required: long or packaging: what was written from
  - `niche` string, nullable, required: the niche you gave; null in intro mode
  - `n` integer, required: how many were written; 1 in intro mode
  - `mode` string, nullable: "intro" on a Write my intro answer; absent on openings and packages
  - `video_brief` string, nullable: intro mode: your video's description, as asked (whitespace collapsed)
  - `written` WrittenFromFind[], required: at most n; one that is the real find's own words is dropped. Intro mode: one object holding the beats
    - `hook` string: long: what the creator says first
    - `then` string, nullable: long: what the next half minute has to deliver for the hook to pay off
    - `title` string: packaging: the written title
    - `thumbnail` string: packaging: what the thumbnail shows and how it is framed
    - `thumbnail_text` string, nullable: packaging: the words to print on it, or null for none
    - `kept_structure` string, nullable: what was kept from the real find, in a few words
    - `mode` 'intro': intro: present only on a Write my intro answer
    - `seconds` number: intro: where the intro ends, in seconds from the video's start; never past the real opening
    - `timing` 'measured' | 'estimated': intro: measured when the real opening's captions carry a clock, estimated (from its words) when they do not
    - `words_per_second` number: intro: the real opening's speaking rate the word budgets use
    - `beats` object[]: intro: one entry per beat of the real opening, in order
      - `beat` string: hook, stakes, proof, credibility, context, promise, preview, story, payoff, cta or other: the real beat it follows
      - `does` string, nullable: what the real beat does
      - `from_s` number
      - `to_s` number
      - `seconds` number: to_s minus from_s, from the real opening's own timing
      - `words_budget` integer: the most words these seconds hold at words_per_second
      - `say` string: the words to say, with {placeholders} for what only the creator knows
      - `words` integer: words in say; a placeholder counts one
      - `placeholders` string[]
      - `suggested_on_screen` string, nullable: a suggestion, not part of what is said
      - `suggested_broll` string, nullable: a suggestion, not part of what is said
    - `placeholders` string[]: intro: every {placeholder} to fill in, once each
    - `numbers_to_placeholders` integer: intro: how many numbers the model wrote that neither your video_brief nor the real opening's template gave; each is now {number}
  - `label` string, required: always "Written by Hook Detector from a real opening's structure" for a long find and "Written by Hook Detector from a real package's structure" for a package: written, never found; show the label with them
  - `credits_charged` integer, required: always 1
  - `credits` integer, required: your balance after this call
  - `remix_id` string, nullable: this remix's id: GET /v1/remixes/{remix_id} reads it back, free
  - `created_at` string, nullable

## Other responses

- `401`: missing, invalid, revoked or expired API key (code key_expired)
- `402`: not enough credits
- `403`: the key lacks the scope this call needs (insufficient_scope), or its credit_limit is spent (key_credit_limit_reached)
- `404`: not found on this account
- `413`: request body over the size cap
- `422`: invalid input (invalid_request, idempotency_key_reused), or remix_not_possible: the model answered but nothing it wrote kept the rules, or it declined the content; detail says why and the credit was refunded
- `429`: rate limited; see Retry-After
- `500`: our fault; names the request id
- `503`: model_unavailable: the language model did not answer; the credit was refunded

---

[API](https://skmtc.dev/hookdetector/apis/hook-detector.md) · [All operations](https://skmtc.dev/hookdetector/apis/hook-detector/llms.txt) · [OpenAPI document](https://skmtc.dev/hookdetector/apis/hook-detector/revisions/b136a2804d2b?raw)
