We Collated Our Own Keyword List. It Got Shorter.
Operator reads of our keywords list: 405 rows (2026-08-05) became 291 (2026-08-20). Token-signature grouped duplicates; similarity folded ahrefs with ahrefs ai.
Article highlights
- Estimated reading time: 8 minutes
- Published on: August 26, 2026
- Last updated: August 26, 2026
Article
On 2026-08-05 the keywords list for trustgrowth.ai had 405 rows and variant_count 0 on every row. After we ran collation on that same site, the 2026-08-20 read showed 291 rows and 53 canonicals with a variant badge. This is a two-point operator case study of that run: which merges were mechanically honest, which were not, and what the shorter list does not mean.
It is not a customer case study and not a claim about other tenants. The public proof page is the standing score surface; this piece is a keyword-list read, not a score claim.
Context
Before collation, every near-duplicate sat on its own row. "surfer ai" and "ai surfer" were separate. So were "all in one seo software" and "all-in-one seo software", and "se ranking vs semrush" versus "semrush vs se ranking".
A practitioner working the list top to bottom could not tell how many of those rows were the same intent. Row count no longer tracked distinct opportunity count.
That is the operator problem collation is supposed to solve: fewer rows on the surfaces that honour a canonical, with a badge when a canonical has absorbed variants, and a combined volume when those variants carry their own volume numbers.
One boundary up front: collation is not a spend reduction. Variants still get enriched. Volume, difficulty, and downstream generation still run against each underlying string. What changes is list legibility on the surfaces that honour canonical grouping. If you are tracking spend per keyword string, do not expect this job to move that number.
Method
We measured one surface: the canonical-scoped keywords list for trustgrowth.ai.
-
Data source:
GET /api/v1/sites/trustgrowth/keywords(v1 operator read). -
Sample: every not-dismissed row until
pagination.total_countwas covered. Page sizeper_page=100. A single page is not the corpus. - Filters: none beyond the list default (not-dismissed, canonical scope). We did not pass a dated snapshot parameter; the endpoint does not accept one.
- Tooling: paginated list only. Token-signature was reproduced by hand in Python (code under Changes shipped). Trigram merges were identified by exclusion: grouped pairs whose signatures differ.
-
Fields received:
keyword,volume,combined_volume,variant_count, plus ranking metadata this piece does not use. -
Fields not on this API: a
variantsarray, amatch_type/ rung label, a historicalas_offilter.
Read dates: 2026-08-05 (five pages, 405 rows) and 2026-08-20 (three pages, 291 rows). Rung labels later in this report come from two places only: the collation dry-run that proposed the groups, and reproducing token-signature by hand. If a later reader cannot see match_type on the list, that is expected.
Changes shipped
Canonical grouping runs two rungs, and they fail in different ways.
Token-signature. Normalize the string — lowercase, strip punctuation, sort tokens — and group exact signature matches. This catches word-order swaps, hyphenation, and "vs" reversals. Two strings either share a signature or they do not. There is no partial credit, which is why this rung is the safer of the two: it will under-group before it invents a relationship.
Trigram similarity (pg_trgm). Separately, pairs that clear a similarity threshold are grouped even when their token signatures differ. PostgreSQL documents this as the pg_trgm trigram matching module (PostgreSQL docs, retrieved 2026-08-20). That catches near-misses token-signature would leave apart. It can also fold together strings that are lexically close and semantically distinct. That is the expensive failure: a high-volume canonical absorbs a different intent, and the list gets shorter in the wrong place.
An audit of any merge has to name which rung produced it.
You can reproduce the safe rung without any product internals:
import re
def token_signature(phrase: str) -> str:
tokens = re.findall(r"[a-z0-9]+", phrase.lower())
return " ".join(sorted(tokens))
token_signature("surfer ai") # "ai surfer"
token_signature("ai surfer") # "ai surfer" — same; token-signature can group these
token_signature("ahrefs") # "ahrefs"
token_signature("ahrefs ai") # "ahrefs ai" — different; this pair is not token-signature
The tokenizer is re.findall on [a-z0-9]+ (Python 3 re docs, retrieved 2026-08-20).
If two strings share a signature, a token-signature merge is at least mechanically honest. If they do not, and they still grouped, the merge came from similarity.
Results
We measured the live keywords list on two dates. Sample: all not-dismissed rows returned by the paginated list (total_count on the last page).
variant_count 0 on 405/405)
—
2026-08-20
291
53
−114 rows on this surface
Units: row counts of not-dismissed keyword opportunities on the canonical-scoped keywords list. Source: operator reads of GET /api/v1/sites/trustgrowth/keywords, 2026-08-05 and 2026-08-20. Public corroboration of the after count: the trustgrowth.ai proof page reports keyword_count 291 (score date 2026-08-19). Per-keyword volume and combined_volume are operator-list fields from 2026-08-20 and are not on that public page.
On 2026-08-20 the variant_count distribution was:
Units: count of canonical rows with that variant_count. Source: same 2026-08-20 operator read.
53 = 39+10+4. 238 of 291 rows (82%) still have variant_count 0. The shortening is concentrated: 53 of 291 rows (18%) carry a variant badge (public proof keyword_count 291). A "shorter list" story that only quotes 405→291 hides that shape.
No underlying query disappeared from the corpus; 114 rows were merged under canonicals. Groupings formed, not keywords deleted. This is a row-count change on the keywords list, not a claim about opportunity volume across the product.
Clean groups: token-signature
Three pairs from the 2026-08-20 read match the token-signature rung:
- surfer ai (search volume 1,600/month, TrustGrowth keywords list, 2026-08-20) with ai surfer — same two tokens, reordered.
- all in one seo software with all-in-one seo software (search volume 880/month, same list and date) — hyphenation that disappears once punctuation is stripped.
- se ranking vs semrush with semrush vs se ranking — a comparison reversal that resolves to the same token set.
Those groupings are defensible: same intent, same likely SERP, mechanical match. On this sample, token-signature did not produce a false merge. If you are going to ship a "we show fewer opportunities on purpose" sentence, these are the examples that sentence is allowed to rest on.
The miss: name the rung
ahrefs (search volume 40,500/month, TrustGrowth keywords list, 2026-08-20) shows variant_count 2 and combined_volume 81,320. The dry-run proposed grouping it with ahref and ahrefs ai.
"ahrefs" and "ahrefs ai" do not share a token signature — different token counts — so that pair is not token-signature. It is a trigram-similarity merge: the strings are close enough to clear the threshold despite distinct intent. "ahrefs" is a tool-name query. "ahrefs ai" is a feature query. Folding them hides a real decision behind a shorter row.
A second row shows the volume effect of folding, without a live match-type label: surfer seo ai humanizer has search volume 27,100/month, variant_count 2, and combined_volume 55,080 (same list and date). The gap is variant volume sitting on the canonical. We do not have a live API field proving that row's rung; treat the combined-volume inflation as observed, and the rung as unverified.
Over-grouping matters because a high-volume canonical that absorbs a different intent leaves the practitioner with one row where two decisions should have been made. That is worse than leaving two near-duplicates visible. That limitation belongs to the similarity rung, not to token-signature.
What we cannot attribute
Named confounds on this design:
- Live two-point read. The list has no snapshot parameter. Keyword imports, dismissals, or enrichment between 2026-08-05 and 2026-08-20 are not isolated. The 114-row drop correlates with collation; this is not a controlled experiment.
- Canonical-scope confound. "Fewer opportunities" is true on read surfaces that honour canonical scope. Other surfaces, including next actions, can still serve ungrouped variants.
-
Rung-label confound. The live list has no
match_type. Similarity versus token-signature is inferred from the dry-run plus hand-reproduced signatures. Combined-volume on surfer seo ai humanizer is observed; that row's rung is not verified from the live list. -
Volume confound.
combined_volumesums variant volumes onto the canonical. It is not independent demand, and it is not a quality score. - Site confound. trustgrowth.ai only.
-
Count-mismatch confound. On 2026-08-20,
variant_countsums to 71 (39×1 + 10×2 + 4×3). The two-point row delta is 114 (405→291). Those are different measurements: badges on remaining canonicals versus list-size change. - Spend confound. The 114-row drop is not an enrichment-cost reduction. This report does not measure rankings, traffic, conversions, or spend.
Public identity for this company is first-party data and weak parts left public — the same posture as how we keep the score honest. Publishing a dedupe thesis we had never run on our own corpus would have been the one hypocrisy the brand cannot afford. The run happened. The miss is part of the result.
Common questions
Does a shorter keyword list mean fewer opportunities? On the keywords list, yes: 405 rows on 2026-08-05 became 291 on 2026-08-20 because near-duplicates grouped under canonicals. That is not uniformly true across the product. Next actions can still serve ungrouped variants.
Does collation reduce enrichment cost? Not on this evidence. Variants still get enriched. A shorter list is a legibility change on canonical-scoped reads, not a spend claim.
What is the difference between token-signature and trigram matching? Token-signature groups exact normalized token sets (word order, hyphenation, vs-reversals). Trigram similarity (pg_trgm) groups strings that clear a fuzzy threshold even when token sets differ. The ahrefs / ahrefs ai miss is the second rung, not the first.
Did collation delete keywords? No. 114 rows were grouped under canonicals. The underlying strings remain in the corpus.
Does the public proof page show these per-keyword volumes? No. The proof page reports keyword_count (291 as of score date 2026-08-19). Per-keyword volume is an operator-list field, not a public ranking URL.
What to copy if you run the same audit
- Page the full list. Page one is a sample. Our 2026-08-05 first page was 100 rows, all
variant_count0; the full 405-row read confirmed it. - Pull a
variant_countdistribution, not just a row-count delta. 238/39/10/4 tells you concentration. - When a merge looks wrong, reproduce token-signature by hand before judging it. If the signatures differ, the merge came from similarity.
- Spot-check high-volume canonicals. "ahrefs" vs "ahrefs ai" is the expensive miss.
- Scope "shorter list" to the surface you actually read.
- Do not translate a shorter list into an enrichment-cost or spend claim without a separate measurement.
Know your site's real SEO score
Free GSC-verified audit, E-E-A-T scoring, and AI-powered content strategy.
Get Started Free