JSON Schema definitions for Nostr protocol events, messages, and tags. Validate Nostr data structures in any programming language.
Quick Links: Installation • Quick Start • Available Schemas • Contributing • Build From Source
JSON-Schema has the most active, widely supported specification standard, with the largest community and ecosystem. Most importantly, it is one of the few schema specification standards that support deep specification of strings (via formats or regex), making the nostresque typing of strings and the tuples that contain them possible. There are schema validators and generators [schema-to-code] for Server Stubs and Client-SDKs available in every single language provided by the JSON-Schema community. The wide availability of JSON-Schema tooling lends itself to creating a system that caters specifically to the requirements of nostr as well as creating an extensible and maintainable system; which is why this exists.
In a nutshell JSON-Schema validates that the structure of the JSON blob is correct. JSON-Schema for a particular kind returns either a pass, or a fail. Whereas test vectors are a deterministic check - a certain input is made, and a certain output is expected. JSON blob validation does not preclude test vectors approach. Test vectors are outside the scope of schemata.
A complementary, and tangential to schemata nostr-test-vector suite can be found here.
Draft-07 to maximize interoperability, and simplicity.
- Integration Testing of both Clients and Relays
- Discovering broken events through fuzz testing
- As a fixture to generate dummy events that are valid
- As an input to code generation --
schemata-codegenreads the schemas and produces typed interfaces, runtime validators, and kind registries for 13 languages (TypeScript, C, C++, C#, Rust, Go, Java, Kotlin, Swift, Dart, Python, PHP, Ruby)
- Runtime validation of events where performance is critical (JSON-Schema is notoriously slow due to the breadth of the specification).
- See known limitations here. Examples include cryptographic operations, and expressions that are not possible with JSON-schema draft-07.
@fiatjaf produced a bespoke schema specification solution, registry-of-kinds. The benefit of this is that it includes only what it needs to and so its specification is drafted for nostr and so the performance is notably better. The performance improvements make it sufficient for use as a runtime validator in performance sensitive applications. The downside is that validators need to be written and maintained for all languages, tooling is non-existent so workflows that benefit maintenance and extensibility are non-existent, all kinds are specified from a single file and any generator pattern would need to be completely rewritten from scratch. A nostr-specific schema validator may prove to be the best long-term solution, with the caveat that it will take extensive development for it to reach maturity.
Note that schemata's schemata-codegen pipeline can generate native validators from JSON-Schema, combining the correctness of a standards-based specification with the performance of compiled code. For performance-sensitive use cases, schemata-codegen can generate native structural validators in 13 languages that don't use JSON-Schema at runtime.
Read this closely and please understand: Tuples of Strongly Typed Strings. Yes, Strongly Typed Strings. Strongly typing strings is kind of unique to nostr. This concept is considered absurd in conventional system design. Thus, support for "Strongly Typed Strings" does not exist basically anywhere by default, except JSON-Schemas where it kind of exists by accident ... Could we change this? Yes! Are you volunteering?
@nostrability/schemata aims to produce JSON-Schema that can be consumed by validators (for example, ajv), code generators (for example, schemata-codegen), and conformance tools. Ideally, each language would have one or more validator wrappers. The validator wrappers provide nostr specific methods to make utilization more straightforward for implementers. The original author of this repo has provided an example of this approach below
Data packages vendor the compiled JSON schemas and provide a registry lookup for each language. They are consumed by validators.
| Language | Data Package | Registry API |
|---|---|---|
| JS/TS | @nostrability/schemata (npm) |
import { kind1Schema } from '@nostrability/schemata' |
| Rust | schemata-rs |
schemata_rs::get("kind1Schema") |
| Go | schemata-go |
schemata.Get("kind1Schema") |
| Python | schemata-py |
schemata.get("kind1Schema") |
| Kotlin | schemata-kt |
Schemata.get("kind1Schema") |
| Java | schemata-java |
Schemata.get("kind1Schema") |
| Swift | (bundled in validator) | SchemataValidator.getSchema("kind1Schema") |
| Dart | schemata-dart |
Schemata.get('kind1Schema') |
| PHP | schemata-php |
Schemata::get('kind1Schema') |
| C#/.NET | schemata-csharp |
Schemata.Get("kind1Schema") |
| C++ | schemata-cpp |
schemata::get("kind1Schema") |
| Ruby | schemata-ruby |
SchemataNostr.get('kind1Schema') |
| C | schemata-c |
schemata_get("kind1Schema") |
Note: Swift uses a single-package approach (schemas inlined into the validator) because SPM resource bundles cause iOS codesign failures. See #88 for details on how this applies to future Kotlin Multiplatform support.
Validators wrap a JSON Schema library and the data package to provide nostr-specific validation methods (validateNote, validateNip11, validateMessage). Best used in CI and integration tests, not runtime hot paths.
| Language | Validator | JSON Schema Library |
|---|---|---|
| JS/TS | @nostrwatch/schemata-js-ajv |
ajv |
| Rust | schemata-validator-rs |
jsonschema |
| Go | schemata-validator-go |
jsonschema/v6 |
| Python | schemata-validator-py |
jsonschema |
| Kotlin | schemata-validator-kt |
json-schema-validator |
| Java | schemata-validator-java |
json-schema-validator |
| Swift | schemata-validator-swift |
JSONSchema.swift |
| Dart | schemata-validator-dart |
json_schema |
| PHP | schemata-validator-php |
opis/json-schema |
| C#/.NET | schemata-validator-csharp |
JsonSchema.Net |
| C++ | schemata-validator-cpp |
valijson |
| Ruby | schemata-validator-ruby |
json_schemer |
| C | schemata-validator-c |
jsonc-daccord (nostrability fork) |
Content schemas validate an event's content field. For json-stringified and plaintext encodings, they validate the decoded/raw payload. For base64 encodings, they validate the encoded string itself (pattern, length) since the decoded binary requires protocol-specific parsers beyond JSON Schema.
For json-stringified content, parse first, then validate. For kinds where content MAY be empty (kind:6, 16, 4550, 30166), check before parsing since JSON.parse('') throws:
import { kind0ContentSchema } from '@nostrability/schemata';
import Ajv from 'ajv';
import addFormats from 'ajv-formats';
const ajv = new Ajv();
addFormats(ajv);
const validate = ajv.compile(kind0ContentSchema);
// json-stringified: parse, then validate
if (event.content !== '') {
const parsed = JSON.parse(event.content);
if (!validate(parsed)) {
console.log('Content errors:', validate.errors);
}
}For plaintext and base64 content, validate the string directly — do not skip empty strings, as the content schema itself enforces any length requirements:
import { kind13194ContentSchema } from '@nostrability/schemata';
const validate = ajv.compile(kind13194ContentSchema);
// plaintext/base64: validate the string as-is
if (!validate(event.content)) {
console.log('Content errors:', validate.errors);
}| Kind | NIP/MIP | Encoding | Content |
|---|---|---|---|
| 0 | NIP-01 | json-stringified |
Profile metadata |
| 3 | NIP-02 | json-stringified |
Contact list relay map |
| 6 | NIP-18 | json-stringified |
Reposted kind:1 note |
| 16 | NIP-18 | json-stringified |
Reposted event (any kind) |
| 40 | NIP-28 | json-stringified |
Channel creation metadata |
| 41 | NIP-28 | json-stringified |
Channel metadata update |
| 4550 | NIP-72 | json-stringified |
Approved community post |
| 30166 | NIP-66 | json-stringified |
NIP-11 relay info document |
| 443 | MIP-00 | base64 |
MLS KeyPackageBundle |
| 30443 | MIP-00 | base64 |
MLS KeyPackageBundle |
| 446 | MIP-05 | base64 |
EncryptedToken(s) |
| 64 | NIP-64 | plaintext |
PGN chess notation |
| 9802 | NIP-84 | plaintext |
Highlighted text |
| 13194 | NIP-47 | plaintext |
NWC supported methods |
| 30023 | NIP-23 | plaintext |
Markdown article |
Each content schema includes an x-content-encoding property indicating the decode step:
| Encoding | Decode step | Schema validates |
|---|---|---|
json-stringified |
JSON.parse(event.content) |
Parsed object structure |
base64 |
atob(event.content) |
The encoded string (pattern, length) — decoded binary needs a protocol-specific parser |
plaintext |
None | The string directly (format, length) |
- Validators: Can add a
validateContent(kind, contentValue)method. Forjson-stringifiedkinds, pass the parsed object; forbase64/plaintext, pass the raw string. Content schemas are opt-in; existingvalidateNote/validateNip11/validateMessageare unaffected. - schemata-codegen: Can consume
x-content-encodingto generate decode+validate helpers. No breaking changes; new schemas appear as additional exports. - Data packages (schemata-rs, schemata-go, etc.): New
kind*ContentSchemakeys automatically appear in registry on next release.
@nostrability/schemata assumes a kind is associated to a NIP and so the schemas are organized by NIP. The system has aliases that are generated via the build-script. The aliases make it easier to reference commonly reused schemas (such as tags, and base schemata like note).
Schemas are conventioned. They are included in directories for support purposes (complex multi-stage validation cases) with the following directory structure (using the NIP-01 directory as an example)
.
├── kind-0
├── kind-1
├── messages
│ ├── client-close
│ ├── ...
├── note
├── note-unsigned
├── secp256k1
└── tag
├── a
├── d
├── e
├── p
└── t
Note: For payloads like NIP-11 where it breaks the general "event" or "message" pattern, just place a schema.yaml in the NIP's directory.
schemata-codegen reads the compiled schemas and generates typed interfaces, runtime validators, kind registries, and error message mappings for multiple languages. Zero dependencies.
| Output | Flag | Description |
|---|---|---|
| TypeScript types | --kinds, --out |
Typed event interfaces (177 kinds) and tag tuples (156 tags) |
| TypeScript validators | --validators |
Runtime structural validators (136 kinds) |
| C validators | --c-validators |
Generic or nostrdb-compatible (--c-api nostrdb) |
| C++ validators | --cpp-validators |
Standard C++ with STL |
| C# validators | --csharp-validators |
.NET with LINQ |
| Rust validators | --rust-validators |
Generic, nostr, or nostrdb crate (--rust-api) |
| Go validators | --go-validators |
Idiomatic Go |
| Java validators | --java-validators |
Java with streams |
| Kotlin validators | --kotlin-validators |
Idiomatic Kotlin |
| Swift validators | --swift-validators |
Swift with Foundation |
| Dart validators | --dart-validators |
Dart |
| Python validators | --python-validators |
Python 3 with dataclasses |
| PHP validators | --php-validators |
PHP 8+ |
| Ruby validators | --ruby-validators |
Ruby |
| Kind registry | --registry |
Kind number to human name mapping |
| Error messages | --errors |
AJV errorMessage enrichment keywords |
| AJV helpers | --ajv-schemas |
Pre-stripped schemas for AJV consumption |
Generic JSON-Schema stub and Client-SDK generators do not produce useful logic for tuples of typed strings, since tuples are not utilized in conventional programming as extensively as in nostr. schemata-codegen addresses this gap with a nostr-specific code generation pipeline that understands tag tuple schemas and produces native validators that don't require JSON-Schema at runtime.
- Install the npm package, download the release ZIP, or use a language-specific data package
- Validate
.jsonschemas against nostr events using a validator or generated code fromschemata-codegen
# Install the package (JavaScript/TypeScript)
npm install @nostrability/schemata
# Or download pre-built schemas for any language
curl -L https://github.com/nostrability/schemata/releases/latest/download/schemata.zip -o schemata.zipimport { noteSchema, kind1Schema } from '@nostrability/schemata';
import Ajv from 'ajv';
const ajv = new Ajv();
const validate = ajv.compile(kind1Schema);
if (validate(nostrEvent)) {
console.log('Valid event!');
} else {
console.log('Validation errors:', validate.errors);
}# Clone and setup
git clone https://github.com/nostrability/schemata.git
cd schemata
pnpm install
pnpm build
# Create new schema
mkdir -p nips/nip-XX/kind-YYYY
echo '$id: "https://schemata.nostr.watch/note/kind/YYYY"' > nips/nip-XX/kind-YYYY/schema.yaml- Event Schemas: Validate structure of all standard Nostr event kinds
- Message Schemas: Validate WebSocket messages (REQ, EVENT, OK, etc.)
- Tag Schemas: Validate event tags (e, p, a, d, t, etc.)
Beyond structural checks, schemata validates field values using 80+ regex patterns — does a signature look like a real signature? Is a relay hint actually a WebSocket URL?
| What | Validation | Example |
|---|---|---|
| Pubkeys & event IDs | 64-char lowercase hex | ^[a-f0-9]{64}$ |
| Signatures | 128-char lowercase hex | ^[a-f0-9]{128}$ |
| Relay URLs | Strict WebSocket URL | ^wss?://[a-zA-Z0-9._-]+(?::[0-9]+)?(?:/.*)?$ |
| Bech32 entities | Prefix + charset + length | ^npub1[02-9ac-hj-np-z]{58}$ |
| BOLT11 invoices | Lightning invoice format | ^lnbc[a-z0-9]*1[02-9ac-hj-np-z]+$ |
| Timestamps & amounts | Digit-only strings | ^[0-9]+$ |
schemata-codegen compiles 100% of these patterns into native, regex-free code for 13 languages — no regex engine needed at runtime. See PATTERNS.md for the full catalog.
- 📖 Using Schemas - How to integrate schemas in your project
- 🛠️ Contributing - How to add new schemas
- 🏗️ Architecture - Technical design and build process
- 🔍 Validator Compatibility - Cross-language API surface comparison
- 🔣 Pattern Reference - All 69+ value-validation patterns (hex, relay URLs, bech32, BOLT11, etc.) with native codegen ops
- 🚧 Validation Boundaries - Spec requirements that JSON Schema cannot express (cross-field constraints, decoded-value checks, cryptographic validation)
179 event kind schemas across 65 NIPs, 15 content schemas, 154 tag schemas, 13 protocol messages, and 598 samples (301 valid, 297 invalid). Codegen reads all 179 schemas from dist/; the curated list below may lag behind by a few entries.
Event Kinds
NIP-01 — Core protocol
kind-0- Profile metadatakind-1- Text note
NIP-02 — Contact list
kind-3- Contact list / follows
NIP-03 — OpenTimestamps
kind-1040- OpenTimestamps attestation
NIP-04 — Encrypted DMs (deprecated)
kind-4- Encrypted direct message
NIP-09 — Event deletion
kind-5- Event deletion request
NIP-17 — Private direct messages
kind-14- Chat message (rumor)kind-15- File headerkind-10050- Relay list for DMs
NIP-18 — Reposts
kind-6- Repostkind-16- Generic repost
NIP-22 — Comments
kind-1111- Comment
NIP-23 — Long-form content
kind-30023- Long-form articlekind-30024- Draft long-form article
NIP-25 — Reactions
kind-7- Reactionkind-17- Reaction to website
NIP-28 — Public chat
kind-40- Create channelkind-41- Channel metadatakind-42- Channel messagekind-43- Hide messagekind-44- Mute user
NIP-29 — Relay-based groups
kind-9000- Group add userkind-9001- Group remove userkind-9002- Group edit metadatakind-9005- Group delete eventkind-9007- Group createkind-9008- Group deletekind-9009- Group edit statuskind-9021- Group join requestkind-9022- Group leave requestkind-39000- Group metadatakind-39001- Group adminskind-39002- Group memberskind-39003- Group roles
NIP-32 — Labeling
kind-1985- Label
NIP-34 — Git stuff
kind-1617- Git patchkind-1618- Git issuekind-1619- Git repo announcementkind-1621- Git replykind-1630- Git status openkind-1631- Git status appliedkind-1632- Git status closedkind-1633- Git status draftkind-30617- Git repositorykind-30618- Git repository state
NIP-35 — Torrents
kind-2003- Torrentkind-2004- Torrent comment
NIP-37 — Drafts
kind-10013- Draft listkind-31234- Draft
NIP-38 — User status
kind-30315- User status
NIP-39 — External identities
kind-10011- Auth identity
NIP-42 — Authentication
kind-22242- Client authentication
NIP-43 — Fast authentication (NIP proposal)
kind-8000- Group joinkind-8001- Group invitekind-13534- Group member listkind-28934- Group add eventkind-28935- Group remove eventkind-28936- Group event list
NIP-46 — Nostr Connect
kind-24133- Nostr Connect request/response
NIP-47 — Wallet Connect
kind-13194- Wallet Connect infokind-23194- Wallet Connect requestkind-23195- Wallet Connect responsekind-23196- Wallet Connect notification (NIP-04)kind-23197- Wallet Connect notification (NIP-44)
NIP-51 — Lists (27 kinds)
kind-10000- Mute listkind-10001- Pin listkind-10003- Bookmarkskind-10004- Communities listkind-10005- Public chats listkind-10006- Blocked relays listkind-10007- Search relays listkind-10009- User groups listkind-10012- Relay feeds listkind-10015- Interests listkind-10020- Tagged events listkind-10030- Custom emoji listkind-10101- Good wiki authors listkind-10102- Good wiki relays listkind-30000- People setkind-30002- Relay setskind-30003- Bookmark setskind-30004- Curation setskind-30005- Video curation setskind-30006- Picture curation setskind-30007- Kind mute setskind-30015- Interest setkind-30030- Custom emoji setkind-30063- Release artifact setskind-30267- App curation setskind-39089- Starter packskind-39092- Media starter packs
NIP-52 — Calendar events
kind-31922- Date-based calendar eventkind-31923- Time-based calendar eventkind-31924- Calendarkind-31925- Calendar event RSVP
NIP-53 — Live activities
kind-1311- Live chat messagekind-10312- Live participation listkind-30311- Live eventkind-30312- Live event participantkind-30313- Live event draft
NIP-54 — Wiki
kind-818- Merge requestkind-30818- Wiki articlekind-30819- Wiki redirect
NIP-56 — Reporting
kind-1984- Report
NIP-57 — Zaps
kind-9734- Zap requestkind-9735- Zap receipt
NIP-58 — Badges
kind-8- Badge awardkind-30008- Profile badgeskind-30009- Badge definition
NIP-59 — Gift wrap
kind-13- Sealkind-1059- Gift wrap
NIP-5A — Git files
kind-15128- Git file blobkind-35128- Git file tree
NIP-60 — Cashu wallet
kind-7374- Cashu tokenkind-7375- Cashu proofkind-17375- Cashu quote
NIP-61 — Nutzaps
kind-7376- Nutzapkind-9321- Nutzap redemptionkind-10019- Nutzap mint preferences
NIP-62 — Request discovery relays
kind-62- User discovery relay list
NIP-64 — Inline resources
kind-64- Inline resource
NIP-65 — Relay list metadata
kind-10002- Relay list metadata
NIP-66 — Relay monitoring
kind-10166- Relay monitor registrationkind-30166- Relay monitor check
NIP-68 — Picture event
kind-20- Picture
NIP-69 — Peer-to-peer trading
kind-38383- Fiat/BTC offer
NIP-71 — Video
kind-21- Short-form portrait videokind-22- Short-form landscape videokind-34235- Video eventkind-34236- Video view
NIP-72 — Communities
kind-4550- Community post approvalkind-34550- Community definition
NIP-75 — Zap goal
kind-9041- Zap goal
NIP-78 — Application-specific data
kind-30078- App-specific data
NIP-7D — Threads
kind-11- Thread root
NIP-84 — Highlights
kind-9802- Highlight
NIP-85 — Trusted assertions
kind-10040- Provider declarationkind-30382- Trusted assertionkind-30383- Trusted assertion revocationkind-30384- Trusted assertion query
NIP-87 — Cashu mint discovery
kind-38000- Ecash mint recommendationkind-38172- Mint recommendationkind-38173- Mint info
NIP-88 — Polls
kind-1018- Poll responsekind-1068- Poll
NIP-89 — App handlers
kind-31989- App handler recommendationkind-31990- App handler
NIP-90 — Data vending machine
kind-5000- DVM text generation requestkind-5300- DVM text extraction requestkind-5301- DVM summarization requestkind-6000- DVM text generation resultkind-6300- DVM text extraction resultkind-6301- DVM summarization resultkind-7000- DVM job feedback
NIP-94 — File metadata
kind-1063- File metadata
NIP-96 — HTTP file storage
kind-10096- File storage server list
NIP-98 — HTTP Auth
kind-27235- HTTP authentication
NIP-99 — Classifieds
kind-30402- Classified listingkind-30403- Draft classified listing
NIP-A0 — Coinjoin
kind-1222- Coinjoin requestkind-1244- Coinjoin proposal
NIP-A4 — Extra-metadata gift wrap
kind-24- Extra-metadata gift wrap
NIP-B0 — Reviews
kind-39701- Review
NIP-b7 — Blossom
kind-10063- Blossom server list
NIP-C0 — Audio
kind-1337- Audio event
NIP-C7 — Group chat relay
kind-9- Group chat message
NKBIP-03 — Nostr Knowledge Base
kind-30- Web sourcekind-31- Text sourcekind-32- Academic sourcekind-33- AI source
BUD-04 — Blossom auth
kind-24242- Blossom auth token
MIP-00 — Marmot MLS
kind-443- MLS key package (deprecated, use kind-30443; cutover May 1, 2026)kind-30443- MLS key package (addressable)kind-10051- MLS key package relay list
MIP-02 — Marmot welcome
kind-444- MLS welcome message
MIP-03 — Marmot group events
kind-445- MLS group event
MIP-05 — Marmot notifications
kind-446- Notification requestkind-447- Token requestkind-448- Token list responsekind-449- Token removal
Protocol Messages (13 schemas)
Client to Relay (NIP-01):
client-req- Request events (REQ)client-event- Publish event (EVENT)client-close- Close subscription (CLOSE)
Client to Relay (NIP-42):
client-auth- Authentication (AUTH)
Client to Relay (NIP-45):
client-count- Count events (COUNT)
Relay to Client (NIP-01):
relay-event- Event delivery (EVENT)relay-ok- Command result (OK)relay-eose- End of stored events (EOSE)relay-closed- Subscription closed (CLOSED)relay-notice- Human-readable message (NOTICE)
Relay to Client (NIP-42):
relay-auth- Authentication challenge (AUTH)
Relay to Client (NIP-45):
relay-count- Count result (COUNT)
Other (NIP-01):
filter- REQ message filter object
Tags (150+ schemas)
NIP-01 — Standard tags:
e- Event referencep- Public key referencea- Replaceable event referenced- Identifier for replaceable eventst- Hashtag- Generic tag base schema
NIP-17 — DM attachment tags:
blurhash,decryption-key,decryption-nonce,dim,encryption-algorithm,fallback,file-type,ox,relay,size,subject,thumb,x
NIP-18 — Repost tags:
k- Kind number referenceq- Quote reference
NIP-22 — Comment tags (uppercase):
_E,_P,_A,_K- Uppercase event/pubkey/address/kind references
NIP-23 — Long-form tags:
published_at
NIP-25 — Reaction tags:
e-react- Reaction event referenceemoji- Custom emoji
NIP-29 — Group tags:
code- Group code
NIP-32 — Label tags:
l- LabelL- Label namespace
NIP-34 — Git tags:
applied-as-commits,branch-name,c,clone,commit,commit-pgp-sig,committer,e-root,e-status-reply,head,maintainers,merge-base,merge-commit,name,parent-commit,r-euc,ref,web
NIP-36 — Content warnings:
content-warning
NIP-38 — Status tags:
expiration,status-type
NIP-42 — Auth tags:
challenge,relay
NIP-43 — Fast auth tags:
claim,member,protected
NIP-47 — Wallet Connect tags:
encryption,notifications
NIP-51 — List tags:
group,word
NIP-52 — Calendar tags:
end_tzid,fb,g,location,start_tzid,status
NIP-53 — Live activity tags:
a-live,a-room,current_participants,endpoint,ends,hand,image,pinned,recording,relays,room,service,starts,status-live,status-room,streaming,summary,title,total_participants
NIP-56 — Report tags:
e,p,server,x
NIP-57 — Zap tags:
amount,bolt11,description,lnurl,preimage
NIP-5A — Git file tags:
path,source
NIP-61 — Nutzap tags:
e-redeemed,mint,proof,pubkey,relay,u
NIP-65 — Relay tags:
r- Relay URL with read/write marker
NIP-68 — Picture tags:
imeta
NIP-69 — Trading tags:
amt,expires_at,f,fa,k,layer,network,pm,premium,s,y,z
NIP-71 — Video tags:
imeta
NIP-73 — External content IDs:
i,k
NIP-84 — Highlight tags:
context,comment
NIP-87 — Cashu mint tags:
modules,n,nuts
NIP-88 — Poll tags:
endsAt,option,polltype,response
NIP-89 — App handler tags:
client
NIP-90 — DVM tags:
amount,bid,i,output,param,request,status
NIP-94 — File metadata tags:
m,ox,url
NIP-98 — HTTP Auth tags:
method,payload
NIP-b7 — Blossom tags:
server
NKBIP-03 — Knowledge base tags:
accessed_on,author,chapter_title,doi,editor,llm,page_range,published_by,published_in,published_on,version
MIP-00 — Marmot tags:
client,d,encoding,i,mls_ciphersuite,mls_extensions,mls_proposals,mls_protocol_version
MIP-03 — Marmot group tags:
h
MIP-05 — Marmot notification tags:
token,token-response,v
npm install @nostrability/schemata# Latest release with all languages
curl -L https://github.com/nostrability/schemata/releases/latest/download/schemata.zip -o schemata.zip
# Specific version
curl -L https://github.com/nostrability/schemata/releases/download/v0.1.1/schemata-v0.1.1.zip -o schemata.zip// Get latest release info
const response = await fetch('https://api.github.com/repos/nostrability/schemata/releases/latest');
const release = await response.json();
console.log(release.assets[0].browser_download_url);# Clone repository
git clone https://github.com/nostrability/schemata.git
cd schemata
# Install dependencies
pnpm install
# Build schemas
pnpm buildschemata/
├── @/ # Aliases (shortcuts to schemas)
├── nips/ # Schema implementations by NIP
│ ├── nip-01/ # Core protocol
│ └── nip-*/ # Other NIPs
├── mips/ # Schema implementations by MIP (Marmot Improvement Proposals)
│ └── mip-00/ # MLS protocol schemas
├── dist/ # Built schemas (git-ignored)
│ ├── @/ # Compiled aliases
│ ├── nips/ # Compiled schemas
│ ├── mips/ # Compiled MIP schemas
│ └── bundle/ # JavaScript bundle
└── docs/ # Documentation
| Project | Language | Usage | Status |
|---|---|---|---|
| nostr-watch | TypeScript | Relay auditing pipeline (NIP-01, NIP-02, NIP-11, NIP-22, NIP-42, NIP-77) and GUI validation | Merged (0e865bf) |
| Synvya/client | TypeScript | Runtime pre-publish validation of kind-0, kind-1, and kind-30402 events | Merged (#159) |
| applesauce | TypeScript | Kind-0 and kind-1 event serialization validation in CI | Merged (#39) |
| nostria | Angular/TypeScript | Schema validation tests for 34 event kinds across 16 NIPs | Merged (#576) |
| schemata-codegen | TypeScript | Generates typed interfaces, runtime validators (TS/C/Rust), kind registries, and error messages from schemas | Active |
| sherlock | TypeScript | Schema conformance scanner -- fetches live relay events and validates against schemata with AJV | Active |
We welcome contributions! See Contributing Guide for details.
Quick tips:
- Schemas are written in YAML, compiled to JSON
- Follow existing patterns for consistency
- Include error messages and descriptions
- Test with valid/invalid examples
For maintainers: See RELEASE.md for the step-by-step release process.
- 🐛 Report Issues
- 💬 Discussions
- 📧 Contact: [iris.to/npub1zafcms4xya5ap9zr7xxr0jlrtrattwlesytn2s42030lzu0dwlzqpd26k5]