OrganizationMembershipRequest schema
Generated from the canonical schema
schemas/organization-membership-request.schema.jsonbyscripts/generate-schema-docs.mjs— do not edit this page by hand.
A User's request to join an Organization, resolved by an Organization admin. At most one pending request per user/Organization; active members cannot request; the requester may cancel their own pending request; resolved requests remain historical and cannot be re-resolved; a pending request is automatically marked superseded when membership arrives through another route. Approval creates exactly one OrganizationMembership (established_via request_approval).
Schema version: 1.0.0 · $id: https://tokensforprogress.org/schemas/organization-membership-request.schema.json
Fields
id
Type: string · Required: yes · Mutable: no · Pattern: ^req_[0-9a-z]{10,32}$
Stable opaque identifier.
Example: "req_01jf93aa1jown"
organization_id
Type: string · Required: yes · Mutable: no · Pattern: ^org_[0-9a-z]{10,32}$
The Organization being asked to join.
Example: "org_01jf90aa1mit0"
user_id
Type: string · Required: yes · Mutable: no · Pattern: ^usr_[0-9a-z]{10,32}$
The requesting User.
Example: "usr_01jf8xw3tempo"
status
Type: pending | approved | declined | cancelled | superseded · Required: yes · Mutable: yes
pending → approved/declined (by an admin), cancelled (by the requester), or superseded (membership was established through another route — domain email, admin add, or invite — while the request was pending). Terminal states are historical.
Example: "pending"
note
Type: string \| null · Required: no · Mutable: no
Optional short note from the requester, shown to admins.
Example: "Visiting researcher this term — no lab email yet."
requested_at
Type: string · Required: yes · Mutable: no
RFC 3339 UTC timestamp of the request.
Example: "2026-08-31T18:00:00Z"
resolved_at
Type: string \| null · Required: no · Mutable: yes
When the request left pending, or null while pending.
Example: null
resolved_by_user_id
Type: string \| null · Required: no · Mutable: yes · Pattern: ^usr_[0-9a-z]{10,32}$
The admin who approved/declined, or the requester for cancellations. Null while pending.
Example: null
membership_id
Type: string \| null · Required: no · Mutable: yes · Pattern: ^mem_[0-9a-z]{10,32}$
The resulting OrganizationMembership when approved; null otherwise.
Example: null
JSON Schema source
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://tokensforprogress.org/schemas/organization-membership-request.schema.json",
"title": "OrganizationMembershipRequest",
"description": "A User's request to join an Organization, resolved by an Organization admin. At most one pending request per user/Organization; active members cannot request; the requester may cancel their own pending request; resolved requests remain historical and cannot be re-resolved; a pending request is automatically marked superseded when membership arrives through another route. Approval creates exactly one OrganizationMembership (established_via request_approval).",
"x-tfp-version": "1.0.0",
"type": "object",
"additionalProperties": false,
"required": [
"id",
"organization_id",
"user_id",
"status",
"requested_at"
],
"properties": {
"id": {
"type": "string",
"pattern": "^req_[0-9a-z]{10,32}$",
"x-mutable": false,
"description": "Stable opaque identifier.",
"examples": [
"req_01jf93aa1jown"
]
},
"organization_id": {
"type": "string",
"pattern": "^org_[0-9a-z]{10,32}$",
"x-mutable": false,
"description": "The Organization being asked to join.",
"examples": [
"org_01jf90aa1mit0"
]
},
"user_id": {
"type": "string",
"pattern": "^usr_[0-9a-z]{10,32}$",
"x-mutable": false,
"description": "The requesting User.",
"examples": [
"usr_01jf8xw3tempo"
]
},
"status": {
"type": "string",
"enum": [
"pending",
"approved",
"declined",
"cancelled",
"superseded"
],
"x-mutable": true,
"description": "pending → approved/declined (by an admin), cancelled (by the requester), or superseded (membership was established through another route — domain email, admin add, or invite — while the request was pending). Terminal states are historical.",
"examples": [
"pending"
]
},
"note": {
"type": [
"string",
"null"
],
"maxLength": 280,
"x-mutable": false,
"description": "Optional short note from the requester, shown to admins.",
"examples": [
"Visiting researcher this term — no lab email yet."
]
},
"requested_at": {
"type": "string",
"format": "date-time",
"x-mutable": false,
"description": "RFC 3339 UTC timestamp of the request.",
"examples": [
"2026-08-31T18:00:00Z"
]
},
"resolved_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"x-mutable": true,
"description": "When the request left pending, or null while pending.",
"examples": [
null
]
},
"resolved_by_user_id": {
"type": [
"string",
"null"
],
"pattern": "^usr_[0-9a-z]{10,32}$",
"x-mutable": true,
"description": "The admin who approved/declined, or the requester for cancellations. Null while pending.",
"examples": [
null
]
},
"membership_id": {
"type": [
"string",
"null"
],
"pattern": "^mem_[0-9a-z]{10,32}$",
"x-mutable": true,
"description": "The resulting OrganizationMembership when approved; null otherwise.",
"examples": [
null
]
}
}
}