Wikifreedia
All versions

= Forms

This NIP provides a way to implement forms on Nostr using parametrized replaceable events. They can be used for surveys, voting, product/service purchases, job applications, grants, or other formal applications.

== Form Definition

Event kind 30168 describes a form as a parametrized replaceable event, with field tags that contain the description of each form field.

{
  "kind": 30168,
  "content": "",
  "tags": [
    ["d", "<form identifier>"],
    ["name", "Name of the form"],
    ["description", "Detailed description of what this form is for"],
    ["c", "application"],
    ["t", "job"],
    ["t", "developer"],
    ["t", "remote"],
    ["settings", JSON.stringify({
      "description": "Additional form settings and metadata"
    })],
    ["field", "age", "text", "What is your age?", "", JSON.stringify({
      "required": true,
      "type": "number"
    })],
    ["field", "experience", "option", "Years of experience", 
      JSON.stringify([
        ["junior", "0-2 years"],
        ["mid", "2-5 years"],
        ["senior", "5+ years"]
      ]),
      JSON.stringify({
        "required": true
      })
    ]
  ],
  "pubkey": "<Author of the form>"
}

The form event uses the following tags:

  • d: Unique identifier for the form, used to make the event replaceable
  • name: Display name of the form (for backward compatibility)
  • description: Detailed explanation of the form’s purpose and context
  • c: Category of the form (poll, purchase, or application)
  • t: Topic tags for categorizing and searching forms
  • settings: JSON object containing form-wide settings and metadata
  • field: One or more field definitions (see Field Tag Structure below)

== Form Response

Event kind 1069 is used to submit responses to a form. The response references the original form using an a tag and contains the submitted data in response tags.

{
  "kind": 1069,
  "content": "",
  "tags": [
    ["a", "30168:form-author:form-identifier", "wss://relay.example.com"],
    ["p", "form-author-pubkey", "wss://relay.example.com"],
    ["response", "age", "28", "{}"],
    ["response", "experience", "mid", "{}"],
    ["response", "motivation", "I have been following the project for a while and would love to contribute to its development. I have experience with similar technologies and am excited about the opportunity to work with the team.", "{}"],
    ["response", "skills", "javascript;typescript;react", "{}"],
    ["response", "availability", "full-time", "{}"],
    ["response", "timezone", "UTC+1", "{}"],
    ["response", "portfolio", "https://github.com/username", "{}"],
    ["response", "references", "{\"name\":\"John Smith\",\"role\":\"Previous Team Lead\",\"contact\":\"john@example.com\"}", "{}"]
  ],
  "pubkey": "Author of Response"
}

For multiple-choice fields, the response values are delimited by semicolons. For complex objects like references, the value is stringified JSON.

== Field Tag Structure

A field tag is described as: ["field", FieldId, InputType, Label, Options, Field Settings]

  • FieldId: Alphanumeric identifier for the field
  • InputType: One of “text”, “option”, “label”
  • Label: Description or question for the field
  • Options: Stringified array of options for option-type fields
  • Field Settings: Stringified JSON with field metadata (required, prerequisites, etc.)

== Options Structure

For option-type fields, the options array is stringified and contains option tags in the format: [OptionId, Label, OptionalConfig]

== Categories

The c tag specifies the form category. For example:

  • poll: For surveys and voting
  • purchase: For product/service purchases with additional fields
  • application: For job applications, grants, or other formal applications

== Client Behavior

  • Clients SHOULD validate form submissions against the field definitions
  • Clients SHOULD respect field settings like “required” and “prerequisites”
  • Clients MAY implement additional input types by extending the text type

Other authors

No one else has published this topic yet.