~ / insights / templates

Template · September 2026

Entity Map Worksheet.

A one-row-per-entity worksheet to fill before writing any JSON-LD for a site with more than one location, person or product.

Amit TiwariTemplate8 min read

The decision this protects

The map the worksheet produces, drawn logo founder parent parent brand Organisation #org Logo #logo Founder about#founder Location a #branch Location b #branch Product #product Every box is declared on exactly one page. Every arrow is an @id reference. If you cannot draw it, the JSON-LD will not validate either.
Figure 1. Draw it first. The table below is the same picture as rows.

The decision is which things on this site are entities, and which single page speaks for each one. On a site with one office and one owner that decision makes itself. On a site with eight branches, a founder and a logo it does not, and if it is left to whoever builds each page you get eight Organizations with four phone formats and a founder attached to nothing, which is what I found at a childcare group with eight branches before filling the first version of this worksheet. Every cell left blank here becomes a contradiction in the graph later.

Before you start

  • The full URL list from the sitemap, so you know which pages can declare an entity.
  • The legal name and the trading name, and a decision on which goes in name and which in legalName.
  • The address and phone of every location, from whatever the business treats as authoritative, and who maintains it.
  • The people who will be named in the graph and the one page each is described on.
  • The output of idledger.py from my multi-branch schema guide, so you know what the site declares today.

Stated limits

  • It decides identity and structure, not rich result eligibility, which depends on fields it does not track.
  • It does not choose the schema type for you. It records the type you chose and asks you to justify it.
  • It covers organisations, locations, people and logos. Products, events and articles follow the same rules with different property lists.
  • It assumes one site on one domain.

1. List the entities

An entity is anything a second node will point at, or that a search engine would treat as a distinct thing with its own name. An address or a set of opening hours is a property of a location and gets no row.

Field What to record Why it matters
Entity label A plain-English name such as “the group”, “Rosewood branch”, “the founder”, “the logo” Keeps the client conversation unambiguous before any @id exists
Schema type The most specific schema.org type that is true, such as EducationalOrganization, ChildCare, Person, ImageObject The type sets which properties are valid; a LocalBusiness subtype is both Organization and Place
Why it is a separate row One sentence, such as “eight branches share a name but not an address” If the sentence will not write, the entity is a property of another row
Visible on the site as Where a visitor sees this thing described in text Google’s guidelines require markup to describe visible content

Judgment prompt: Would a parent searching for this thing expect it as its own result, or as a detail on something else’s result? If the second, move it back into a property.

2. Mint the @id and fix where it is declared

An @id is an absolute URL that names the node, minted once, written down here and copied from here into every block. Each @id is declared, with its full set of properties, on exactly one page, and every other mention is a reference containing only {"@id": "..."}.

Field What to record Why it matters
Declared on The canonical URL of the one page that carries the full node, such as https://example.com/locations/rosewood Two declarations of one @id with different phone strings merge into one entity with two phone numbers
Fragment A short stable token, such as #org, #branch, #founder, #logo The fragment is part of the identifier, so #branch on two page URLs yields two identifiers
Absolute @id Declaring page URL plus fragment, copied exactly, such as https://example.com/about#founder A relative #org resolves against whichever page it sits on and silently creates a new entity on every page
Legacy blocks to remove Any existing block that declares this entity without the @id or with a different one Old markup competes with the new graph until deleted and the cache cleared

Judgment prompt: If this page were deleted next year, which page would inherit the entity, and are you prepared to rename every reference on the site to match?

3. Referenced from

A reference never repeats the name, the phone or the address.

Field What to record Why it matters
Referenced from Every other page whose markup points at this @id, by URL or template name Eight branches means eight references to the parent, and the count is checkable against the sitemap
Property used The property on the referencing node, such as parentOrganization, founder, logo Its expected type must match the row’s schema type
Reference shape Confirm it is {"@id": "..."} alone, or record the deliberate exception A reference that also carries a name is a second declaration, and the ledger script will flag it

Judgment prompt: Compare the number of pages in “referenced from” with the number of pages that mention this entity in visible text. If they differ, one of the two lists is wrong.

4. Links between entities

Every arrow in the graph is a property on one row pointing at the @id of another row. Record both ends.

Field What to record Why it matters
parentOrganization For each location, the @id of the organisation it belongs to The upward link that makes a branch read as a branch rather than a separate business
subOrganization On the parent, the full list of location @ids, references only A branch missing here is a branch the parent does not claim
founder and employee On the organisation, the @id of each Person row, never a name string A name string is a new anonymous Person on every page; an @id is one person
brand Where the trading brand differs from the legal entity, the @id of a Brand row Keeps the brand name out of name where it would conflict with legalName
logo and image The @id of the single ImageObject row One logo with width, height and URL, instead of eight slightly different image URLs
sameAs The profile URLs and the one row that carries them Profiles belong to the entity they describe, usually the organisation, rarely a branch

