draft optional
Two addressable event kinds for gating workflow progression on Nostr — a proposer publishes a gate requiring sign-off, and one or more designated reviewers respond with approval, rejection, or revision requests.
Design principle: Approval gates are a coordination primitive. They communicate that sign-off is required and record decisions — they do not enforce access control. Enforcement is the responsibility of the consuming application.
Standalone. This NIP works independently on any Nostr application.
Nostr has events for publishing content, sending messages, and making payments, but no standard mechanism for gating progress on a decision. Many real-world workflows require explicit sign-off before the next step can proceed:
- Pull request reviews — a maintainer must approve before merging
- Content moderation — an editor must approve before publishing
- Grant applications — a committee must approve before funding
- Procurement — a budget holder must approve before purchasing
- Inspections — a qualified inspector must sign off before work continues
Without a standard, every application invents its own approval scheme with incompatible tag conventions. NIP-APPROVAL provides a minimal, composable primitive that any Nostr application can adopt for structured decision-making.
- NIP-25 (Reactions): Reactions express lightweight sentiment (
+/-) with no named reviewer set, no quorum or threshold semantics, no revision loop, and no deadline enforcement. A reaction does not encode who is required to approve; approval gates name the required reviewers upfront and track structured decisions (approved, rejected, revision requested) with mandatory reasoning. - NIP-22 (Comments): Comments carry unstructured text with no decision semantics, no gate status tracking, and no distinction between "I have thoughts" and "I formally approve." Approval responses are structured decisions, not discussion.
| kind | description |
|---|---|
| 30570 | Approval Gate |
| 30571 | Approval Response |
Both kinds are addressable events (NIP-01). The d tag format ensures each event occupies a unique slot, allowing updates via republication.
Published by a proposer to create a gate requiring one or more reviewers to sign off. Addressable — the proposer can update the proposal before a final decision is recorded.
{
"kind": 30570,
"pubkey": "<proposer-hex-pubkey>",
"created_at": 1698765000,
"tags": [
["d", "pr_review_42:gate:code_review"],
["t", "approval-gate"],
["alt", "Approval gate: code review for PR #42"],
["gate_type", "review"],
["gate_authority", "<reviewer-hex-pubkey>"],
["gate_status", "pending"],
["expiration", "1699370000"]
],
"content": "PR #42 ready for review. Implements NIP-APPROVAL event kinds.",
"id": "<32-bytes lowercase hex>",
"sig": "<64-bytes lowercase hex>"
}Tags:
d(REQUIRED): Addressable event identifier. RECOMMENDED format:<context_id>:gate:<sequence>. Applications MAY use any d-tag format that ensures uniqueness.t(RECOMMENDED): Protocol family marker. RECOMMENDED value:"approval-gate".gate_type(REQUIRED): Type of gate. Primary values:review,approval. Applications MAY define additional gate types such asregulatory,inspection, or other domain-specific values.gate_authority(REQUIRED, one or more): Hex pubkey of a required reviewer. Multiplegate_authoritytags indicate that all listed reviewers must respond (see Multi-Reviewer Gates below).gate_status(REQUIRED): MUST be"pending"on creation.expiration(RECOMMENDED): Unix timestamp — deadline for the review. Clients SHOULD use NIP-40expirationfor relay-level enforcement.p(RECOMMENDED): Additional parties to notify.gate_reference(OPTIONAL): External reference (certificate number, permit ID, PR URL).ref(OPTIONAL): Cross-application external reference.e(OPTIONAL): Event ID of the event being gated (e.g. the content draft, the pull request event).
Content: Plain text or NIP-44 encrypted JSON describing what requires approval. May include specification references, inspection criteria, or submission details.
Published by a reviewer to approve, reject, or request revision of a gated proposal. The d tag format allows one response per reviewer per gate.
{
"kind": 30571,
"pubkey": "<reviewer-hex-pubkey>",
"created_at": 1698766000,
"tags": [
["d", "pr_review_42:gate:code_review:response:<reviewer-hex-pubkey>"],
["t", "approval-response"],
["alt", "Approval response: approved for code review"],
["e", "<gate-event-id>", "wss://relay.example.com"],
["decision", "approved"],
["p", "<proposer-hex-pubkey>"],
["gate_reference", "REVIEW-2026-0042"]
],
"content": "Code looks good. Approved with no changes required.",
"id": "<32-bytes lowercase hex>",
"sig": "<64-bytes lowercase hex>"
}Tags:
d(REQUIRED): Format<gate_d_tag>:response:<reviewer_pubkey>. One response per reviewer per gate.t(REQUIRED): Protocol family marker. MUST be"approval-response".e(REQUIRED): Event ID of the Kind 30570 gate being responded to.decision(REQUIRED): The reviewer's decision. One of"approved","rejected", or"revise".p(RECOMMENDED): Proposer's pubkey (for notification).gate_reference(OPTIONAL): External reference (inspection report number, review ID).revision_notes(OPTIONAL): Feedback when decision is"revise".
Content: Plain text or NIP-44 encrypted JSON with the reviewer's notes, findings, or conditions.
Proposer Relay Reviewer(s)
| | |
|-- kind:30570 Gate -------->| |
| (gate_status: pending) | |
| |------- notification ------>|
| | |
| |<-- kind:30571 Response ----|
| | (decision: revise) |
|<------ notification -------| |
| | |
|-- kind:30570 Gate -------->| (updated proposal) |
| |------- notification ------>|
| | |
| |<-- kind:30571 Response ----|
| | (decision: approved) |
|<------ notification -------| |
| | |
| Proceed to next phase | |
- Gate: Proposer publishes
kind:30570withgate_status: pendingand one or moregate_authoritytags identifying the required reviewers. - Review: Each reviewer evaluates the proposal and publishes
kind:30571with theirdecision. - Revision (optional): If a reviewer requests revision (
decision: revise), the proposer updates theirkind:30570event with revisions, and the reviewer evaluates again. - Resolution: The gate is resolved when all required reviewers have published a final
approvedorrejectedresponse. If any reviewer rejects, the gate is rejected.
The following diagram illustrates the gate state transitions:
flowchart TD
classDef green fill:#1b3d2d,stroke:#16c79a,color:#f0f0f0
classDef yellow fill:#2d2d1b,stroke:#f5a623,color:#f0f0f0
classDef blue fill:#1b2d3d,stroke:#0f3460,color:#f0f0f0
classDef red fill:#3d1b1b,stroke:#e94560,color:#f0f0f0
CREATE([Proposer publishes<br/>kind:30570 Gate<br/>gate_status: pending]):::blue
CREATE --> PENDING
PENDING[PENDING<br/>Awaiting reviewer responses]:::yellow
PENDING --> RESPONSE{Reviewer publishes<br/>kind:30571 Response}:::blue
RESPONSE -- "decision: revise" --> REVISION[REVISION REQUESTED<br/>Proposer updates<br/>kind:30570 with changes]:::yellow
REVISION --> PENDING
RESPONSE -- "decision: rejected<br/>(any reviewer)" --> REJECTED([REJECTED]):::red
RESPONSE -- "decision: approved" --> CHECK{All gate_authority<br/>reviewers approved?}:::yellow
CHECK -- "No, still waiting<br/>on other reviewers" --> PENDING
CHECK -- "Yes, all approved" --> APPROVED([APPROVED<br/>Proceed to next phase]):::green
PENDING -- "expiration reached<br/>without resolution" --> EXPIRED([EXPIRED]):::red
When multiple reviewers must approve, the proposer publishes multiple gate_authority tags on the Kind 30570 event. Each reviewer publishes their own Kind 30571 response. The gate is considered approved only when all listed authorities have published approved responses. If any reviewer publishes rejected, the gate is rejected. Clients SHOULD track the set of outstanding approvals and display progress.
A Nostr-native Git collaboration tool can use approval gates to model pull request reviews. The proposer creates a kind:30570 gate referencing the PR, with the maintainer's pubkey as gate_authority. The maintainer reviews and publishes kind:30571 with their decision. CI/CD systems can subscribe to approval responses to trigger automated merges.
A Nostr publishing platform can gate article publication behind editorial approval. Authors submit drafts as kind:30570 gates with gate_type: review. Editors respond with kind:30571 — approving for publication, rejecting, or requesting revisions. The revision flow allows iterative editing before final sign-off.
A decentralized grant program can use approval gates for application review. Applicants publish kind:30570 with the grant committee members as gate_authority tags. Committee members independently review and vote. The multi-reviewer gate model ensures all required approvals are recorded before funds are released.
Any application requiring regulatory approval (building permits, food safety certificates, financial compliance checks) can use approval gates to record the decision. The gate_reference tag links to external regulatory identifiers, creating an auditable trail on Nostr.
All examples use timestamps around 1709280000 (2024-03-01) and placeholder hex pubkeys.
A regulatory inspection gate requiring sign-off from 2 authorities before work can proceed.
{
"kind": 30570,
"pubkey": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"created_at": 1709280000,
"tags": [
["d", "site_inspection_007:gate:structural_review"],
["t", "approval-gate"],
["alt", "Approval gate: structural inspection requiring two reviewers"],
["gate_type", "inspection"],
["gate_authority", "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3"],
["gate_authority", "c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"],
["gate_status", "pending"],
["expiration", "1709366400"],
["gate_reference", "INSP-2024-0307"]
],
"content": "Structural inspection required before phase 2 construction can begin. Both inspectors must sign off.",
"id": "<32-byte-hex>",
"sig": "<64-byte-hex>"
}An "approved" response from one of the gate authorities.
{
"kind": 30571,
"pubkey": "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3",
"created_at": 1709283600,
"tags": [
["d", "site_inspection_007:gate:structural_review:response:b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3"],
["t", "approval-response"],
["alt", "Approval response: structural inspection approved"],
["e", "aaaa1111bbbb2222cccc3333dddd4444eeee5555ffff6666aaaa1111bbbb2222", "wss://relay.example.com"],
["decision", "approved"],
["p", "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"],
["gate_reference", "INSP-2024-0307-A"]
],
"content": "Structural integrity confirmed. Foundation and load-bearing walls meet specification.",
"id": "<32-byte-hex>",
"sig": "<64-byte-hex>"
}- Authority verification. Implementations MUST verify that Kind 30571 responses are signed by a pubkey listed in the corresponding Kind 30570's
gate_authoritytags. Responses from unauthorised pubkeys MUST be ignored. - Replay protection. The addressable
dtag format (one response per reviewer per gate) prevents duplicate approvals. Relays SHOULD store only the latest response from each reviewer. - Expiration enforcement. Gates with an
expirationtag SHOULD be considered expired after the deadline. Clients MUST NOT accept approval responses published after the gate's expiration timestamp. - Content encryption. When gate content is sensitive (e.g. financial details, personal information), the
contentfield SHOULD be NIP-44 encrypted to the gate authority and proposer. - Immutability after decision. Once a reviewer publishes an
approvedorrejectedresponse, the proposer SHOULD NOT update the Kind 30570 event. Clients MAY warn if the gate content changes after a final decision has been recorded.
- NIP-01: Basic protocol flow, addressable events
- NIP-40: Expiration timestamps (gate deadlines)
- NIP-44: Versioned encrypted payloads (sensitive gate content)
No public reference implementation exists yet. Implementors SHOULD refer to the kind definitions above.
A minimal implementation requires:
- A Nostr client that supports addressable event publishing.
- Logic to track gate state by aggregating Kind 30571 responses per Kind 30570 gate.
- Authority verification to ensure only designated reviewers' responses are counted.