1 Overview
The NIP repository marks this NIP unrecommended: it adds unnecessary burden for little gain. Every relay and client must carry extra validation logic for a feature few users need. Do not build new software on it. For the main use case — keeping the root key off everyday devices — use NIP-46 remote signing instead. This chapter documents the scheme for readers who meet it in old events.
Every event carries the pubkey of the key that signed it (NIP-01). Normally that key is the user's one identity key. This NIP lets a delegator authorize a second keypair, the delegatee, to sign events for it.
The delegator signs a short authorization string once. The signature is called the delegation token. The delegatee attaches the token to each event it signs. Clients then display those events as if the delegator published them.
The intended use was root-key hygiene. A user keeps the root keypair in cold storage. The user generates a fresh keypair for each client and delegates to it. If one client leaks its key, the root key stays safe and the delegation expires.
2 The delegation Tag
This NIP introduces one new tag: delegation. The delegatee adds it to each delegated event. The tag has exactly four elements:
[ "delegation", <pubkey of the delegator>, <conditions query string>, <delegation token: 64-byte Schnorr signature of the sha256 hash of the delegation string> ]
| Index | Element | Rule |
|---|---|---|
| 0 | tag name | The literal string delegation. |
| 1 | delegator pubkey | The public key of the account that granted the delegation. |
| 2 | conditions query string | Limits on what the delegatee may sign. See §4. |
| 3 | delegation token | 64-byte Schnorr signature, hex. Made by the delegator. See §3. |
The event itself stays a normal NIP-01 event. Its pubkey is the delegatee's key. Its sig is the delegatee's signature. Only the tag links it to the delegator.
3 The Delegation Token
The delegation token proves that the delegator approved this delegatee and these conditions. To create it, the delegator builds the delegation string:
nostr:delegation:<pubkey of publisher (delegatee)>:<conditions query string>
Hash the delegation string with sha256. Sign the hash with the delegator's private key. The signature is a 64-byte Schnorr signature, the same scheme as event signatures. That signature is the delegation token. Place it at index 3 of the delegation tag.
The delegation string names the delegatee. The tag names the delegator. Do not swap them. A token signed over the wrong pubkey verifies for nobody.
4 The Conditions Query String
The conditions query string limits the delegation. A condition is one supported field plus one supported operator. Combine multiple conditions with &. You may repeat the same field. The supported fields and operators are:
| Field | Operator | Meaning |
|---|---|---|
| kind | =${KIND_NUMBER} | The delegatee may only sign events of this kind. |
| created_at | <${TIMESTAMP} | The delegatee may only sign events created before this timestamp. |
| created_at | >${TIMESTAMP} | The delegatee may only sign events created after this timestamp. |
These condition strings are all valid:
kind=1&created_at<1675721813 kind=0&kind=1&created_at>1675721813 kind=1&created_at>1674777689&created_at<1675721813
For almost every use case, follow both rules. One: include a created_at after condition set to the current time. This stops the delegatee from publishing historic notes in the delegator's name. Two: include a created_at before condition that is not empty and not in the far future. An unbounded delegation carries the same risk as handing out the root key.
The spec says conditions "must be combined with &" but never defines the logic between them. Read as AND, the valid example kind=0&kind=1 can never match: no event has two kinds. The intended reading is OR between repeated kind conditions, but the text does not say so. A fix (PR #208) was merged in 2023-02 and reverted five days later. The ambiguity remains.
5 Validation and Display
Treat an event as a valid delegation only when both checks pass:
- The event satisfies every condition in the tag's query string. In the worked example:
kind=1,created_at>1674834236, andcreated_at<1677426236. - The delegation token verifies against the delegator's pubkey. The verified conditions must be unchanged from the original delegation string.
Clients should display a valid delegated note as if the delegator published it directly. The delegatee's key does not appear in the UI.
The spec does not say who performs these checks — relay, client, or both. It only says the event "should be considered" valid. In practice both sides must verify, or a forged token slips through. This vagueness is part of why the NIP is deprecated.
6 Relay and Client Support
Two relay rules make delegation usable:
| Rule | Behavior |
|---|---|
| query | Answer a request such as ["REQ", "", {"authors": ["A"]}] by matching both the event pubkey and the delegator pubkey at index 1 of delegation tags. |
| delete | Relays SHOULD allow the delegator to delete events that the delegatee published. See NIP-09 for deletion requests. |
Without the query rule, a follower of the delegator never sees delegated notes. The follower's authors filter names the delegator, but the events carry the delegatee's pubkey.
7 Worked Example
Two keypairs take part. The delegator holds the root identity. The delegatee is a fresh client key.
# Delegator: privkey: ee35e8bb71131c02c1d7e73231daa48e9953d329a4b701f7133c8f46dd21139c pubkey: 8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd # Delegatee: privkey: 777e4f60b4aa87937e13acc84f7abcc3c93cc035cb4c1e9f7a9086dd78fffce1 pubkey: 477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396
The delegator grants note-publishing rights to the delegatee (477318cf) for the next 30 days. The current timestamp is 1674834236. The delegation string is:
nostr:delegation:477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396:kind=1&created_at>1674834236&created_at<1677426236
The delegator (8e0d3d3e) signs the sha256 hash of that string. The result is the delegation token:
6f44d7fe4f1c09f3954640fb58bd12bae8bb8ff4120853c4693106c82e920e2b
898f1f9ba9bd65449a987c39c0423426ab7b53910c0c6abfb41b30bc16e5f524
The delegatee now constructs an event on behalf of the delegator. The delegatee signs it with its own private key and publishes it:
{
"id": "e93c6095c3db1c31d15ac771f8fc5fb672f6e52cd25505099f62cd055523224f",
"pubkey": "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396",
"created_at": 1677426298,
"kind": 1,
"tags": [
[
"delegation",
"8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd",
"kind=1&created_at>1674834236&created_at<1677426236",
"6f44d7fe4f1c09f3954640fb58bd12bae8bb8ff4120853c4693106c82e920e2b898f1f9ba9bd65449a987c39c0423426ab7b53910c0c6abfb41b30bc16e5f524"
]
],
"content": "Hello, world!",
"sig": "633db60e2e7082c13a47a6b19d663d45b2a2ebdeaf0b4c35ef83be2738030c54fc7fd56d139652937cdca875ee61b51904a1d0d0588a6acd6168d7be2909d693"
}
The event is a valid delegation. It is kind 1. Its created_at of 1677426298 sits inside the allowed window. The token verifies and the conditions are unchanged. A client shows this note as posted by 8e0d3d3e, the delegator.
The example's created_at of 1677426298 is 62 seconds after the created_at<1677426236 limit in its own delegation tag. Read strictly, the spec's own example event fails its own conditions. The surrounding text still calls it valid. The mismatch was never fixed.
8 Version History
NIP-26 lived for under three years as an active proposal. Adoption stayed low, and remote signing (NIP-46) covered the key-hygiene use case with less protocol burden. Notable changes, newest first:
- 20262026-05The "unrecommended: adds unnecessary burden for little gain" warning was stamped into the NIP body.
- 20252025-12Added the
relaytag to the status line (#2173). - 20252025-04Formally deprecated: marked
unrecommended(#1051, Vitor Pamplona). - 20232023-06Added advice to bound the
created_atbefore-condition; unbounded delegations equal root-key risk. - 20232023-04Relays SHOULD allow the delegator to delete events published by the delegatee.
- 20232023-02Naming of token and string made consistent. A multiple-
kindsemantics fix (#208) was merged, then reverted. - 20232023-01Documented the valid fields and operators for the conditions string (#194). Example changed to expire at a future date (#157).
- 2023+2023-2025Typo, header-style, and author-list cleanups.
- 20222022-08Revised after community feedback, three weeks in.
- Origin2022-08-04Mark Harding published the first draft of Delegated Event Signing.
Original Proposal - Credits
| Author | Mark Harding |
| First commit | 2022-08-04 — “First draft of Delegated Event Signing” |
| Status | draft - unrecommended - optional - relay — deprecated, do not implement |
| Source | 26.md on GitHub - full change history |
9 See Also
- NIP-01 — the event format,
pubkey,sig, and the Schnorr signature scheme this NIP reuses. - NIP-46 — remote signing; the living replacement for the key-protection use case.
- NIP-09 — deletion requests; the mechanism behind the delegator-delete rule in §6.
- NIP-07 — browser signer extensions; another way to keep private keys out of clients.