Research & strategy Independent solution

Keyword & SERP Intelligence

Feed it a seed topic and it returns intent-clustered keywords, a map of who owns the SERP, the exact content gaps versus competitors, and a ranked content calendar — the strategy work that usually takes an analyst a week.

The problem

Keyword research produces spreadsheets, not decisions

Teams export thousands of keywords and then stall. Which ones share intent? Which are winnable given domain authority? Where are competitors weak? Answering that by hand is slow, subjective, and stale the moment the SERP shifts.

This solution turns raw keyword data into a prioritised plan you can hand straight to writers.

Primary objective
Convert keyword noise into a ranked, intent-aware content roadmap.
How it works

Expand → cluster → analyse SERP → prioritise

Seed & expand
Pull volume, difficulty & related terms
Intent cluster
Embeddings group terms by search intent
SERP analysis
Who ranks, content type & gap detection
Prioritised plan
Opportunity score → content calendar
What it does
  • ✓ Intent-based keyword clustering
  • ✓ Competitor gap analysis
  • ✓ Opportunity & winnability scoring
  • ✓ SERP feature detection (PAA, snippets)
  • ✓ Cannibalisation warnings
  • ✓ Auto-generated content calendar
Built with
  • ✓ Embeddings for semantic clustering
  • ✓ Claude for intent labelling & briefs
  • ✓ Keyword & SERP data APIs
  • ✓ Vector store for topic maps
  • ✓ Sheets / Notion / Airtable export
Feeds into
  • ✓ SEO Content Engine (briefs)
  • ✓ Social Media Autopilot (topics)
  • ✓ Ad Copy Optimizer (angles)
  • ✓ Weekly refresh as SERPs move
Under the hood

Semantic intent clustering

Group thousands of keywords by what the searcher actually wants, then score each cluster for opportunity.

intel/cluster.py PYTHON
import numpy as np
from sklearn.cluster import AgglomerativeClustering
from embed import embed_batch      # -> unit-norm vectors

def cluster_by_intent(keywords: list[str], threshold: float = 0.35):
    vecs = embed_batch(keywords)                # semantic, not string, match
    model = AgglomerativeClustering(
        n_clusters=None, metric="cosine",
        linkage="average", distance_threshold=threshold,
    )
    labels = model.fit_predict(vecs)
    clusters: dict[int, list] = {}
    for kw, label in zip(keywords, labels):
        clusters.setdefault(int(label), []).append(kw)
    return clusters

def opportunity_score(volume, difficulty, our_da) -> float:
    # reward reachable, high-volume clusters; punish out-of-reach ones
    reach = max(0.0, (our_da - difficulty) / 100)
    return np.log1p(volume) * reach
Outcomes
Weeks→hrs
Strategy turnaround
1000s
Keywords clustered per run
Ranked
Calendar by opportunity
Weekly
Auto-refresh as SERPs shift

Turn keyword data into a plan

Standalone, or paired with the Content Engine for research-to-publish in one flow.

Start a conversation →
More SEO & Marketing solutions
Keyword & SERP Intelligence | Smort