Diagnose a traffic drop
From "clicks are down" to a named cause per query - and the different action each cause implies.
Use this when clicks fell and you do not yet know why. The point of the sequence is that a drop in clicks looks the same whatever caused it, so the cause has to be attributed before any work is chosen: a rank loss, a CTR loss and a fall in demand each want a different response, and one of them wants no response at all.
get_site_snapshot - confirm the drop is
real and get its size, per engine. A fall on one engine only is a different story
from a fall on both.
get_performance_trend - find when
it happened. A weekly or monthly series separates one step down from a slow slide;
a window-over-window comparison cannot.
diagnose_traffic_losses - for the
queries that lost the most clicks, the cause. It locates the period the series
actually stepped and decomposes around that, rather than across calendar windows,
because a mid-window rank drop is smeared by a window average and its impressions
loss then reads as falling demand.
Act on the class, not the number - the classes carry the whole answer:
- A ranking - outranked in place. Strengthen the page;
get_query_pagestells you which page held the slot. - A′ page swap - a different page of yours took the slot. Consolidate rather
than update;
detect_keyword_cannibalizationnames the survivor to keep. - B CTR - ranking intact, clicks gone. The cheapest fix in the set: title,
meta, schema.
find_ctr_opportunitiesfinds the rest of them. - C visibility - impressions gone, ranking intact, demand ruled out. No search-console feed exposes what else was on the page, so this one needs the live SERP (next step).
- D - a rank loss across the page-one boundary. The impressions followed the ranking; never report it as demand.
- E demand - fell on both engines with position flat. Nothing to fix.
explain_query_serp on a case C (or case
B) query - fetches that query's Google SERP live and diffs it against the newest
one stored for the workspace, which is how an AI Overview, a new entrant or a
rewritten competitor title becomes visible. This costs money on every call and
is capped per workspace per day, so run it on the queries the previous step
flagged rather than sweeping a keyword list.
Reading the result honestly
Case E supports a narrower claim than it looks
A case E row supports "fewer people searched this phrasing", not "fewer people searched for this" - nothing in the diagnosis looks at neighbouring queries, so a reformulation is indistinguishable from a real fall in demand. And "this is demand, not you" is a useful result rather than a failure: it stops a content cycle being spent on a page that is fine.
Two more things specific to this recipe:
- The row ceiling matters more here than anywhere else, because this tool
attributes a cause. A period Google truncated is an impressions fall with
nothing behind it, and the cross-engine control does not catch it either - a
query missing from both feeds looks like two engines agreeing. Read
unsupportedInputsbefore reporting a cause. - A baseline can be absent. In
explain_query_serp,baselineCapturedAt: nullmeans nothing was stored to compare against, so the movement lists are empty for want of a baseline - not because nothing changed. Only the workspace's roughly 100 weekly-captured queries have one; outside that set (isTracked: false) your first call establishes it.