OrganizationDomain schema
Generated from the canonical schema
schemas/organization-domain.schema.jsonbyscripts/generate-schema-docs.mjs— do not edit this page by hand.
A verification-bearing relationship between an Organization and an institutional domain. Created on first successful verification — merely claiming a domain reserves nothing. Cardinality is one-to-one for v0: at most one Organization holds a non-revoked relationship to a given domain, and an Organization has at most one non-revoked canonical domain (alias/additional domains are a deliberate later extension). DNS-verified domain control can be established by any authenticated User — including one who is not yet an Organization admin — and serves as the recovery path for an already-claimed Organization: the domain controller becomes an admin with the narrow authority to end other admin grants, and controller status itself can rotate: a current controller may remove another controller grant, but never the last one. The current strength is derived from the strongest non-revoked verification event: email_verified (mailbox access at the domain) or domain_controlled (DNS control, which outranks email). Commodity personal-mail domains are ineligible.
Schema version: 1.0.0 · $id: https://tokensforprogress.org/schemas/organization-domain.schema.json
Fields
id
Type: string · Required: yes · Mutable: no · Pattern: ^dom_[0-9a-z]{10,32}$
Stable opaque identifier.
Example: "dom_01jf91aa1anth"
organization_id
Type: string · Required: yes · Mutable: no · Pattern: ^org_[0-9a-z]{10,32}$
The Organization this domain relationship belongs to.
Example: "org_01jf90aa1mit0"
domain
Type: string · Required: yes · Mutable: no · Pattern: ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$
The verified domain, lowercased, exactly as verified (institutional subdomains are preserved, not silently widened to a parent domain).
Example: "example.org"
status
Type: email_verified | domain_controlled | revoked · Required: yes · Mutable: yes
Current derived verification strength. domain_controlled (DNS proof) outranks email_verified (mailbox proof). revoked relationships free the domain for another Organization.
Example: "email_verified"
created_at
Type: string · Required: yes · Mutable: no
RFC 3339 UTC timestamp of the first successful verification.
Example: "2026-08-31T18:00:00Z"
updated_at
Type: string · Required: yes · Mutable: yes
RFC 3339 UTC timestamp of the most recent status change.
Example: "2026-08-31T18:00:00Z"
JSON Schema source
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://tokensforprogress.org/schemas/organization-domain.schema.json",
"title": "OrganizationDomain",
"description": "A verification-bearing relationship between an Organization and an institutional domain. Created on first successful verification — merely claiming a domain reserves nothing. Cardinality is one-to-one for v0: at most one Organization holds a non-revoked relationship to a given domain, and an Organization has at most one non-revoked canonical domain (alias/additional domains are a deliberate later extension). DNS-verified domain control can be established by any authenticated User — including one who is not yet an Organization admin — and serves as the recovery path for an already-claimed Organization: the domain controller becomes an admin with the narrow authority to end other admin grants, and controller status itself can rotate: a current controller may remove another controller grant, but never the last one. The current strength is derived from the strongest non-revoked verification event: email_verified (mailbox access at the domain) or domain_controlled (DNS control, which outranks email). Commodity personal-mail domains are ineligible.",
"x-tfp-version": "1.0.0",
"type": "object",
"additionalProperties": false,
"required": [
"id",
"organization_id",
"domain",
"status",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"pattern": "^dom_[0-9a-z]{10,32}$",
"x-mutable": false,
"description": "Stable opaque identifier.",
"examples": [
"dom_01jf91aa1anth"
]
},
"organization_id": {
"type": "string",
"pattern": "^org_[0-9a-z]{10,32}$",
"x-mutable": false,
"description": "The Organization this domain relationship belongs to.",
"examples": [
"org_01jf90aa1mit0"
]
},
"domain": {
"type": "string",
"pattern": "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$",
"x-mutable": false,
"description": "The verified domain, lowercased, exactly as verified (institutional subdomains are preserved, not silently widened to a parent domain).",
"examples": [
"example.org"
]
},
"status": {
"type": "string",
"enum": [
"email_verified",
"domain_controlled",
"revoked"
],
"x-mutable": true,
"description": "Current derived verification strength. domain_controlled (DNS proof) outranks email_verified (mailbox proof). revoked relationships free the domain for another Organization.",
"examples": [
"email_verified"
]
},
"created_at": {
"type": "string",
"format": "date-time",
"x-mutable": false,
"description": "RFC 3339 UTC timestamp of the first successful verification.",
"examples": [
"2026-08-31T18:00:00Z"
]
},
"updated_at": {
"type": "string",
"format": "date-time",
"x-mutable": true,
"description": "RFC 3339 UTC timestamp of the most recent status change.",
"examples": [
"2026-08-31T18:00:00Z"
]
}
}
}