Judgment prompt: Read each arrow aloud as a sentence, such as “Rosewood branch has parentOrganization the group”. If it is untrue or the target row does not exist, delete the arrow or add the row.

5. Source of truth for name, address and phone

The original site had four phone formats because four people typed a phone number. Name where each value comes from and the one format it is written in, so the markup is generated rather than typed.

Field What to record Why it matters
Name source Where the exact name string comes from, such as the Google Business Profile listing The markup name must match what a visitor sees and what citations say
Address source The document or system the address is copied from Two branches on the childcare site had inherited the head office address from a copied template
Phone source and format Where the number comes from and the single format rule, such as country code, space, area code, space, number Four formats of one number read as four numbers
Owner and last verified Who updates the value, and when it was last checked Without an owner the markup drifts from the business within a year
Generated or typed Rendered from a locations table or JSON file, or hand-written Hand-written blocks are where the four phone formats came from

Judgment prompt: If one branch’s phone number changed tomorrow, name the single cell someone would edit. If the answer is more than one cell, the source of truth is not yet single.

The defensible output

Interactive builder for the ledger above. Needs JavaScript.

The worksheet, filled in for a small site ENTITY TYPE @ID DECLARED ON REFERENCED FROM LINKS TO Organisation Organization /#org Homepage All pages logo, founder, Location a LocalBusiness /locations/a#branch Location a page Homepage parentOrganization Founder Person /about#founder About page Homepage worksFor Logo ImageObject /#logo Homepage All pages
Figure 2. Each @id in one ‘declared on’ cell. The validation is a count.

One table, one row per entity, in which every @id appears in exactly one “Declared on” cell and every @id named in “Links to” appears as a row of its own. Run idledger.py against the built site and its ledger should report PASS with the counts this table predicts. The other seven branches are rows identical in shape to the Rosewood row.

Entity Schema type @id Declared on Referenced from Links to NAP source
The group EducationalOrganization https://example.com/#org / 8 branch pages, /about founder to #founder; subOrganization to 8 branch @ids; logo and image to #logo; sameAs to 3 profile URLs Google Business Profile, owner [VERIFY: name], verified [VERIFY: date]
Rosewood branch ChildCare https://example.com/locations/rosewood#branch /locations/rosewood / parentOrganization to #org; image to #logo Locations table row 1, generated, owner [VERIFY: name]
The founder Person https://example.com/about#founder /about / worksFor to #org About page copy, no address or phone
The logo ImageObject https://example.com/#logo / 8 branch pages none Theme file path, 512 by 512

A table that passes has no @id in two “Declared on” cells, no arrow pointing at an @id that is not a row, and a “NAP source” that names a system rather than a person’s memory.

Where I could be wrong

Google’s documentation does not promise that @id references across pages are stitched into one entity. If Google reads each page in isolation, a bare reference on a branch page tells it nothing about the parent’s name, and a minimal repeated declaration with @id, @type and name might serve the branch better, in which case the “reference shape” exception applies to every branch row.

The one-declaring-page rule assumes every entity has a natural home page. A founder who appears only in a footer has to borrow one, and that @id rests on a URL chosen for convenience.

Section 5 assumes the business has a source of truth to name. Some do not, and the honest entry is then “none yet” with an owner assigned to create it, and the markup should wait until it exists.

Sources

  • W3C, JSON-LD 1.1, node identifiers. https://www.w3.org/TR/json-ld11/#node-identifiers
  • schema.org, Organization type and properties. https://schema.org/Organization
  • schema.org, LocalBusiness type. https://schema.org/LocalBusiness
  • Google Search Central, General structured data guidelines. https://developers.google.com/search/docs/appearance/structured-data/sd-policies
  • Google Search Central, Organization structured data. https://developers.google.com/search/docs/appearance/structured-data/organization
  • Schema Markup Validator. https://validator.schema.org/
  • Google, Rich Results Test. https://search.google.com/test/rich-results

How to cite this template

Amit Tiwari (2026). Entity Map Worksheet. Template, September 2026. amittiwari.net. https://amittiwari.net/templates/entity-map-worksheet

Send me the template

A filled example alongside the blank one, so you can see how it is meant to be used.

So I can look before we talk.

Discuss in the community ↗