YouTube Keyword Research
Turns a topic into a validated search filter over every YouTube title, description and transcript we index, plus the channels and videos it selects.
- Command
- /tl-keyword-research
- Run modes
- Quick, or deep with 3+ refinement rounds
- Returns
- Filter set, report link, videos and channels
Give it a topic in plain words. It expands that into candidate keywords, runs a live query for each against the 687M videos we index, drops the ones whose matches are off topic, and returns a filter plus the channels or videos it selects.
What you get
- A filter set, always. Reusable keyword groups, a link that opens a report with the filter applied, and the Boolean expression so anyone can re-run or audit it.
- Trend data. Matching uploads, sorted and windowed, with prevalence numbers: how many videos, how many distinct channels.
- Channel targets. Channels tiered by how much they cover the topic, ranked, context-validated, and flagged for whether you can book them.
I want to find YouTube channels that cover cold plunge and cold-water recovery. Run tl-keyword-research on it, deep mode, channel targets. Give it the topic and say what you want back. Leave either out and it asks.
Why a synonym list falls short
What people use it for
- A brand sizing a niche
-
how big is the home espresso topic on YouTube, and is it growing?
Prevalence numbers and the matching uploads by date.
- An agency building a target list
-
find channels for a retirement client, deep, channel targets
Tiered, context-validated channels with subscribers, price, and outreach email where on file.
- A creator-sourcing analyst
-
keywords that represent budget meal prep content
A filter set, and the report link showing where the list came from.
- Someone chasing a launch
-
make a topic for this week's product launch, run autonomously
A web lookup for the real product names, then expansion covering its siblings.
- A researcher writing it up
-
how common is each of these keywords?
Counts per keyword, ranked, with the scope stated.
How it works
Seven stages. Scripts do the deterministic work at no model cost; classification runs on small fast models in batches.
-
Stage 0: Set up
Your sentence is kept verbatim as the intent, since every later check is judged against it. Scope, operator and a breadth judgment are stated back before anything is spent.
One cheap probe asks whether a channel-identity version of the topic exists, or whether the market is channels that keep returning to it.
runs
expand_entities.py -
Stage 1: Expand
Each named entity expands into its family: company, product line, version, codename, and the sibling that shipped alongside. 8 to 15 candidates for a narrow niche, 30 to 50 for a multi-facet event.
A shallow synonym list is the biggest failure mode. Coverage is won or lost here.
-
Stage 2: Probe
One live query per candidate returns matching documents, distinct channels reached, and real samples. Recency rides the same query free, flagging terms that live off an old back catalogue.
Samples collapse to distinct channels, so one prolific creator cannot flood the evidence.
runs
probe.py -
Stage 3: Validate
Each keyword's samples are checked against your intent, and off-topic terms are dropped with the reason shown. At scale a batch classifier does it, with a completeness check that re-sends anything left out.
Relevance is judged from samples. Scope is your call, so those come back with snippets attached.
runs
select_keywords.py -
Stage 4: Refine
At least three rounds of recomposing the filter. Each measures coverage, scores fitness, records the query, and names its move: narrow, expand, or backtrack.
A move that reduces fitness is discarded and a different axis tried.
-
Stage 5: Materialize
One aggregation tiers every matching channel by how much of its output is the topic. Results are then built from the final filter verbatim.
The tier table is 2 to 3 queries however many channels match, so it runs before any per-channel spend.
runs
search_channels.py --intensity -
Stage 6: Deliver
Filter set, report link, results, and the Boolean expression. Anything pruned or translated is listed. Nothing is saved unless you say so.
runs
build_report.py
Every spelling is a different word
The index lowercases and splits on whitespace and punctuation, but does not split letter-digit runs and does not stem. One product name written four ways produces four sets of tokens.
| You write | Tokens | Matching videos |
|---|---|---|
fable 5 | fable 5 | 1,215 |
fable-5 | fable 5 | 1,215, identical to the spaced form |
fable5 | fable5 | 94 |
fable five | fable five | 118 |
fablefive | fablefive | 1 |
Four populations, one product. All-time counts, verified live in our index when the skill was written, so they drift as new videos land.
So anything with a number, version or model name is probed in every spelling, and
the survivors fold into one group. Inflections too, since nothing is stemmed:
invest, investing and investments are three terms.
When the model does not know the names
For a topic newer than the model’s knowledge, recently renamed, or thick with insider jargon, a web lookup runs first in an isolated context. It returns names only. Each then earns its place through the same probe and validation as any other candidate, and a hallucinated one probes to zero and drops.
The word is there. Is the topic?
Every probe returns two counts: total documents, and distinct channels. Judge a niche by the second, since one prolific creator can produce a thousand matches alone.
Samples are then read against your sentence. Two verified examples from one retirement run:
"social security"reaches 228 channels, a good share of them Brazilian pension-law firms. ExcludingINSSleaves 192.annuityreaches 596, including finance coursework:annuity due,ordinary annuity,present value. Excluding that cluster leaves 557.
Neither term is wrong, and neither problem is visible until you read what the term matched.
Whether matches are on topic is judged from evidence. Whether a sub-topic belongs in your scope is your call, so those come back with snippets and an in-or-out question.
Content fields
| Field | What it holds | Character |
|---|---|---|
title | The video title | Cleanest signal, weighted highest in ranking |
summary | The creator’s own description under the video | Main field for description text. Misleadingly named: not an AI summary |
transcript | The full spoken transcript, with timings | Widest reach, noisiest by far |
channel_description | The channel’s About text, indexed so whole domains stay single terms | Match a channel by what it links to, such as patreon.com |
channel_topic_description | A description of what the channel covers | Focused, but on only about a third of channels |
hashtags | The video’s hashtags | Catches handle-style spellings |
Ranking weights them title^4, summary^2, transcript^1. A term too noisy
corpus-wide is often precise in titles alone, so rather than drop it, the skill
probes per field and keeps the group with a field restriction attached. Fields are
set per group, not once for the filter.
Boolean queries a list cannot express
Every group is a self-contained Boolean query. Groups combine with OR; inside one you get required terms, alternatives and exclusions with real precedence.
Scope an exclusion to its own arm
A whole-filter exclusion hits groups that never had the problem. Inside its own group, it de-noises only the family that needed it:
("mythos 5" | mythos5) -ketoOn one live run this kept 51 on-topic documents a global exclusion had removed.
Guard against over-exclusion
Re-run the core with and without the exclusion; the count should barely move.
Excluding bare film from a Cannes Lions core cut it 24%, since on-topic content
shares the word. The phrase "film festival" cut 4%, so that is the one that ships.
Anchor a root too broad to use alone
A place name has no single polluter to cut. Require an anchor token plus a domain qualifier:
cannes +lions +(advertising | agency | campaign | "young lions") -"film festival"
"cannes lions" fires only when the words sit side by side; cannes +lions fires
when both appear anywhere, catching “Young Lions at Cannes”. The qualifier supplies
the precision, which bare cannes +lions lacks. Measured live, that group added
roughly 815 distinct channels beyond the phrase, around 80% on topic.
Judge a broad term on its residual
Probe the candidate with the core phrase excluded and read those samples. Relevance scoring otherwise floats covered documents to the top and hides how little is new.
Research operators never ship
* catches inflections, ~1 absorbs typos, "a b"~2 catches near-phrases. None
survive into a report filter, so variants are enumerated first: retire* becomes
(retire OR retiring OR retirement).
The grammar translation
A report link uses the uppercase words AND, OR and NOT; raw |, + and -
are literal text there. Groups are translated on the way out:
("fable 5" | fable5) -keto
("fable 5" OR fable5) AND NOT ketoEvery translation is listed, and an unsupported operator fails loudly. This is the most common way a hand-built filter breaks: the link looks right and is matching a literal plus sign.
Channels tiered by coverage
Few channels are entirely about any topic, so “channels about X” alone returns a near-empty list for most niches.
| Tier | What it means | Use it for |
|---|---|---|
core | Recurring, and at least half their output | The obvious targets, often a short list |
recurring | Three or more matching uploads | For a niche topic, the actual sponsorship market |
occasional | A couple of mentions | Trend math, usually the wrong target |
one_off | Touched it once | Trend math, almost never a target |
The top tiers are context-validated: the text around each keyword occurrence is classified on topic, mixed or off topic, with an evidence quote and confidence. Mixed channels are kept and labelled, only clear misses excluded, and the excluded list shown. Channels you cannot book are flagged, not filtered out.
If a topic has almost no core channels, you are told, with the recurring tier framed as the market. A near-empty list is never padded.
Run modes
| Mode | What runs | Rough cost |
|---|---|---|
| Quick | One pass: expand, probe, validate, deliver. Spelling variants, entity-family expansion and sample validation all still run | 10 to 20 credits |
| Deep | Everything above, plus 3 or more refinement rounds and full materialization with context validation | 60 to 120 credits |
Say which you want, or answer when it asks; it will not pick silently. Say run autonomously to skip every check-in, which implies deep with both result types. Spend is narrated at every stage transition. Report links are free, and so is asking the skill to explain itself.
Try it
uv tool install thoughtleaders-cli tl auth login tl setup claude
The skill arrives as a slash command. The full setup page covers other installers, headless machines, and the one-liners for Codex, Gemini CLI and Cursor.
Start on a topic you know well, so you can check the output against your own knowledge.
/tl-keyword-research "cold plunge" quick A single pass on a niche small enough to sanity-check yourself. Watch which terms it drops, and why.
Good next prompts:
how does tl-keyword-research work?for the built-in guide, freekeywords that represent budget meal prep content, quickfor a starter filterhow big is the GRWM trend on youtube right now? trend data onlyfor prevalence, no channel listfind channels covering Medicare for a retirement client, deep, channel targetsmake a topic for cannes lions, run autonomously, bothfor no pauses
Options, in plain words
| You say | What changes |
|---|---|
| ”quick” or “deep” | The run mode |
| ”trend data”, “channels to sponsor”, or “both” | Which results come back |
| ”run autonomously” | No check-ins. Implies deep, and both result types |
| ”include shorts and live” | Widens the longform-only default |
| ”newest first”, “biggest videos”, “since June” | Sorts and windows the trend feed |
| ”one video per channel” | Dedupes the feed to each channel’s best match |
| ”only channels that cover it repeatedly” | Focuses on the recurring tier. Default is 3 uploads; name a number to change it |
| ”title matches only” | Restricts a keyword to titles |
| ”exclude [word or sense]“ | Adds an exclusion, scoped so it does not over-cut |
| ”broaden it” or “narrow it to X” | Changes breadth mid-run |
| ”save it as a report” | Persists a named, shareable report |
| ”keyword counts” | The distribution table instead of the full pipeline |
Scope and limits
YouTube uploads only, longform by default. Shorts and live on request, and the scope in force is echoed back with every result.
Headline counts are all-time. Recency rides the same query, so a term living only in an old back catalogue is tagged stale.
There is no universal right result size. A few dozen channels is complete for a narrow niche and a miss for a broad one, so breadth is stated up front and measured at the end. If mining runs dry, a small result is reported as correct, not padded.
The corpus is the boundary. This searches what we index, titles, creator descriptions and transcripts across 1,302,318 tracked channels, not the open web. It is the same data our sponsorship matching runs on.