Grid model
A Grid is the canonical JSON document for one verifiable profile. It is validated by grid.schema.json and versioned as gridz/1.0.0.
Top-level shape
{
"schema_version": "gridz/1.0.0",
"subject": { "type": "human", "did": "did:…", "ens": "kevin.gridz.eth" },
"theme": { "background_type": "solid", … },
"cells": [ … ],
"root_attestation": { "format": "eas-onchain", … }
}| Field | Required | Role |
|---|---|---|
schema_version | yes | Pins the model. Currently the constant gridz/1.0.0. |
subject | yes | Who this Grid describes — human, agent, or organization. |
theme | yes | Renderer theme (colors, fonts, card style). May derive from ENSIP-18 theme cell. |
cells | yes | Array of signed fields. May be empty; Grid still valid with zero cells. |
root_attestation | yes | Binds the full cell set via a merkle root over cell attestation UIDs. See Canonicalization. |
Subject
The subject identifies the entity the Grid belongs to. The did is authoritative; human-readable names like ens or sns are optional conveniences that MUST resolve via real lookup — they are never assumed without verification.
| Property | Values | Notes |
|---|---|---|
type | human | agent | organization | Drives renderer affordances (e.g. agent endpoints, org token widgets). |
did | W3C DID | Supported methods include did:pkh, did:ethr, did:web, did:key, did:oneclaw. Hash domain (keccak vs sha256) follows the signing curve. |
ens | string | e.g. kevin.gridz.eth on gridz.bio. When present, typically attested as its own cell. |
display_name | string | Non-authoritative label. The alias cell is the signed display name. |
Theme
Themes control how a Grid renders: background, accent colors, typography, and card chrome. Renderers enforce WCAG 4.5:1 contrast and fall back when a theme fails accessibility checks.
Required properties:
background_type—solid,gradient, orimagebackground_value— color, CSS gradient, or image URLaccent_color,text_color— CSS colors (hex, rgb, hsl)card_style—rounded,sharp, orsoftcard_background,font_family
Optional show_gridz_badge (default true) controls attribution on rendered pages.
Cell
A cell is one signed key-value field on the profile layout. Each cell carries its own attestation envelope — verification never chains through sibling cells.
{
"id": "cell-alias-1",
"key": "alias",
"value": "Kevin",
"position": { "x": 0, "y": 0, "w": 2, "h": 1 },
"size": "2x1",
"is_visible": true,
"attestation": {
"format": "eas-onchain",
"uid": "0x…",
"uri": "eas://8453/0x…",
"attester": "did:pkh:eip155:8453:0x…",
"iat": "2025-06-01T12:00:00Z",
"value_hash": "0x…"
}
}| Field | Purpose |
|---|---|
id | Stable opaque identifier, unique within the Grid (1–128 chars). |
key | Field name. See Standard keys. Dynamic keys matching the regex are first-class. |
value | JSON-serializable payload. Shape constrained per-key by widget schemas. Big integers MUST be strings, not JSON numbers. |
widget_type | Optional render hint (e.g. gridz.poll). Unknown types use the Generic renderer. |
position / size | Bento layout: grid coordinates { x, y, w, h } and size hint like 2x1. |
is_visible | Render-only flag. Hidden cells still count toward the merkle tree and cellCount. |
expires_at | Optional ISO-8601 deadline. After expiry the cell shows as expired (amber), not invalid. |
attestation | Required on published Grids. Self-describing proof for this cell's value. |
Authoring-only flags
These MUST NOT appear on published Grids. Validators and gridz grid validate reject them at publish time.
_needs_input: true— template placeholder; operator must fill the value._unattested: true— imported from ENS or another sink but not yet signed.
gridId
Every cell and the root share a stable 32-byte gridId, independent of cell contents so the identity persists across edits:
gridId = H( JCS({ "did": subject.did, "schema_version": grid.schema_version }) )On EVM chains H is keccak256. See Canonicalization for the full derivation.
One Grid per identity
A DID maps to at most one active Grid at a time. Publishing a new cell updates the resolver mapping for that key; the root attestation (when used) commits to the full current cell set. gridz.bio reads the resolver on Base and assembles the Grid JSON for rendering and API responses.