How we score keywords
Every keyword gets a composite score between 0 and 1. The formula is calibrated, transparent, and applied identically to every site. Here it is, with every lookup table and a full worked example.
Score = 0.25·CTR_gap
+ 0.15·Intent_norm
+ 0.25·SERP_Weakness
+ 0.25·Position_Accessibility
Actionable only if clicks_at_stake ≥ 3 / monthWorked example
Throughout this page we score a single real-world keyword end-to-end:
- Keyword
- échafaudage roulant 3m
- GSC position
- 12
- GSC CTR
- 0.008 (0.8%)
- Intent
- commercial
- GSC impressions
- 270 over 90 days (≈ 90 / month)
- Top-10 SERP
- 2 directories, 1 article (2022), no top-5 domain far above yours
CTR gap
weight: 25%Is the page under-performing the CTR its position predicts?
We compare the actual CTR reported by Google Search Console to the expected CTR for that position (Google FR benchmarks). Below 20 impressions the measured CTR is noise, so the expected CTR is used. The gap is normalized by the maximum possible gap — the expected CTR at position 1 — so it lands in [0, 1].
When actual CTR matches or exceeds expected, the gap is 0 — the keyword is already converting. When it's far below expected, the signal lights up: the snippet, title, or rich-result coverage is leaving clicks on the table.
| 1 | 0.30 |
| 2 | 0.20 |
| 3 | 0.15 |
| 4–5 | 0.08 |
| 6–10 | 0.04 |
| 11–20 | 0.015 |
| > 20 | 0.005 |
position = 12 → expected_CTR = 0.015
gap = max(0.015 − 0.008, 0) = 0.007
CTR_gap = 0.007 / 0.30 = 0.02
CTR_gap = 0.02Intent
weight: 15%Does the keyword express commercial or transactional intent?
Transactional and commercial queries drive revenue; informational queries drive traffic. We weight them accordingly using DataForSEO's intent classification. On content-driven sites (blog, media, SaaS, education, non-profit) an informational query is a lead, so it weighs 0.40 there. This is the smallest weight in the formula — intent modulates priority but never dominates it.
| informational | 0.00 (0.40 on content sites) |
| navigational | 0.25 |
| commercial | 0.70 |
| transactional | 1.00 |
intent = commercial → Intent_norm = 0.70
Intent_norm = 0.70SERP weakness
weight: 25%How weak is the top-10 competition?
A SERP dominated by directories, comparison sites, outdated articles, or pages whose title covers less than half of the query is a vulnerable SERP. We scan the top 10 and sum signed weights — capped to [0, 1]. Authority is relative: a top-5 domain whose backlink rank (DataForSEO, 0–100) exceeds yours by more than 35 subtracts from the score — it is a wall for your site, not for a stronger one. Local packs and video carousels are not counted: no page displaces them (a local pack is a Google Business Profile lever, and we say so in the recommendation).
| Directory / compare-sites | +0.25 |
| Article > 2 years old | +0.15 |
| Title covers < half of the query | +0.10 |
| Top-5 domain rank > your rank + 35 | −0.15 |
+0.25 (directory #1)
+0.25 (directory #2)
+0.15 (article from 2022, > 2 years)
────────────────────────
SERP_Weakness = 0.65
SERP_Weakness = 0.65Position accessibility
weight: 25%How reachable is the top-3 from the current position?
Page 1 positions 4–10 are the sweet spot: on-page work alone is usually enough to climb. Position 1 has no upside left; positions 2–3 still do (3 → 1 doubles the clicks), so they sit in between. Positions > 50 are ignored for short-term triage — they require backlinks or new content.
| position 1 (already won) | 0.20 |
| position 2–3 (partial upside) | 0.60 |
| position ≤ 10 (sweet spot) | 1.00 |
| position ≤ 20 (page 2) | 0.80 |
| position ≤ 50 (needs backlinks) | 0.40 |
| position > 50 (out of reach) | 0.10 |
position = 12 → 12 ≤ 20 → Position_Accessibility = 0.80
Position_Accessibility = 0.80Clicks at stake
weight: gateIs the prize worth the work?
The four signals say how winnable a keyword is, not how much it is worth. So we size the prize: the extra clicks per month if the page reached the top 3 (or #1 from inside the top 3), from monthly impressions — or search volume when Search Console is not connected. A keyword promising fewer than 3 clicks a month stays in Monitor, whatever its score. The feed is sorted by this number.
demand = 270 impressions / 3 months = 90 / month
target = top 3 → expected_CTR = 0.15
clicks = 90 × (0.15 − 0.008) = 12.8
Clicks at stake ≈ 13 / monthComposite score
Multiply each normalized signal by its weight, read the result against the tier thresholds, and check the clicks at stake.
Score = 0.25·0.02
+ 0.15·0.70
+ 0.25·0.65
+ 0.25·0.80
= 0.47Score Breakdown
A score of 0.47 with about 13 clicks a month at stake lands in the Opportunity tier — plan for it, not immediate. The thresholds, fixed in product logic (Quick Win and Opportunity also need ≥ 3 clicks/month at stake):
| score ≥ 0.50 | Quick Win — act this week |
| score ≥ 0.30 | Opportunity — plan for it |
| score ≥ 0.15 | Monitor — watch it |
| score < 0.15 | Not actionable — ignore |
Calibration
The weights and lookup tables were calibrated on March 25, 2026 against the level-echafaudage.com dataset (DR 5, FR market, 1,200+ ranking keywords). The formula is identical for every site we score — we do not tune per-account.
Version 3 (October 8, 2026): replayed on 579 live keywords. The effort term was removed (it only ever took two values), authority became relative to your own domain, local packs and videos stopped counting as weakness, positions 2–3 regained their upside, and the clicks-at-stake gate was added.
Data sources: Google Search Console (real CTR and position via read-only OAuth), DataForSEO (SERP composition, search volume, intent classification, content age, backlink rank). No third-party scoring black-boxes.
AI Overview penalty: when the SERP contains an AI Overview block, the composite score is multiplied by 0.85 — a 15% haircut reflecting the click suppression we measured on impacted queries.
The scoring functions are deterministic and pure. Same inputs, same score, always.
Run your own site through this formula
Drop a domain in — we'll score every keyword using the exact formula above and show you the Quick Wins, Opportunities, and At Risk pages in under a minute.
Run your audit →