understand · market research
Channel analysis and white space
Where competitors find customers, and the gaps.
In Market research
For each competitor, check twelve channels and mark how hard they work each one. A channel nobody works, in a place your buyers gather, is white space: an open lane. A channel everyone works heavily is a fight that needs a different angle.
Check, don't assume.
Every cell is heavy, present, absent or unchecked. Unchecked is shown as a question mark, never filled in.
White space needs buyers.
An empty channel only matters if your buyers gather there. Empty and buyerless is just empty.
Read columns, not rows.
The decision comes from looking down a channel across all competitors, not at one competitor's profile.
what it is
Channel mapping, in industry terms
Industry names: channel analysis, distribution audit, white-space analysis (from strategy work), sometimes competitive channel mapping. The output is a matrix: competitors down the side, channels across the top, and a mark in each cell for how hard that competitor works that channel.
It answers one question for the founder: where can I show up without competing head-on with someone who spends more? The answer feeds which playbooks run first and which detector sources to add.
Heavy — works it hard · regular, recent output: a library of pages, weekly posts, an active community.
Present ◐ — exists · a page or account exists but isn't worked.
Absent · — checked, not there · looked for it, found nothing.
Unchecked ? — not yet · nobody has looked; never guessed.
White space — open lane · a column of absents in a place your buyers gather.
Red ocean — crowded lane · a column of heavies: compete only with a different angle.
how it works
Filling the matrix and reading it
Fill one cell at a time from public evidence. Then read down each column. The order of play comes from the columns, weighted by where buyers actually are.
- List competitors — all four kinds; at least the direct and alternatives
- Check each channel — 12 channels, the check for each in the catalog
- Mark the cell — heavy, present, absent, unchecked, with evidence
- Read the columns — count heavies per channel across competitors
- Overlay the buyers — watering holes from the brief and the interview
- Name the lanes — white space where buyers gather; fights to avoid
- Pick plays — playbooks for the open lanes, first
- Re-check monthly — and when a competitor launches or reprices
- List competitors — all four kinds; at least the direct and alternatives
- Check each channel — 12 channels, the check for each in the catalog
- Mark the cell — heavy, present, absent, unchecked, with evidence
- Read the columns — count heavies per channel across competitors
- Overlay the buyers — watering holes from the brief and the interview
- Name the lanes — white space where buyers gather; fights to avoid
- Pick plays — playbooks for the open lanes, first
- Re-check monthly — and when a competitor launches or reprices
the object
A channel cell
One row per competitor per channel. The matrix is a view over these rows; the evidence lives on the row so any cell can be hovered and checked.
channel_cell
| field | type | what it holds |
|---|---|---|
competitor | id | which profile |
channel | enum | one of the 12 channels |
level | enum | heavy, present, absent, unchecked |
evidence | text | what was seen: page count, post cadence, member count |
source_url | url | where it was seen |
checked_at | date | when |
checked_by | enum | founder, agent, research run |
sample
{
"competitor": "OpenTweet",
"channel": "free_tools",
"level": "heavy",
"evidence": "20+ free tools: tweet generator, shadowban checker, character counters, viral checker",
"source_url": "https://opentweet.io",
"checked_at": "2026-10-13",
"checked_by": "research run"
}And the lane it produces
| field | type | what it holds |
|---|---|---|
channel | enum | the column |
heavy_count | int | competitors working it hard |
checked_count | int | how many cells are actually checked |
buyers_here | bool + evidence | do your buyers gather here (from the brief) |
verdict | enum | open lane, fight, skip, unknown |
plays | list | playbooks that work this lane |
sample
{
"channel": "launch_sites",
"heavy_count": 0,
"checked_count": 0,
"buyers_here": true,
"verdict": "unknown",
"plays": [
"launch-window",
"community-answers"
]
}channel catalog
The twelve channels and how to check each one
Grouped by the kind of channel: owned (you build it), social (you show up), borrowed (someone else's audience) or paid.
owned
SEO content
guides, glossaries, templates
- check
- search site:theirdomain.com; read their footer and sitemap
owned
Free tools
calculators, generators, checkers
- check
- their footer's tools section
owned
Comparison pages
'vs' and 'alternative to' pages
- check
- search 'theirname vs' and 'alternative to theirname'
social
Own social
the company account
- check
- post frequency and replies over the last month
social
Founder account
the founder posting as themselves
- check
- the founder's profile; building in public?
social
Community
Discord, Slack, subreddit
- check
- links in their footer; member count
borrowed
Launch sites
Product Hunt, Uneed, PeerPush, Show HN
- check
- search each site for their name and dates
borrowed
Directories and stores
app stores, marketplaces, 'best tools' lists
- check
- search their name plus 'directory'
borrowed
Integrations
partner marketplaces, plugins, APIs, MCP
- check
- their integrations or developers page
paid
Referral and affiliate
paid referrals, partner programs
- check
- a 'referral' or 'affiliates' page
paid
Paid ads
Meta, LinkedIn, Google
- check
- Meta Ad Library, LinkedIn Ad Library, Google Ads Transparency Center
paid
Sponsorships
newsletters, podcasts, YouTube
- check
- search their name with 'sponsored by'
failure modes
How it goes wrong, and how to catch it
Filling unchecked cells — A blank becomes 'absent' because nobody looked. · Catch it: unchecked is its own value and renders as ?.
Counting, not weighting — A channel with no competitors but no buyers looks like an opportunity. · Catch it: a lane needs buyers_here with evidence from the brief.
One-time map — A competitor starts a community; the map still says open. · Catch it: monthly re-check, plus immediately on a launch, shutdown or price change.
Surface-level 'heavy' — One old blog post marked heavy. · Catch it: heavy needs recent, regular output; record the cadence as evidence.
data to capture
Record it so a model can learn from it later
Every decision on this page is training data if it is recorded in the guide's shape from day one.
1 · log the decision · 2 · version whatever decided · 3 · freeze the inputs · 4 · keep the negatives · 5 · log the odds · 6 · every human touch is a label · 7 · one chain of ids · 8 · keep the raw
record
- every cell with level, evidence, source and checked_at
- every lane verdict and the plays chosen for it
- each play's results on that lane (signals, replies, signups)
label
per lane verdict: did plays on an 'open lane' beat plays on a 'fight' lane, per hour of founder time
trains
a lane-ranking model that predicts which channels pay off for a given ICP, from many founders' maps and results
test
- knob: which lane gets the first playbook
- mode: randomized order across founders with similar ICPs (later, when there are several accounts)
- win rule: waitlist joins or signups per founder hour in the first four weeks