Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions web/content/marketing/library/keyword-ranking-report.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
title: "The keyword ranking report your CEO will read"
description: "A table of positions is not a report. Lead with the number the business tracks, group the movement into four buckets, explain the three rows that caused it, and say what happens next. One page, every week."
---

## What should a keyword ranking report show?

The number the business already cares about, first, then rankings as the explanation for it. Most ranking reports do this backwards. They open with a table of keywords and positions, sometimes with green and red arrows, and leave the reader to work out whether anything in it matters. The reader is usually someone who does not do SEO, has ten minutes, and needs to decide whether to keep paying for this. A table does not help them decide.

Grant Simmons, who ran search at Homes.com and now works with Fiat Growth, drew the line when we were talking about a well-liked Search Console tool:

> it's still not reporting. It's insights.

![A quote card reading: It's still not reporting. It's insights. Attributed to Grant Simmons of Fiat Growth, formerly Homes.com, from The Unscripted SEO Interview Podcast.](/library/rank-tracking/quote-not-reporting-insights.png "Grant Simmons on reporting versus insights")

Insights are what a tool gives you. A report is what you give someone who has to make a decision with it. His full conversation on measurement is [on the Unscripted SEO podcast](https://unscriptedseo.com/grant-simmons-on-entity-seo-llms-and-the-future-of-search-visibility/). The structure below is built to be the second thing.

## The structure

### 1. One number, and what it did

Open with the metric the business tracks, for the pages the tracker covers, against the previous period. Clicks from Search Console if that is what you have; leads or revenue on those pages if analytics is connected. One sentence: "Organic clicks on the twelve service pages we track were 1,240 this month, up from 980." That sentence is the report. Everything after it is support.

![OpenSEO Search Console report for seoarcade.com, last 28 days against the previous period: clicks, impressions, click-through rate and average position with the change, then clicks, impressions, CTR and position by page](/library/rank-tracking/search-console-clicks-by-page-openseo.png "Search Console clicks by page in OpenSEO")

Do not open with average position across all tracked keywords. It is a mean of unrelated things, it moves when you add a keyword, and nobody outside SEO knows whether 11.4 is good.

### 2. Movement in four buckets

Rankings come next, as counts rather than rows. Of the keywords tracked this period:

- how many entered the top three
- how many entered page one
- how many dropped off page one
- how many did not move

Label the comparison period next to these counts. The OpenSEO MCP currently compares ranks against a seven-day baseline, falling back to the earliest available snapshot when history is sparse. In a monthly report, present this as the latest weekly movement alongside the monthly click totals. It is not a month-over-month ranking comparison.

### 3. The three rows that explain the number

Now the table, cut to three rows: the biggest gain, the biggest loss, and the row where the position held but the clicks changed. Show keyword, position, previous position, ranking URL, and what is on the page.

The third row is the one that earns the report its credibility. When a term holds position 4 and loses half its clicks, the reason is almost always something Google put above it: an AI overview, a local pack, a video block. A tracker that records SERP features shows it in a column, and a report that names it turns "clicks fell, not sure why" into "clicks fell because Google added an answer box, and here is what we do about it".

### 4. Brand and non-brand, separately

Split the tracked list and the clicks into brand and non-brand before you draw any conclusion. Brand terms rise when the company does marketing of any kind, and a report that counts them as SEO wins will get found out at the first hard question. Charlie Birch, founder of Humanize Collective, on what the number is supposed to be for:

> the result that you ultimately want is not search volume, it's conversion and retention

The non-brand line is the one SEO can claim. Report it on its own, even when it is the smaller number. Especially then. Expect the query rows to add up to less than the page total: Search Console withholds a share of queries for privacy, so some clicks on every page belong to queries you will never see. Say so in a footnote rather than letting the reader find the gap. [The Dark Query Problem](/blogs/dark-queries) covers how large that share is and how to read around it. Her episode is [here](https://unscriptedseo.com/charlie-birch-on-where-brand-strategy-meets-seo-what-every-founder-needs-to-know/).

### 5. AI answers, with the caveat attached

If you report visibility in AI assistants, say what the number is. Brittany Trafis, founder of Soarion Digital, on the tools that monitor it:

> It is a monitoring tool. It is directional. do not think this data is Google Search Console level data. It is nowhere close

Put the row in, label it directional, and do not let it sit next to the click count as if it were the same kind of fact. Her episode on treating AI search as its own channel is [on the podcast](https://unscriptedseo.com/brittany-trafis-ai-search-is-not-seo-2-0-unscripted-seo-podcast/).

### 6. What we did, what we will do

Two short lists. The work that shipped this period, and the work planned for next, each tied to a row in section 3 or a bucket in section 2. This is the section that gets the budget renewed, because it connects the numbers to decisions someone made.

## What to leave out

The full keyword table goes in an attachment, not the body. Anyone who wants it can open it; putting it in front of the reader costs the attention you need for section 1.

Year-on-year comparisons need a warning label now. Google's results pages changed enough between 2024 and 2026 that a query's clicks last year and this year are often not the same kind of number, because the page they came from had a different shape. Compare periods, name what changed on the SERP in between, and resist the chart that makes it look continuous.

And leave out any score you cannot explain in a sentence. A "visibility index" invites a conversation about how it is calculated instead of a conversation about what to do.

## Run this with the OpenSEO MCP

Connect Search Console to the project and the [OpenSEO MCP](/docs/mcp) to your assistant. The tracker read and the Search Console read use no credits, so the report itself is free to produce once the tracker has run.

```text
Using the OpenSEO MCP on project [name], write this month's ranking
report for [company].

1. Call get_rank_tracker to list trackers, then read the relevant
ones with trackerId. Pull every tracked keyword with position,
previous position, and ranking URL. Label this section "Latest
weekly ranking movement": the comparison uses a seven-day
baseline, with an earliest-available fallback for sparse history.
Do not present it as monthly movement or assume a full week of
history when that is not established.

2. Pull Search Console performance for the last 28 days and the 28
days before, by page, filtered to the URLs from step 1. Give me
total clicks for both periods. That is the first sentence.

3. Bucket the keywords: entered top 3, entered page 1, left page 1,
unchanged. Four counts.

4. Show me three rows: the largest position gain, the largest loss,
and the keyword where position moved by 2 or less but Search
Console clicks on its URL changed by more than 30%. Include SERP
features for that third row.

5. Pull Search Console query data for the same two 28-day periods,
filtered to the same URLs from step 1. Split reported queries into
brand (containing "[brand]") and non-brand. Report non-brand clicks
separately. Note that query totals can omit anonymized queries
and differ from page totals.

6. Do not compute an average position across keywords. Do not
invent a score. Put the full table in a separate block at the end.
```

Step 4 is the only step that needs judgement, and the prompt hands it a rule instead. Adjust the thresholds to your site, but keep the rule written down so the report is consistent month to month.

## A report is a request for a decision

Every ranking report is asking the reader to do something: keep funding this, approve that fix, accept that a term is lost. Write it so the request is visible in the first sentence and supported by the fourth section, and the tracker underneath it becomes the most useful thing in your stack rather than the most ignored. If you have not built the tracker yet, [which keywords to track](/library/rank-tracking/which-keywords-to-track) is where to start.

## Ranking report FAQ

### What should an SEO ranking report include?

The business metric for the tracked pages against the prior period, ranking movement as four counts (entered top 3, entered page 1, left page 1, unchanged), the three rows that explain the movement with SERP features noted, a brand and non-brand split, and a short list of work done and planned. The full keyword table goes in an attachment.

### How often should I send a ranking report?

Monthly for most businesses, weekly if a launch or migration is in progress. The tracker can check daily; the report should not, because week-to-week ranking noise is real and reporting it trains the reader to ignore the report.

### Should a ranking report show average position?

Not across all keywords. It is a mean of unrelated queries, changes whenever the list changes, and means nothing to a non-SEO reader. Report positions per keyword for the few rows that matter and movement counts for the rest.

### How do I explain a ranking drop to a client or manager?

Name the keyword, the previous and current position, the URL, and what is now on the results page, then say what you are doing about it. If the position held and clicks fell, show the SERP feature that took the click. A drop with a cause and a plan is a normal report; a drop with neither is a problem.

### Can OpenSEO generate a ranking report?

It provides the pieces: tracked positions with previous positions and SERP features, Search Console clicks by page and query at no credit cost, and an MCP so an assistant can assemble the report from a prompt like the one above. It does not produce a composite score, on purpose.
112 changes: 112 additions & 0 deletions web/content/marketing/library/local-rank-tracking.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: "Local rank tracking: your position depends on where the searcher is standing"
description: "For a local business there is no single rank, only a rank at a point on the map. A nine-point grid around one Tennessee service company showed four different businesses holding number one, and the company itself nowhere in the set."
---

## Why a local business cannot have one rank

Ask Google for a plumber from the north side of a town and from the south side, three kilometres apart, and you get two different map packs. Neither is wrong. Google weights proximity heavily for local queries, so the answer moves with the searcher, and a rank tracker that checks from one fixed point reports one of the many answers as if it were the answer.

Melissa Popp, content strategy director at Rickety Roo, states the rule most local SEOs work from:

> we know proximity and relevance are two of the most important factors for how you show up in map pack as a local business

![A quote card reading: Proximity and relevance are two of the most important factors for how you show up in the map pack as a local business. Attributed to Melissa Popp, content strategy director at Rickety Roo, from The Unscripted SEO Interview Podcast.](/library/rank-tracking/quote-proximity-and-relevance.png "Melissa Popp on proximity and relevance")

Her episode on fixing your Google Business Profile before anything else is [on the Unscripted SEO podcast](https://unscriptedseo.com/melissa-popp-go-fix-your-google-business-profile/). The implication for tracking is that a local business needs its position measured from several places, not one, or the number will describe the tracker's location rather than the customer's.

## What a nine-point grid showed

Here is the shape of the problem on a real business: an HVAC and plumbing company in a mid-sized Tennessee town. I ran a three-by-three grid, nine points three kilometres apart, centred on the town, on mobile, for two queries.

For `plumber cookeville tn`, the number one result was a different business depending on the point. One plumber held the top spot across the north and west, a larger plumbing, heating and cooling company held the centre and the south, a third business took the east and south-east, and a fourth appeared at a single north-east point. Every point returned 18 to 20 results.

![OpenSEO local rank grid for plumber cookeville tn: nine points three kilometres apart, with a different business at number one across the north-west, the centre and south, the east, and the north-east, and the target business matched at none of them](/library/rank-tracking/local-rank-grid-cookeville-openseo.png "Local rank grid in OpenSEO")

For `hvac repair cookeville`, the split was cleaner: one company held number one at seven of nine points and a second company took two of the three points along the southern edge.

So over a six-kilometre square, a searcher could be shown five or six different businesses at number one depending on which query they typed and where they typed it. A single-point tracker reporting "position 1" or "position 4" for this town would be reporting one of those cells and calling it the market.

The company I was checking on appeared at none of the eighteen points. The grid's name-match returned nothing, and a listings search within 15 kilometres found no business under the name the company uses on its website. That is a finding in its own right, and it comes before any question of rank: the first thing a local grid tells you is whether you are in the set at all. If the profile exists under another name, that name needs to go into the tracker; if it does not exist, no amount of rank tracking will find it.

## Storefront or service area

Set up your Business Profile to match how you serve customers. [Google allows eligible hybrid businesses](https://support.google.com/business/answer/9157481) to show a storefront address and a service area when they both receive customers and travel or deliver to them. If customers do not visit your address, hide it and list the area you serve.

Melissa describes the difficulty of competing across locations:

> it can be a lot easier to rank an actual brick and mortar location than it can be a service area page because you open up the competitiveness

Choose the profile settings that describe your business accurately. You can also build useful location pages for the neighbourhoods and towns you serve to reach customers through organic website results. [Map positioning to real demand](/library/keyword-research/positioning-to-demand) covers finding which of those towns search for it.

## Which points to track

Run a Maps grid to survey your visibility, then repeat it with the same settings to compare positions over time. Choose points where your customers search. Melissa's method for finding them:

> there's also testing that needs to be involved there to figure out, know, like what areas, you know, looking in GA4 and other analytics tools, you know, where are people searching from down to at that city level

That gives you two to five named places. Separately, OpenSEO rank trackers measure your website's organic rankings from a chosen location. They do not track your Business Profile's Maps position. A business serving three towns can use three small trackers to follow its organic results. Twenty keywords in three locations is 60 checks a week, which on the queued schedule is about $0.60 a month.

The grid itself is priced per point: a 3x3 grid is nine Maps searches, a 5x5 is twenty-five, and the app shows the cost before it runs. Use the 3x3 for a quarterly survey and the 5x5 when you are deciding whether to open or list a second location.

## What to do with a bad grid

If you rank well at the centre and fall off two kilometres out, that is proximity doing what proximity does, and the fixes are the ones Melissa puts first: a complete, accurate profile in the right category, reviews you answer, and hours and contact details that are correct. If you rank badly everywhere, check the category and the name before anything else. And if you are absent, as the company above was, the tracker has done its job on the first run by telling you the problem is upstream of rankings.

This is also a budget conversation. Melissa on the size of budget she can work with:

> I can work with $500. It doesn't mean that we are going to have all the results we want in six months or a year. But I can move the needle with $500

A local grid and three small trackers are a few dollars of that, and they are what stops the other $490 being spent on the wrong town.

## Run this with the OpenSEO MCP

Connect the [OpenSEO MCP](/docs/mcp): use the grid for Maps positions and a rank tracker for organic website rankings. The [local-seo](/docs/skills/local-seo) skill packages this workflow.

```text
Using the OpenSEO MCP on project [name] for [business name] at
[address or coordinates]:

1. Search local businesses within 10 km for "[business name]" and
confirm the listing exists. Give me its exact title, its cid, and
its primary category. If nothing matches, stop and tell me.

2. Run a 3x3 local rank grid, 2 km spacing, on mobile, for
"[main service] [town]", using the cid from step 1 as the target.
Show me the rank at each point and the business holding #1 at
each point.

3. Repeat for "[second service] [town]".

4. Summarise: at how many of the 9 points am I in the top 3, how
many in the top 10, and which competitors hold #1 where I do not.

5. For organic website rankings, separately create one rank tracker
per location I name, weekly, mobile, depth 20. Estimate the cost
with 20 keywords each before adding anything. Explain that these
trackers do not measure Maps positions.
```

Step 1 is the one that would have saved the company above a quarter of guessing. Match on the cid, not the name, once you have it.

## Local rank tracking FAQ

### Why do my local rankings look different on my phone and my colleague's?

Because you are standing in different places, or Google thinks you are. Proximity is one of the strongest signals for local queries, so two searchers a few kilometres apart routinely see different map packs. A tracker that checks from one point reports one of those views.

### What is a local rank grid?

A set of searches run from points on a grid around a location, usually 3x3 or 5x5, reporting where a business ranks at each point. It shows how far a business's visibility reaches and where competitors take over, which a single rank check cannot.

### How many points should a local rank grid have?

Nine, spaced to cover the area you serve, is enough to see the shape. Use twenty-five when you are making a location decision. Beyond that you are paying for resolution you will not act on.

### Should a service-area business set up a service area or an address on Google?

Use the settings that match how you serve customers. An eligible storefront that also visits or delivers to customers can show both an address and a service area. If customers do not visit your address, hide it and list your service area.

### Does OpenSEO do local rank tracking?

Yes. The MCP local rank grid measures Business Profile positions in Maps. Scheduled rank trackers measure organic website rankings from a chosen location. Both use credits. On the hosted app, scheduled and live rank-tracker checks require the $10/month plan, which includes $10 of credits.
Loading
Loading