Open-source architecture for making ENS identities into Google-recognized entities: Schema.org structured data, verification, and indexing for Web3 identity pages.
Web3 Identity SEO: Structured Data for ENS Identity Pages
Open-source documentation for structured data, identity verification, and search indexing of ENS-based pages.>
Reference implementation: ookyet.eth โ measured outcomes in Results.
Privacy: see the Privacy Notice.
Problem
ENS domains like vitalik.eth or ookyet.eth often lack structured entity markup on an associated website. Without machine-readable Person/Organization data and cross-source consistency, they may not appear as named entities in web search results or Knowledge Panels.
Solution Architecture
A documented five-layer approach for entity markup and indexing submission:
Layer 1: Indexing Acceleration
- Google Indexing API - 24-48 hour indexing vs 7+ days traditional crawl
- IndexNow - Bing/Yandex instant indexing
- Direct submission bypasses crawl queue
Layer 2: Entity Markup
- Schema.org @graph - Structured entity data
- Person/Organization types - Standard Schema.org entity types
- hasCredential properties - Dentity/ENS verification signals
Layer 3: Proof of Humanness
- Dentity Unique Human verification - Anti-Sybil KYC
- Government ID + Biometric - Third-party liveness and document checks
- Verification checklist - Provider-specific credential status
Layer 4: Entity Graph Linkage
@graphwith shared@idreferences - Person, ProfilePage, WebSite, and Article entities are explicitly linked through stable@idURIs, so Google parses one cohesive entity rather than several disconnected ones- ProfilePage with
mainEntityโ Person - signals the page's primary subject is a Person entity (per Schema.org ProfilePage). Google requiresmainEntityto be aPersonorOrganization; emit exactly one ProfilePage on the canonical "about" page. FAQ Schema (โ RETIRED - Google limited FAQ rich results to authoritative government/health sites in Aug 2023, then fully removed the feature from Search on May 7, 2026 (FAQ structured-data docs removed June 15, 2026). Do not emitFAQPage)FAQPagefor entity SEO โ keep FAQ as visible page content. (HowTolikewise retired Sep 2023;QAPageis still supported but only for a single user-submitted Q&A page, not authored FAQ copy.)
Layer 5: Cross-Platform Validation
- Unified cross-platform identity - Consistent name/avatar/links across Web2/Web3 (audited count in Results)
- NFT avatar - Visual identity proof
- sameAs linkage - Cross-source consistency
- Off-site co-occurrence -
Real Name (@handle)on every authority profile (LinkedIn, ORCID) so Google reconciles the alias itself โ see Step 4.3 of the guide
Reference Implementation
See ookyet.eth for a production example:
- โ ENS Domain: ookyet.eth (owned since 2023)
- โ Dentity Verified: Unique Human KYC (10/10 checks)
- โ NFT Avatar: Lil Ghost #761 on-chain proof
- โ Indexed entity: Person + Organization + ProfilePage detected, 0 errors (Rich Results Test)
- โ SERP features: Position 1, Sitelinks, Image pack, AI Overview entity mention
Implementation Guide
Step 1: Schema.org Entity Markup
Person-first naming. Make the Person your single primary entity. Its name should read like a person/handle (e.g. Your Name or yourhandle), not the ENS domain. Put the ENS name in alternateName and as an identifier โ it is a verifiable anchor, not the entity's primary key. This keeps Google's person entity keyed to a human/handle while ENS corroborates it.
Step 2: ProfilePage Declaration
Per Google's ProfilePage documentation, the page's primary focus must be a single person/organization affiliated with the site (an "About" / author page qualifies). mainEntity must be a Person or Organization, and name is required. Google also recognizes sameAs, identifier, description, and dateCreated/dateModified on the entity. This markup feeds Google's Discussions and Forums understanding of who a creator is.
Step 3: FAQ โ RETIRED (do not emit FAQPage)
**Google limited FAQ rich results to authoritative government/health sites in
Aug 2023, then fully removed the feature from Search on May 7, 2026 (FAQ
structured-data docs removed June 15, 2026).** Emitting FAQPage no longer produces a rich result
and can surface as an invalid item / "Q&A" issue in Search Console. Keep FAQ
content as visible page copy instead. HowTo is likewise retired (Sep 2023).
QAPage remains supported but only for a single user-submitted Q&A page โ not
authored FAQ/marketing content.>
The former FAQPage example is kept below for historical context only โ do not deploy it:
<!-- RETIRED: do NOT deploy. FAQPage no longer yields rich results and may trigger GSC errors. -->
Step 4: Get pages indexed
โ ๏ธ The Google Indexing API is NOT for identity/profile pages. Per Google's policy, the Indexing API may only be used for pages withJobPostingorBroadcastEvent(in aVideoObject). In May 2025 Google reiterated it "may stop supporting unsupported content formats without notice," and misuse can get API access revoked. For an identity/ProfilePagelike/proof/, do not call the Indexing API โ submit a sitemap and, for a one-off, use Search Console โ URL Inspection โ "Request indexing." IndexNow (below) covers Bing/Yandex.
The API call itself, shown only for the content types Google actually allows (e.g. a JobPosting page):
const { google } = require('googleapis');
async function submitToIndexingAPI(url) { const auth = new google.auth.GoogleAuth({ keyFile: 'service-account.json', scopes: ['https://www.googleapis.com/auth/indexing'] });
const indexing = google.indexing({ version: 'v3', auth });
await indexing.urlNotifications.publish({ requestBody: { url, type: 'URL_UPDATED' } }); }
// Allowed: a JobPosting / BroadcastEvent page only. await submitToIndexingAPI('https://yoursite.com/jobs/some-job-posting/');
Results
Based on the ookyet.eth implementation:
| Metric | Before | After | How measured | |--------|--------|-------|--------------| | Google indexing time (per page) | 7-30 days | 24-48 hours | Google Search Console "Last crawl" timestamps | | SERP features for ookyet / ookyet.eth | None | Position 1, Sitelinks, Image thumbnail, Image pack | Reproducible โ search ookyet / ookyet.eth | | Entity recognition in AI Overview | None | Google's AI Overview answers that ookyet "is indeed an entity," resolving the person (real name), the ookyet.eth ENS name, and the NFT avatar from 6-7 cross-linked sources | Reproducible โ search ookyet or ookyet is entity | | Search performance (cumulative since first indexed, Aug 2025) | โ | Avg position 1.4, CTR 11.1% (11.8K impressions / 1.31K clicks) | Search Console โ Performance (Web); ookyet.com was first indexed Aug 2025, so these are ~10 months of cumulative data | | Rich Results Test status | N/A | 0 errors, Person + ProfilePage detected | Google Rich Results Test | | Cross-platform sameAs links | 0 | 15+ verified profiles | Manual audit of profile links in sameAs array | | Google Knowledge Graph entity node | None (KG API returned no entity) | Machine-generated Person node confirmed 2026-07-02 โ query ookyet resolves uniquely to MID /g/11z806my44 | KG Search API, reproducible (see milestone) | | Knowledge Panel (formal KP box) | Not triggered | Still not triggered โ a KG entity node is the mechanical prerequisite for a KP, not the KP itself | Google KG API + direct SERP |
AI Overview entity recognition โ a Knowledge Panel. Being narrated as an entity in an AI Overview (achieved above) means Google has resolved and understood the entity; a formal Knowledge Panel is a separate, black-box decision Google has not made here. (AI Overviews are generated and can vary between queries/sessions; the entity recognition above has been observed stable over an extended period.) The Knowledge Graph API exposes no "candidate"/pre-trigger state, so any "% probability of KP trigger" is an internal model estimate, not a Google metric. This project optimizes for verifiable entity understanding, not for forcing a KP.
Milestone: Knowledge Graph entity node (2026-07-02)
About 11 months after first indexing (Aug 2025), the Google Knowledge Graph Search API returns a machine-generated Person node for this implementation:
curl "https://kgsearch.googleapis.com/v1/entities:search?query=ookyet&limit=10&indent=true&key=YOURAPIKEY"
โ exactly one result: kg:/g/11z806my44 (@type: Person)
Why this is the outcome the architecture targets:
/g/MID = a machine-minted node (post-Freebase), created by Google's own cross-source reconciliation. It cannot be registered or bought โ only corroborated into existence. This is entity resolution, not document retrieval.- Zero-ambiguity resolution. The KG holds 8 distinct Person nodes sharing the author's real name; the query
ookyetresolves uniquely to this one. A coined handle works as a cross-namespace disambiguation key (handle โ person), which is exactly what a Person-first entity model is for. - Third-party corroboration outweighs self-declaration. The node's canonical name is the author's real name (Qifeng Huang โ see CITATION.cff), taken from high-authority anchors (LinkedIn, ORCID) rather than the site's self-declared
name: ookyet. Expected and healthy: the handle stays the unique entry point; the legal name carries source authority. - Honest status. The node is still sparse (no
detailedDescription,image, orurlexposed; near-zeroresultScore), and a formal Knowledge Panel remains untriggered. Growth from here is driven by independent third-party coverage plus time โ not by further markup changes.
urlโ usually first. It means Google has bound your entity home to the node; it is driven by the corroboration you already shipped (Person-first graph + ProfilePage + consistentsameAs), not by new signals.imageโ next; drawn from the node's reconciled visual identity (a consistent avatar across sources keeps the candidate pool unambiguous).resultScorerising by an order of magnitude โ a precursor of display-worthiness.detailedDescriptionโ usually last, and often never for niche entities: it is largely sourced from encyclopedic references (Wikipedia/Wikidata), which are notability-gated. An empty description does not block the other fields.
url" is the point at which "Knowledge Panel plausible soon" becomes a defensible statement.
Recovery-playbook validation (same window). The reference site's structured-data fix (retiring QAPage, fixing ProfilePage.mainEntity; deployed Jun 28) was confirmed digested by Google on Jul 7: the GSC Profile page report turned valid (1 item, 0 invalid), indexed pages rose 4 โ 6, and 404s stayed at 0 โ about 9 days from deploy to report-level validation, with zero further schema edits in between. This is the "fix once, freeze, wait" discipline working as designed; re-tweaking mid-window would have reset Google's evaluation clock. (Related GSC note: Test Live URL is read-only โ it never queues a crawl or resets anything; only Request Indexing sends an active signal.)
Timeline: Aug 2025 first indexed โ Oct 2025 Dentity verification + entity markup โ Jun 2026 Person-first convergence (single Person entity; FAQ/HowTo retired) โ Jul 2, 2026 KG entity node confirmed via API โ Jul 7, 2026 GSC structured-data recovery confirmed (ProfilePage valid; indexed pages 4โ6).
Architecture Diagram
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Google Knowledge Graph โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Entity: ookyet (alt: ookyet.eth) โ โ
โ โ Type: Person โ โ
โ โ Verification: Dentity โ โ โ
โ โ KG node: /g/11z806my44 (2026-07-02) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โฒ
โ
โ 5-Layer Signals
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ookyet.eth Website โ
โ โ
โ Layer 1: Indexing API โโโโโโโโโโโโโโโโโโโโโโโ โ
โ Layer 2: Schema.org @graph โโโโโโโโโโโโโโโโโโค โ
โ Layer 3: Dentity Unique Human โโโโโโโโโโโโโโโค โ
โ Layer 4: Entity Graph Linkage โโโโโโโโโโโโโโโค โ
โ Layer 5: Cross-Platform sameAs linkage โโโโโโ โ
โ โ
โ Result: KG Person node minted on 2026-07-02 โ
โ (KP triggering is Google's black-box decision) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Key Technologies
- ENS (Ethereum Name Service) - Blockchain naming system
- Dentity - Unique Human KYC verification
- Schema.org - Structured data standard
- Google Indexing API - Direct indexing submission
- IndexNow - Multi-search-engine indexing protocol
Community
- Issues: actionable, verifiable suggestions only (observability/privacy/minimization). For ideas, use Discussions.
- Labels:
proposal:observability,privacy-reviewed,wontfix:ranking.
Use Cases
Individual identity
- Publish structured Person/Organization markup tied to an ENS name
- Express on-chain ownership and optional third-party verification in
identifier/hasCredential - Link a canonical website and social profiles via
sameAs
Web3 / Web2 interoperability
- Document a repeatable pattern for aligning on-chain names with a public site
- Provide cross-source consistency signals search engines can parse
Search engines
- Machine-readable entity graphs (
@graph, ProfilePage, Person) - Optional proof-of-personhood credentials where applicable
- Explicit cross-platform linkage for entity disambiguation
Case Study: ookyet.eth
The complete implementation demonstrates:
- ENS Ownership Proof
- Dentity Verification
- NFT Avatar Integration
- Search indexing and markup
mainEntity โ Person on the about page
- Consistent cross-platform sameAs + verifiable identifier/hasCredential
Full Technical Breakdown: https://ookyet.com/blog/identity-through-ens/ Proof hub: https://ookyet.com/proof/
Getting Started
Prerequisites
- ENS domain (register at app.ens.domains)
- Dentity verification (dentity.com)
- Website/Hugo site
- Google Cloud service account
Quick Start
The fastest path is to fork this repository and adapt the reference schema to your own identity:
- Fork this repo โ you'll be editing the schema examples and scripts to match your identity, so start from your own copy.
- Replace the placeholder values in
examples/schema-person.json: your domain (yoursite.com), your ENS name (yourname.eth), and your handle (@yourhandle). - Serve the JSON-LD server-side as a single
@graphโ one source of truth, no client-side injection (implementation guide). - Verify, then submit: pass the Rich Results Test with zero errors, then accelerate indexing with the Indexing API and IndexNow scripts in
scripts/. - Bind your off-site profiles โ LinkedIn, ORCID, GitHub โ to the same name/handle pair (guide, Step 4.3).
Advanced Setup
- ProfilePage (
mainEntityโ Person) on the about page - Person-first entity model (name = person/handle; ENS in
alternateName+identifier) - Cross-platform unification and off-site co-occurrence (guide, Step 4.3)
- Image structured data for the Google Images surface (guide, Advanced Optimization)
- Monitoring with kg-audit.sh
Resources
- Reference example: ookyet.eth
- Technical Blog: Identity Through ENS
- ENS Domains: app.ens.domains
- Dentity KYC: dentity.com
- Google Indexing API: Google Documentation
Contributing
Improvements welcome. See CONTRIBUTING.md for scope, process, and issue policy.
Git commit guard setup:
git config core.hooksPath .githooks
chmod +x .githooks/commit-msg scripts/commit-message-guard.sh
License
MIT License.
Disclaimer
This project is independent documentation. It is not affiliated with, endorsed by, or sponsored by Google, the Ethereum Name Service (ENS), Dentity, Microsoft, or Yandex; all trademarks and product names are the property of their respective owners. Search result appearance โ including Knowledge Panels โ is determined solely by the search engines and is not guaranteed by anything in this repository. Nothing here is financial, legal, or investment advice.
Reference implementation: ookyet.eth.