I built the GEO Grader because I got tired of opening Rich Results Test, then Schema.org validator, then viewing page source, then copy-pasting into a JSON linter, then writing down what was missing. Four tabs to answer one question: does this site's LocalBusiness schema actually do its job.
The tool at /free-tools/geo-grader/ does all four checks in one shot. You paste a URL, wait about 10 seconds, and get a score from 0 to 100 with a breakdown. No login. No email gate. No credit card.
Here's what it actually measures, what a good score looks like, and the 4 mistakes I see on roughly 80% of contractor sites I run through it.
The 3 things it scores
The grader runs your page through three filters. Each one carries a weight toward the final score.
Completeness (50 points). Does your LocalBusiness schema include the 10 fields that matter? Name, address, phone, hours, priceRange, areaServed, sameAs social links, image, url, and a valid @type. Each missing field costs you 5 points.
Correctness (30 points). Is your @type actually LocalBusiness (or a valid subtype like Plumber, Electrician, Dentist)? Is your @context set to https://schema.org? Wrong @type is the single most common failure I see.
Machine-readability (20 points). Does the JSON-LD actually parse without errors? Are there nested objects that break validation? Is there a stray trailing comma that kills the whole block? A human can read around a typo. A crawler can't.
Add them up, you get your score.
What a 95 looks like
A 95 means you're hitting 9 of 10 fields, your @type is correct, and the JSON parses cleanly. The single missing point is usually priceRange or a second sameAs entry. Here's a real schema block that scored 95 when I ran it last week:
{
"@context": "https://schema.org",
"@type": "Plumber",
"name": "Westside Plumbing Co.",
"image": "https://westsideplumbing.com/logo.jpg",
"url": "https://westsideplumbing.com",
"telephone": "+1-403-555-0142",
"priceRange": "$$",
"address": {
"@type": "PostalAddress",
"streetAddress": "412 Bow Trail SW",
"addressLocality": "Calgary",
"addressRegion": "AB",
"postalCode": "T3C 2E8",
"addressCountry": "CA"
},
"openingHoursSpecification": [{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
"opens": "07:00",
"closes": "18:00"
}],
"areaServed": ["Calgary","Airdrie","Cochrane","Okotoks"],
"sameAs": [
"https://www.facebook.com/westsideplumbing",
"https://www.instagram.com/westsideplumbingyyc",
"https://g.page/westsideplumbingcalgary"
]
}
Notice what's there. A specific subtype (Plumber, not generic LocalBusiness). Real hours with day ranges. A list of 4 served cities, not just one. Three sameAs links pointing at the Google Business Profile and two social accounts. That's what the grader rewards.
What a 45 looks like
A 45 is the average score for a site built by a template shop in 2019 and never touched since. It usually looks like this:
@typeis set toOrganizationorWebSiteinstead ofLocalBusiness(loses 15 points)- No
areaServedfield at all (loses 5) - No
priceRange(loses 5) - No
openingHoursSpecification(loses 5) - Only the business homepage URL, no
sameAssocial links (loses 5) telephoneis either missing or formatted as plain text instead of E.164 (loses 5)- An image reference pointing at a broken URL (loses 5)
That's a 55 before you even check if the JSON parses. Add one stray comma from a theme update and you're at 45.
The frustrating part: most of these sites rank fine on brand searches. But on "plumber near me" or "emergency electrician Calgary," they lose to a competitor whose schema hands Google a clean plate of structured data.
The 4 mistakes I see every week
After grading a few hundred sites, the same failures show up. In order of how often I see them:
1. Using Organization instead of LocalBusiness. About 60% of the sites I test use Organization for a local service business. Organization is for entities without a physical trade area, like a software company. If you drive trucks to job sites, you're a LocalBusiness or one of its subtypes.
2. Missing areaServed. Roughly 70% of contractor sites don't list the cities or regions they actually service. This is the single biggest miss for local ranking, because areaServed is literally how you tell a search engine "I work in these 5 suburbs."
3. No priceRange. About 50% of sites skip this. It's just one character: $, $$, $$$, or $$$$. Takes 3 seconds to add. Google uses it in comparison features.
4. No phone, or a phone buried in a script. Around 25% of sites have a click-to-call button but no telephone field in the schema. The button is for humans. The schema field is for the crawler.
Fix those four things and most sites jump from 45 to 75 in a single afternoon.
How Flare uses the score
Flare is the advisor built into RankingLocal. When your GEO Grader score drops below 70, Flare flags it in the dashboard and lists the exact fields you're missing. No guesswork. If you're at a 55 because of missing areaServed, Flare tells you that in plain English and points at the template file.
The grader doesn't just give you a score and walk away. It tells you which 10-point fix to do first.
Run your own site
Head to /free-tools/geo-grader/, paste your URL, wait 10 seconds. If you score above 90, you're in the top 10% of local sites I've tested. Below 60, you have a quick afternoon of cleanup ahead.
Questions about your result, or you think the grader got something wrong? hello@rankinglocal.ai is read by me directly.