NIPs by PolleramaCommunity NIPs, surfaced by trustConnect
npub1kg4sdvz3l4f...

Scheduler DVM

Published Jun 8, 2026
kind 5905kind 7000kind 31990

NIP Scheduler DVM

draft optional

This NIP defines a privacy-preserving protocol for scheduling Nostr events to be published at a future time, using a Data Vending Machine (NIP-90) as the scheduling backend.

Motivation

Publishing a Nostr event at a future time requires an always-online server. This NIP standardizes the interaction between a client and a Scheduler DVM so that:

  • Any client can schedule any signed event without implementing its own server
  • Multiple Scheduler DVMs can exist and compete (self-hostable, open market)
  • No observer or relay can link a scheduled job to its future published event
  • No observer or relay can read the content or the target publication time of a scheduled job
  • The DVM operator can read the scheduled event content and publication time after decryption

Roles

  • Client: the Nostr user who wants to schedule an event
  • Scheduler DVM: an always-online service that publishes the signed event at the requested time

Kinds

KindDescription
5905Schedule job request (client -> DVM)
7000Job feedback (DVM -> client)
5Delete / cancel a job (standard Nostr delete)

1. Creating a Schedule

The client publishes a kind:5905 job request:

{
  "kind": 5905,
  "pubkey": "<client_pubkey>",
  "content": "<nip44_encrypt(dvm_pubkey, client_privkey, payload)>",
  "tags": [
    ["p", "<dvm_pubkey>"],
    ["encrypted"]
  ]
}

Encrypted Payload

{
  "job_id": "<64 random hex chars>",
  "schedule_at": 1748000000,
  "signed_event": { "<full signed Nostr event>" },
  "relays": ["wss://relay.damus.io", "wss://nos.lol"]
}
FieldTypeRequiredDescription
job_idstringyes64-char random hex, generated by the client. Stable identifier for this job.
schedule_atunix timestampyesUTC time at which the DVM should publish the event
signed_eventobjectyesThe complete, already-signed Nostr event to publish.
relaysarray of stringsyesRelay URLs where the DVM should publish the event

2. Cancelling a Schedule

The client publishes a standard NIP-09 delete event tagging the kind:5905 to cancel:

{
  "kind": 5,
  "tags": [
    ["e", "<id of the kind:5905 event to cancel>"]
  ]
}

The DVM MUST send a kind:7000 feedback with status:cancelled after processing the deletion.

3. Listing Schedules

The client fetches its own job requests directly from relays:

{
  "authors": ["<client_pubkey>"],
  "kinds": [5905]
}

The client decrypts each event's content locally to reconstruct the list of scheduled jobs and their job_ids.

4. Job Feedback (DVM -> Client)

The DVM sends status updates using kind:7000 with no p tag to avoid linking the feedback to the client's pubkey. The content is encrypted using a one-time ephemeral keypair that the DVM destroys immediately after use.

{
  "kind": 7000,
  "pubkey": "<dvm_pubkey>",
  "content": "<nip44_encrypt(ephemeral_privkey, client_pubkey, feedback_payload)>",
  "tags": [
    ["r", "<job_id>"],
    ["ephemeral-pubkey", "<ephemeral_pubkey>"]
  ]
}

Feedback Payload (decrypted content)

{
  "status": "scheduled",
  "message": "<optional human-readable string>"
}
StatusDescription
scheduledDVM has accepted and queued the job
publishedThe event has been broadcast to the requested relays
failedAll relays rejected or were unreachable
cancelledThe job was cancelled via kind:5
errorThe job request was invalid

5. DVM Discoverability (NIP-89)

Scheduler DVMs SHOULD announce themselves using NIP-89:

{
  "kind": 31990,
  "pubkey": "<dvm_pubkey>",
  "content": "{\"name\": \"My Scheduler DVM\", \"about\": \"Schedule any Nostr event.\"}",
  "tags": [
    ["k", "5905"],
    ["t", "scheduler"]
  ]
}