Read it, chapter by chapter
The full 7-chapter guide for law firms — pick any chapter to read it here.
What You're Actually Auditing: The Ontology Separate from SEO
An ontology audit examines the semantic meaning layer of your site — the entities (who, what, where) and how they relate (who works for whom, what practice belongs to which hub, which office serves which location). This is fundamentally different from traditional SEO audits, which check titles, links, and Core Web Vitals. You are auditing meaning, not mechanics.
Most law firm sites have a URL structure (e.g., /practice-areas/medical-malpractice) but no explicit ontology. The pages exist, but AI models reading the site cannot easily answer: Is "medical malpractice" a service offering, a practice hub, or just a category? Who at the firm handles it? Which office(s) serve it? How does it relate to other practices? Without ontology, the site is a collection of isolated pages, not a coherent knowledge graph.
An ontology audit answers: (1) What are our core entities? (2) Are they defined consistently everywhere? (3) Do relationships between entities exist and resolve? (4) Does our schema.org markup reflect this graph correctly? (5) Would an AI model reading the site understand our structure?
The audit focuses on semantic correctness, not ranking signals. You are checking that if an AI model embeds your pages and reads your JSON-LD, it correctly understands your firm's shape: the attorneys, the practices, the locations, and how they connect. A page with perfect grammar and strong backlinks but a contradictory entity definition will confuse AI models and lose citations to competitors whose pages are clearer.
Map Your Three Core Entity Types: Person, Practice, Place
Every law firm ontology rests on three entity types: Person (attorneys, partners, counsel), Practice (services offered, areas of law), and Place (office locations, service areas). Audit by listing every instance of each type on your site, then verifying consistency.
Person entities: For each attorney on your site, collect: full legal name (as it appears on bar records), bar admission state and year, law school, current role (Partner, Counsel, Associate), and which office/practice(s) they lead or serve. A common failure is listing an attorney as "John Smith" on one page, "J. Smith" on another, and "John P. Smith, Esq." on a third. To AI models, these look like three different people. The ontology audit fixes this by assigning one canonical name and one @id (e.g., #john-smith-person) referenced everywhere.
Practice entities: For each practice area (medical malpractice, employment law, corporate transactions), document: canonical name, description, jurisdictions served, and whether it is a hub (top-level practice) or a spoke (sub-specialization under a hub). Medical malpractice might be a hub; nursing home malpractice might be a spoke. Construction defects might be its own hub, or a spoke under premises liability. The ontology must be a tree — every practice belongs to exactly one parent, with no cycles. A page about "catastrophic injury" should clearly belong under medical malpractice OR personal injury, not both.
Place entities: For each office location, list: street address (byte-identical to Google Business Profile), city, state, ZIP, phone number, and service-area jurisdictions (if not all locations serve all practices). A common mistake: the main office address appears as "123 Main Street, Suite 400" on one page and "123 Main St. Ste. 400" on another. To schema-validation tools and AI models, these are different addresses. The audit ensures every address appears identically everywhere.
| Entity Type | What to List | Canonical ID Format | Common Audit Failure |
|---|---|---|---|
| Person (Attorney) | Full legal name, bar state, bar year, role, office(s) | #firstname-lastname-person | Same attorney spelled three different ways across pages |
| Practice (Service Area) | Name, parent hub (if spoke), jurisdictions, description | #practice-slug | Practice appears as both a hub and a spoke in different places |
| Place (Office) | Street, city, state, ZIP, phone, service areas served | #office-slug or #city-state | Address formatted inconsistently ("Suite 400" vs "Ste 400" vs "Ste. 400") |
Check Entity Consistency: One Identity, One @id
The cardinal rule of ontology auditing: every entity must have ONE canonical identifier (@id) and appear identically everywhere that identifier is used. This is how AI models resolve "who is this person?" and "is this the same practice area as the one I saw three pages ago?"
Start by auditing Person entities. Pull a list of all attorneys mentioned anywhere on the site (firm bios, practice-area pages, office pages, case studies, testimonials). For each name, collect every variation and every page it appears on. You will often find: "John Smith" on the bio page, "J. Smith" in a case result, "John P. Smith, Esq." in a footer, and "John Smith, Partner" in a sidebar. Assign one canonical form (use the bar record as the source of truth) and one @id. Then audit whether every occurrence links back to the same @id in your schema.org markup.
For Practice entities, check whether the practice name is consistent. Pull every instance of "medical malpractice," "personal injury," "employment law," etc. from the site. Do they all capitalize the same way? Are abbreviations used inconsistently ("PI" vs "Personal Injury")? Does a page about a specific sub-practice (nursing home malpractice) correctly reference its parent hub? The ontology must enforce a single spelling and hierarchy for each practice.
For Place entities, audit addresses ruthlessly. Pull every occurrence of each office address. Compare not just the street and city, but the suite number, ZIP code format (with vs without a hyphen in ZIP+4), and phone number format (with vs without dashes). A single inconsistency — "Suite 400" vs "Ste 400" — signals to an AI model that these might be different locations. Search your site for each address using multiple formats (e.g., grep for both "Suite" and "Ste") to find hidden variations.
After identifying variations, establish canonical forms: one name per Person, one name per Practice, one address per Place. Update every page to use the canonical form, and link every mention back to the same @id in your schema. This unified identity is the foundation of a coherent ontology.
Verify Relationships: spokeOf, relatedTo, partOf, and Sidebar Links
Entities alone do not make an ontology. Relationships do. Audit by checking that every relationship explicitly exists: UP (each spoke links to its hub via spokeOf), DOWN (each hub lists all its spokes), and SIDEWAYS (related practices/locations are cross-linked).
First, audit spoke-to-hub relationships. For every practice page that is a spoke (e.g., "Nursing Home Malpractice"), check: (1) Does the page's schema.org markup include a spokeOf property pointing to the parent hub ("Medical Malpractice")? (2) Does the hub page list this spoke in its hasPart or relatedLink properties? (3) Is the spoke visible in the hub's sidebar navigation or spoke list? A common failure: a spoke page exists and is findable via search, but the hub page does not list it, and the schema has no spokeOf. The page is orphaned from the graph.
Second, audit sideways relationships. For a spoke like "Catastrophic Injury in Medical Malpractice," check whether it links (in schema and in visible text) to related practices like "Permanent Disability" or "Wrongful Death," which are siblings under the same hub or under related hubs. A sidebar that lists related practices, or an inline link like "Related: Wrongful Death claims typically involve different damages calculation," creates these relationships. Without sideways links, the model does not know that catastrophic injury and wrongful death are semantically related.
Third, audit location-to-practice relationships. For a page like "Personal Injury in San Francisco," verify: (1) The location page links to the practice hub ("Personal Injury"), not just to the specific location. (2) The practice hub acknowledges the location (either linking to the SF office or mentioning SF in its service-area list). (3) The actual office location page exists and is reachable. A missing link breaks the graph — the model does not connect the SF office to the personal injury practice.
Finally, audit the spoke sidebar. On the hub page and on every spoke page, there should be a visible sidebar or related-pages section listing all sibling spokes with links and thumbnails. This visual representation mirrors the schema relationships and helps both humans and AI understand the practice cluster. Check that every spoke in the sidebar actually resolves (no 404s) and that the sidebar appears consistently on every page in the cluster.
Schema Graph Completeness: The Checklist
An ontology is only as strong as its schema.org implementation. Audit your JSON-LD against this checklist to ensure the graph is complete and correct.
Firm-level schema: You should have one firm Organization node, declared once (typically in the site footer or root layout), with a single canonical @id (e.g., #organization). This node must include: name (byte-identical to GBP), description, address (byte-identical NAP), telephone, url (the site homepage), sameAs (links to GBP, LinkedIn, Avvo, Wikipedia if applicable), and foundingDate. Every page that references the firm should point to this ONE @id, not re-declare a second Organization node with different values.
Attorney nodes: For each attorney, create one Person node with @id (e.g., #attorney-john-smith), including: name (canonical spelling), jobTitle, worksFor (reference to firm #organization), sameAs (LinkedIn profile URL), and hasCredential (bar admission as a structured Credential). No two attorneys should have the same @id. No attorney should be re-declared with different credentials on different pages.
Practice/Service nodes: For each practice area that has its own page, create a Service node with @id, name (canonical, matching the visible title), description, provider (reference to firm #organization), and areaServed (list of jurisdictions, e.g., California, New York). If the practice is a spoke, include partOf (reference to the parent hub). If it is a hub, include hasPart (array of spoke @id references).
Location/LocalBusiness nodes: For each office, create a LocalBusiness node with @id, name, address (byte-identical), telephone, latitude and longitude (real geocoordinates, not place names), openingHours (if available), areaServed (list of jurisdictions this office serves), and aggregateRating (third-party rating from GBP only — never self-serving). Cross-reference with the firm @id so the office is linked to the parent organization.
Page-level schema: Every significant page (hub, spoke, attorney bio, location page) should have a WebPage or article-subtype node (BlogPosting, NewsArticle) with @id, headline, description, datePublished, dateModified (ISO-8601 with timezone), author (reference to a Person @id if bylined), publisher (reference to firm #organization), and mainEntity (reference to the primary entity the page is about — a Practice @id for a practice page, a Person @id for an attorney bio).
Breadcrumb and FAQPage nodes: Add BreadcrumbList to every page (visible + schema) showing the path from home to the current page. Add FAQPage to every page with an FAQ section, ensuring each question-answer pair is a proper item in the FAQPage array.
After adding all nodes, validate using validator.schema.org (syntax check). Then manually inspect the @graph to verify: (1) Every reference (e.g., "provider": {"@id": "#organization"}) points to an @id that actually exists in the graph. (2) No entity is declared twice with different values. (3) Every @id is unique. (4) Date fields are ISO-8601 with timezone.
Common Ontology Audit Failures and How to Fix Them
Failure 1: Multiple Names for One Entity
You have "Smith & Associates," "Smith and Associates Law Firm," and "Smith Associates" used on different pages. Fix: Choose one canonical name (match GBP). Search the codebase for all variations. Replace with the canonical form everywhere. Add alternateName to the schema if you want to preserve alternate forms for discovery.
Failure 2: Orphaned Spokes
A practice page exists and ranks in Google, but the hub page does not list it in a sidebar, and the schema has no spokeOf. The page is not wired into the graph. Fix: Add the spoke to the hub's sidebar template. Add a spokeOf property in the spoke's schema pointing to the hub's @id. Verify the link resolves.
Failure 3: Inconsistent Attorney Credentials
An attorney is listed as "Partner" on their bio page, "Associate" in a case result, and "Counsel" in the office listing. Fix: Establish a canonical title from your firm records (law.com, bar records, GBP). Update all occurrences to match. Use the bar record as the authoritative source for bar admission year and state; use your current org chart for current title.
Failure 4: Address Formatting Variations
Offices are listed as "123 Main Street" (one page), "123 Main St" (another), and "123 Main St." (third). Fix: Establish a canonical format and a script to search-and-replace. Most law firms use "Street" not "St." or "St" for formality. Byte-match to GBP.
Failure 5: Missing Location-to-Practice Connections
A practice page exists; a location page exists. But they do not link to each other in schema or navigation. Fix: Add cross-links in both directions. The location page should reference the practice pages served by that office. Each practice page should acknowledge multiple locations (e.g., "We serve clients in San Francisco and Los Angeles") or reference the nearest office.
Failure 6: Practice Hub Not Listed as a Parent
An AI model reading your site cannot determine whether "Medical Malpractice" is a top-level hub or a spoke under "Personal Injury." Your sidebar might list it at the top, but your schema has no hierarchy defined. Fix: For every spoke, add partOf in the schema explicitly naming its parent @id. For every hub, add hasPart listing all spokes. The schema should match the navigation hierarchy.
Failure 7: No Real Geocoordinates
Your LocalBusiness schema has an address but no latitude and longitude. The model cannot pinpoint your location precisely. Fix: Use Google Geocoding API or a tool like geocoding.js to convert your address to coordinates. Verify against Google Maps: the coordinates should place a pin on your actual office building.
Failure 8: Self-Serving aggregateRating
You have "aggregateRating": {"ratingValue": 5.0, "ratingCount": 100} on your firm Organization node, made up or derived from your internal review system (not GBP). This is fabricated entity inflation. AI models distrust this and may penalize you. Fix: Pull the real rating and count from your GBP profile (via the Places API or by reading GBP directly). Do NOT put aggregateRating on the firm node at all — put it only on individual location pages (LocalBusiness nodes) with real GBP data, and on Review and Rating-specific pages.
Why Ontology Audits Matter for AI Search Citations
An AI model reading your site needs to understand its structure. When a user asks "What attorneys at [Firm] handle medical malpractice in California?", the model retrieves pages from your site and constructs an answer. If your ontology is clear — attorneys are linked to practices via schema, practices are linked to locations via areaServed, and every entity has one canonical identifier — the model can answer correctly and cite your pages with confidence. If the ontology is fragmented — the same attorney appears under different names, the practice is not clearly linked to a location, or multiple conflicting pieces of information exist — the model will either refuse to cite you ("I found conflicting information") or cite a competitor who has a clearer graph.
A practical example: a user asks Gemini "Best medical malpractice attorney in San Francisco." Gemini retrieves your SF office page, your medical malpractice hub, and several attorney bios. If your schema clearly connects: (1) the SF office @id to the medical malpractice @id to specific attorney @ids, the model confidently cites you. If the schema is unclear, Gemini might cite a competitor who has the same name/location in cleaner pages or better-connected schema, or might not cite you at all.
Ontology audits are the bridge between semantic accuracy and AI visibility. Unlike traditional SEO audits (which optimize for Google's crawler and ranking algorithms), ontology audits ensure that every reader of your site — human or AI — understands who you are, what you do, and where. This is foundational for AI-age visibility.
Recommended audit schedule: Before launch (blocks deployment), quarterly on new pages (within 7 days of publication), and annually for the full site. After any major restructure (new office, new practice area, merger), audit within 7 days. The goal is to catch entity drift (names changing, addresses migrating) before it accumulates into a fragmented graph that AI models cannot make sense of.

