Read it, chapter by chapter
The full 8-chapter guide for law firms — pick any chapter to read it here.
What Is an Ontology, and Why Does It Matter for Law Firms?
An ontology is a formal, shared vocabulary that defines entities (things in your domain) and the relationships between them. In philosophy, ontology is the study of what exists. In computer science and semantic web design, an ontology is a machine-readable blueprint of that existence. For a law firm, the ontology might define: a Firm (entity) has Attorneys (entities); each Attorney has a Bar License (property); the Firm offers LegalServices (entities); each Service applies in certain Jurisdictions (relationships); Clients (entities) engage Services and may receive Outcomes (properties, like a verdict or settlement).
Why ontologies matter: Google, ChatGPT, Claude, Gemini, and Perplexity are trained to extract and reason over entities and relationships. When they read your website, they are trying to build a mental model—an ontology—of what you do, where you serve, and who you are. If your website is vague ("we handle all kinds of law in many places"), the ontology the AI builds is diffuse and useless. If your website is precise and structured ("our firm offers medical malpractice litigation in San Francisco and Oakland; our attorneys are John Smith (State Bar #123456) and Jane Doe (State Bar #654321)"), the ontology is sharp, and AI engines can confidently cite you for relevant queries. This is core to GEO — Generative Engine Optimization for law firms.
Schema.org is the industry standard for expressing ontologies on the web. It is a collaborative project between Google, Microsoft, Yahoo, Yandex, and others—a shared vocabulary so that any site can describe its entities and relationships using the same terms. When you encode your law firm's ontology using Schema.org, you are using a language that every major AI engine and search engine understands natively.
Translating ontology to Schema.org JSON-LD is the bridge from your human understanding of your firm ("we are a personal injury practice with two offices and three attorneys") to a machine-readable graph that AI engines can crawl, parse, and cite. The translation happens in three layers: (1) design the ontology (entities + relationships), (2) map it to Schema.org types and properties, (3) encode it as JSON-LD in your HTML. Start with the ontology overview, then return here for the technical implementation.
From Ontology to Schema.org: Mapping Entities and Relationships
The first step is identifying the entities in your law firm's ontology and picking the Schema.org type that represents each one. Schema.org is a type hierarchy—a family tree where types inherit properties from their parents. An Attorney is a Person; a Person is a Thing. A LegalService is a Service; a Service is an Intangible Thing. Understanding the hierarchy helps you pick the right type.
| Entity (Ontology) | Schema.org Type | Key Properties | Why It Matters |
|---|---|---|---|
| Your law firm | Organization (or LocalBusiness for offices) | name, address, telephone, sameAs (LinkedIn, GBP), knowsAbout | The root entity; all other entities reference it via provider or publisher. Single @id across all pages makes entity authority additive. |
| An attorney | Person | name, worksFor (→ firm @id), hasCredential (bar license), sameAs (LinkedIn profile) | Disambiguates individual expertise. AI engines cite Person nodes for authorship and byline credibility. |
| A practice area (e.g., personal injury) | LegalService (or Service) | name, provider (→ firm @id), areaServed (cities/states), knowsAbout (keywords), hasOfferCatalog | Connects your firm to specific practice domains and geographies. Multiple LegalServices form an offer catalog. |
| A court or jurisdiction | CourtHouse (or Place / AdministrativeArea) | name, address, geo (lat/lng), sameAs (Wikipedia) | Grounds your service area in real geography. Courts are institutions AI models recognize; linking to them is a trust signal. |
| An office location | LocalBusiness (a subtype of Organization) | name, address (specific to that office), telephone (local), geo, openingHours | For multi-office firms. Each office is its own LocalBusiness entity but has sameAs → the firm's main @id to show it is part of the same organization. |
| A service offering in a specific city | Offer (inside an OfferCatalog or linked from a page) | name, price (if applicable), priceCurrency, areaServed, availableAtOrFrom (→ firm or office @id) | Connects offer (service) to place. AI engines use this to match queries like "employment law in Denver" to your Denver employment law page. |
Once you have mapped entities to types, the next step is identifying relationships. In an ontology, relationships are directed edges: Attorney A "works for" Firm B; Firm B "offers" LegalService C; Service C "is available in" City D. In Schema.org, relationships are properties. The Property connects two entities.
For example, an Attorney (Person) has a property worksFor whose value is the Firm (Organization). In JSON-LD, this looks like:
{ "@type": "Person", "name": "John Smith", "worksFor": { "@id": "#organization" } }
The @id is a unique identifier for the entity. By using #organization on every page, you tell the AI engine: "this is the same firm every time." The AI engine builds entity authority by aggregating signals across all mentions of #organization. This is the highest-leverage ontology-to-schema translation: consistent entity resolution via shared @id.
Relationships also serve a navigational function for AI. When an engine crawls your site and sees "LegalService X is offered by Organization @id/#organization," it can backtrack to the org's page and extract the firm's reputation, credentials, and presence. This interlinking builds a denser, more credible graph than if each page mentioned the firm only in prose.
JSON-LD: The Format That Carries Your Ontology
JSON-LD stands for JSON for Linking Data. It is a W3C standard for encoding linked data (entities and relationships) as JSON. JSON-LD is the preferred format for Schema.org on the web because it is easy to embed in HTML (inside a <script type="application/ld+json"> tag) and does not require separate RDF/XML or Turtle files.
A JSON-LD document is a collection of objects, each representing an entity. The simplest example:
{ "@context": "https://schema.org", "@type": "Organization", "name": "My Law Firm", "url": "https://mylaw.firm" }
The @context tells the parser where to resolve term names (e.g., name, url) to their definitions. https://schema.org is the canonical Schema.org namespace. The @type is the Schema.org type. The remaining properties are key-value pairs from the Schema.org vocabulary.
For law firms, the most useful JSON-LD structure is a @graph — a collection of related entities on a single page. A local service page might contain:
- Organization (the firm)
- LocalBusiness (the office serving that city)
- LegalService (the practice area offered)
- BreadcrumbList (navigation)
- Article or WebPage (the page itself)
- FAQPage or QAPage (Q&A content)
All of these entities are related via properties and shared @id references. Here is a minimal example:
{ "@context": "https://schema.org", "@graph": [ { "@type": "Organization", "@id": "https://mylaw.firm/#organization", "name": "My Law Firm", "sameAs": "https://www.linkedin.com/company/my-law-firm" }, { "@type": "LegalService", "@id": "https://mylaw.firm/medical-malpractice/#service", "name": "Medical Malpractice Litigation", "provider": { "@id": "#organization" }, "areaServed": { "@type": "City", "name": "San Francisco" } }, { "@type": "WebPage", "@id": "https://mylaw.firm/medical-malpractice-san-francisco/", "name": "Medical Malpractice Lawyer in San Francisco", "mainEntity": { "@id": "#service" } } ] }
Notice the @id field. Every entity has a unique identifier. The organization's @id is #organization (a fragment identifier, meaning "this page's organization"). The service's @id is specific to that service. The page's @id is the page's own URL. Relationships between entities are expressed by referencing their @ids—e.g., the page's mainEntity points to the service via { "@id": "#service" }.
This interlinking is what transforms a bunch of scattered data into a graph. The AI engine does not have to infer that the page is about the service; the schema explicitly says so via the mainEntity link.
The @id Pattern: Entity Resolution and Authority Accumulation
The most critical pattern in law-firm ontology-to-schema translation is the reuse of @id across pages. Every time your firm is mentioned—on the homepage, on every practice-area page, on every location page, on every attorney bio—it should have the same @id. Typically, #organization. Similarly, each attorney should have a consistent @id, e.g., #john-smith-attorney or a full URL like https://mylaw.firm/attorneys/john-smith/#person.
Why? Because AI engines, especially Google and Gemini, use entity linking to recognize that multiple mentions refer to the same real-world thing. If your firm's homepage uses @id https://mylaw.firm/#organization, your practice-area page uses https://mylaw.firm/practice-areas/medical-malpractice/#firm, and your location page uses https://mylaw.firm/locations/sf/#org, the engine sees three different organizations, even though they are the same firm. The entity gets fragmented; authority is diluted.
Conversely, if all three pages use https://mylaw.firm/#organization, the engine recognizes it as a single entity. Facts about the firm from the homepage (e.g., "top-rated medical malpractice firm in California") can be cross-linked with facts from location pages ("serves San Francisco, Oakland, Los Angeles") and practice pages ("handled over 200 medical malpractice cases"). This aggregation builds entity authority—the entity becomes more credible and more likely to be retrieved and cited by AI search engines.
The same principle applies to people. If an attorney appears on the firm's homepage, in an attorney-directory page, and on a practice-area page, use the same @id everywhere. This makes the attorney's credentials, experience, and expertise accumulate. AI engines see a single, consistently-referenced Person node rather than fragments scattered across the site.
This pattern is the bridge between the ontology (a conceptual graph) and practical ranking. The ontology defines who the entities are and how they relate. The @id pattern ensures the schema reflects that ontology faithfully.
Mapping Visible Content to Schema Fields: The Truthfulness Gate
Schema.org's core rule is: every field in the schema must correspond to visible, verifiable content on the page. You do not mark up invisible content. You do not invent facts to fill schema fields. You do not claim credentials the attorney does not have, results you did not achieve, or services you do not offer.
For example, if a page claims "We have a 5-star rating (50 reviews)," you must embed aggregateRating in the schema—but only if that rating is displayed on the page and is real (sourced from Google Business Profile, Avvo, or your own collected reviews). If the rating is not visible and real, omit the schema field.
Similarly, if a service page lists "available in San Francisco, Oakland, Los Angeles," the schema areaServed property should list those three cities. But every city named in the schema should also appear visibly on the page. If you list 20 cities in the schema but only mention 3 on the page, you have a schema-mismatch violation. Google and AI engines flag this as low-quality markup and may ignore it.
This is where the ontology enforces truthfulness. A well-designed ontology should reflect what your firm actually is and does. When you translate that ontology to schema, and you encode the schema faithfully from visible content, the result is a truthful graph. AI engines can then cite your content with confidence, knowing that the facts in your schema match the facts on the page.
For every fact in the schema, ask: Is this visible on the page? Is it real? Is it sourced if it is a number or claim? If the answer is no to any, remove the field. Incomplete schema is better than false schema.
Validation: Schema.org and Google's Tools
Once you have encoded your ontology in JSON-LD, validate it in two places: validator.schema.org and Google's Rich Results Test.
validator.schema.org checks syntax and completeness. It will flag missing required fields for certain types. For example, if you use the LocalBusiness type but do not include a name and address, the validator will warn you. If you have a syntax error (mismatched braces, invalid JSON), it will catch that too. Always run your JSON-LD through this validator before publishing.
Google's Rich Results Test checks which types are eligible for Google SERP features. Article, LocalBusiness, FAQPage, etc. If you have a type eligible for a rich result, the tool will show you the preview of how it will appear in Google search results (e.g., the 5-star rating snippet). However, the Rich Results Test only shows rich-result-eligible types. Non-eligible types like Service, HowTo, Dataset, and Person nodes are still valid and are parsed by Google and AI engines, but they will not appear in the Rich Results Test's preview. Do not mistake absence from the test for invalidity. See law-firm schema rules for the complete type reference.
A final validation: SSR check. Run curl -A GPTBot https://yourpage.com to fetch the page as an AI bot would see it. The JSON-LD must be in the initial HTML response, not loaded by JavaScript. This ensures AI crawlers can index your schema immediately.
Practical Example: A Complete Law Firm Ontology in JSON-LD
Here is a concrete example of a personal-injury firm with one office, two attorneys, and two practice areas, translated to JSON-LD:
{ "@context": "https://schema.org", "@graph": [ { "@type": "Organization", "@id": "https://example.lawfirm.com/#organization", "name": "Example Law Firm", "url": "https://example.lawfirm.com", "address": { "@type": "PostalAddress", "streetAddress": "123 Main St", "addressLocality": "San Francisco", "addressRegion": "CA", "postalCode": "94103" }, "telephone": "+1-415-555-0100", "sameAs": ["https://www.linkedin.com/company/example-law-firm", "https://www.google.com/maps/place/Example+Law+Firm"], "knowsAbout": ["Personal Injury Law", "Medical Malpractice"] }, { "@type": "Person", "@id": "https://example.lawfirm.com/#attorney-john-smith", "name": "John Smith", "worksFor": { "@id": "#organization" }, "hasCredential": { "@type": "EducationalOccupationalCredential", "credentialCategory": "State Bar of California", "identifier": "123456" }, "sameAs": "https://www.linkedin.com/in/john-smith" }, { "@type": "LegalService", "@id": "https://example.lawfirm.com/personal-injury/#service", "name": "Personal Injury Litigation", "provider": { "@id": "#organization" }, "areaServed": [ { "@type": "City", "name": "San Francisco", "sameAs": "https://en.wikipedia.org/wiki/San_Francisco" }, { "@type": "City", "name": "Oakland", "sameAs": "https://en.wikipedia.org/wiki/Oakland,_California" } ], "knowsAbout": ["Auto accidents", "Slip and fall", "Premises liability"] }, { "@type": "WebPage", "@id": "https://example.lawfirm.com/personal-injury/", "name": "Personal Injury Lawyer | Example Law Firm", "mainEntity": { "@id": "#service" }, "author": { "@id": "#attorney-john-smith" } } ] }
This ontology captures: the firm exists (Organization), has an office in San Francisco (address), employs John Smith (Person worksFor Organization), John is licensed (hasCredential), the firm offers Personal Injury Litigation (LegalService), that service is available in San Francisco and Oakland (areaServed), and the page is authored by John. All entities are cross-linked via @id. This is what a translated ontology looks like: structured, explicit, and machine-readable.
Why This Matters for GEO (Generative Engine Optimization)
Translating your ontology to JSON-LD is not just about schema validation. It is fundamental to being cited by AI search engines. ChatGPT, Claude, Gemini, and Perplexity use entity graphs (built from schema, sameAs links, and entity co-occurrence) to understand what your firm is and what you specialize in. When a user asks "personal injury lawyer in San Francisco," the engine builds a query entity graph ("personal injury" + "San Francisco") and retrieves pages whose entities match. This is the core of answer-engine optimization for lawyers.
If your ontology is vague or your schema is incomplete, you will not appear in that retrieval. If your ontology is clear and your schema is rich, the engine will confidently retrieve your pages and cite you. For law firms competing in AI visibility, this is non-negotiable.
The other advantage is disambiguation. Hundreds of law firms are named "Smith & Associates." Without clear schema and sameAs links (to LinkedIn, GBP, Wikidata if applicable), the engine cannot tell your firm from similar ones. With a rich, cross-linked entity graph, you are unambiguous.
Finally, consistent entity resolution (the @id pattern) means that signals from multiple pages accumulate. If five practice-area pages all reference the same firm @id, and each page has 2,000 words of high-quality content, the engine recognizes this as a single firm with 10,000 words of authority across diverse practice areas. That is more impressive than five pages linking to five different firm @ids.

