What it does: searches YouTube for long-form videos on the topic, keeps only the
outliers (a video whose views are at least min_outlier times the median views of its
own channel's recent uploads; 2 by default) posted in 2023 or later (nothing older is
ever delivered), reads the first intro_seconds (60 by default) of each one's
transcript, and says why that opening holds a viewer.
What comes back: the run's `finds`, ranked, strongest outlier first. Each has title,
channel, watch_url, player_url (an iframe src), thumbnail_url, views,
channel_median_views, outlier (28.2 means 28 times the channel's usual), outlier_score
(0 to 100 on one fixed scale: nothing else a run found moves it, so finds from
different runs rank together), outlier_tier, channel_size, likes_per_1k, posted_at,
duration_s, and the opening: intro (the first minute as it was said: lines of n, t in
seconds, text) and intro_text, always whole; and inside it the hook (verbatim: the lines
the analysis marks as the hook, ending on a sentence end, at most 25 seconds and 60
words, with hook_words, hook_start_s and hook_end_s, a sponsor read or greeting at the
front left out; hook_seconds is hook_end_s). auto_captions says the opening has almost
no punctuation. about_subject is yes or partly: a video the model judges not to be
about the subject is dropped. The analysis: hook_type (the same list as find_hooks),
mechanism (why it holds, quoting the opening word for word), promise, open_loop,
title_link (how the first lines pay off the title), beats (the opening in parts: from,
to, beat, does),
opens_with (cold_open, greeting, teaser, question, sponsor), format (the kind of
video), angle, template (the hook as a fill-in structure), steal_it and audience. When
the topic asks for a kind of opening ("question hooks", "storytime"), style_match says
whether each find is that kind and the matches come first. analysed is false
when the model could not analyse an opening: the opening is still real, its analysis
fields are null. The run's report.patterns lists the opening types at least two finds
share; report.shape says how the openings are built, counted from the finds
(hook_seconds, how long the hook runs, and hook_words as medians, beats with how many
openings use each and the second it usually starts_at, and the sequence of beats most
of them share); and
report.openers holds up to `openers` (3 by default, 0 for none) openings WRITTEN for
your topic from those structures (hook, then, hook_type, based_on). report.openers_label
is always "Written by Hook Detector from the structure of these real openings": show
it with them, never present one as a real video's opening. report.landscape is the
subject at a glance, counted from the videos the run held against their own channel
(videos, channels, outliers and their share, breakouts, small_channel_outliers,
recent_outliers). The run's hooks and bonus are always empty.
A link instead of a subject: when topic is a channel's YouTube address
(https://www.youtube.com/@name, or just @name) the run returns that channel's OWN
outliers, its recent long-form uploads that beat its usual (one provider call, no
search); when it is a long-form video's address the run returns that one video,
whatever its multiple (requested is 1). options.link says "channel" or "video". No
openings are written for a link (use remix_find on a find to write for your niche).
A Short's address is refused with 422.
Arguments: topic 3 to 500 characters; count 1 to 30 (default 8); language and country
optional; posted_within_days 30, 90, 365 or 730 to narrow the 2023 floor further;
channel_size "small", "medium" or "large" to keep only channels of that size (by what
their uploads usually get), so a small creator sees breakouts from channels their own
size; reuse=true (default) starts from the videos your last long or packaging run on
this topic bought within a week, and a video you already had read is delivered from
that read (analysis_from_earlier_read) at no model or provider cost. seen_before says
an earlier run of yours already found the video. idempotency_key: always pass one and
reuse it on a retry. wait_seconds 0 to 50: 0 returns the run_id at once; above 0 waits
and returns the run. Starts are limited per account per hour (429 rate_limited).
Cost: reserves up to 90 credits for 20 videos or fewer and 5 more for each video above
that (140 at 30; less on a smaller balance, down to 25) and charges
only the provider calls it made: the searches, one call per channel measured, one per
transcript read. A failed run costs nothing, and so does a run that
finds nothing, inside the same allowance a hook run has (the outcome says so).
Timing and next step: how long a run takes has not been measured yet, so never assume
a time. Call get_run with wait_seconds=50 until status is done or failed;
progress.items holds the finds written so far as cards
and progress.scan the videos it is looking at while it runs. Then keep_find, export_run. Same as POST /v1/longform. Needs the research
permission (403 insufficient_scope otherwise).