Educational Data Pool — integration guide

How to write, query, update, and convert AMB resources — Nostr events of kind 30142, specified by NIP-AMB — in the Edufeed Educational Data Pool. The read side of the same data — fetching and rendering — is shown in the Educational Data Pool live demo.

1. What is stored kind 30142

Each educational resource is stored as a Nostr addressable event of kind 30142, implementing the Allgemeines Metadatenprofil für Bildungsressourcen (AMB). An event is uniquely identified by its three-part coordinate kind:pubkey:d-tag — the d tag typically holds the canonical resource URL. Metadata is stored as flat Nostr tags using : as a nesting delimiter. The exact on-the-wire mapping — which AMB property becomes which Nostr tag — is defined in NIP-AMB, the specification that defines kind 30142. "Kind 30142" and "NIP-AMB" always refer to the same event format — the number is what goes over the wire, NIP-AMB is the document that specifies it.

What "addressable" means. Nostr defines four event-storage behaviours by kind range (NIP-01): regular events are kept indefinitely, replaceable events (kind 1000019999) keep only the latest per (kind, pubkey), and addressable events (kind 3000039999, sometimes called parameterized replaceable) keep only the latest per (kind, pubkey, d-tag). Because the resource carries its own d identifier, one author can hold arbitrarily many distinct kind 30142 resources, each independently replaceable in place — publishing the same coordinate again overwrites the prior version rather than appending a duplicate. That stable coordinate is what makes a resource referenceable: other events point at it with an a tag ("a", "30142:<pubkey>:<d-tag>") and it can be encoded as an NIP-19 naddr for sharing. See the NIP-01 "Kinds" section for the authoritative range definitions.

AMB property Nostr tag(s) Notes
id ["d", <uri>] Stable identifier, usually the content URL
name ["name", <title>] Human-readable title
description ["description", <text>] + content field Stored in both places; clients prefer content field
keywords ["t", <keyword>] (repeated) Nostr-native keyword tag
about (concept) ["about:id", <uri>]
["about:prefLabel:<lang>", <label>]
["about:type", "Concept"]
Repeated for each subject; multiple about-groups are co-indexed by tag order
learningResourceType (concept) ["learningResourceType:id", <uri>]
["learningResourceType:prefLabel:<lang>", <label>]
["learningResourceType:type", "Concept"]
Repeated for each type
creator — with Nostr identity ["p", <pubkey-hex>, <relay-hint>, "creator"] Only p tag is emitted; name resolved from kind:0 profile
creator — external (no Nostr pubkey) ["creator:name", <name>]
["creator:id", <uri>] (optional, e.g. ORCID)
["creator:type", "Person"|"Organization"]
Same structure for contributor, publisher
isBasedOn / isPartOf / hasPart Nostr resource: ["a", "30142:<pubkey>:<d>", <relay>, <role>]
External URI: ["isBasedOn:id", <uri>] etc.
Role is the property name, e.g. "isBasedOn"
External references ("see also") ["r", <url>] (repeated) DOI, ISBN, OERSI source URL — Nostr-native NIP-24; no AMB equivalent on reverse conversion

Extension namespaces — properties outside the AMB-core spec use an ext prefix so they coexist without collision:

2. How data enters the pool

Kind 30142 events are produced by any Nostr client that can sign on behalf of the author — whether it holds the private key directly or delegates to a remote signer (NIP-46). Signing is independent of where the event is published:

After signing, the event is published to the Edufeed AMB relay (wss://amb-relay.edufeed.org) using standard Nostr EVENT messages. Anyone who can sign as the author can later publish replacements or deletions for the same coordinate.

For a quick end-to-end check from the command line, nak (the Nostr army knife) builds, signs, and publishes a valid kind 30142 event in one call:

# Build, sign, and publish a kind 30142 event to the AMB relay
nak event -k 30142 \
  -d "https://example.org/my-resource" \
  -t "name=My Open Educational Resource" \
  -t "about:id=http://w3id.org/kim/schulfaecher/s1055" \
  -t "about:prefLabel:de=Religion" \
  -t "learningResourceType:id=https://w3id.org/kim/hcrt/drill_and_practice" \
  -t "learningResourceType:prefLabel:de=Übung" \
  -t "t=Beispiel" \
  -c "A short description of the resource." \
  --sec nsec1... \
  wss://amb-relay.edufeed.org

3. Does storage location matter?

No — the canonical address of a resource is its coordinate 30142:<pubkey>:<d-tag>, which is location-independent. The same signed event can be stored on any number of relays simultaneously. The Edufeed AMB relay (wss://amb-relay.edufeed.org) is the primary index, but clients are free to mirror or query elsewhere.

Query using standard NIP-01 filters:

// All AMB events (up to relay limit)
{"kinds": [30142]}

// Specific resource by coordinate
{"kinds": [30142], "authors": ["<pubkey-hex>"], "#d": ["<d-tag-value>"]}

// Filter by Nostr-native keyword tag
{"kinds": [30142], "#t": ["Gerechtigkeit"]}

// Filter by subject URI (AMB tag filter)
{"kinds": [30142], "#about:id": ["http://w3id.org/kim/schulfaecher/s1055"]}

// Filter by resource type URI
{"kinds": [30142], "#learningResourceType:id": ["https://w3id.org/kim/hcrt/drill_and_practice"]}

Tag filters only work for keys the relay indexes: all single-letter Nostr tags (d, t, p, a, …) plus the AMB-core keys such as about:id and learningResourceType:id. Values must match byte-for-byte (note the http:// scheme above — it is whatever the producer stored, not necessarily https://). Extension namespaces (ext:ekw:* and per-form ext:<slug>:*) are not indexed for filtering; fetch a coarser set and refine client-side, or use the converter to read them out of the ext object.

Query using NIP-50 full-text search (supported by amb-relay.edufeed.org):

// Free-text search across name, description, keywords
{"kinds": [30142], "search": "evangelisch"}

// Field-specific filter via dot-notation
{"kinds": [30142], "search": "publisher.name:e-teaching.org"}

// Combined: free text + field filter
{"kinds": [30142], "search": "Frieden about.prefLabel.de:evangelisch"}

NIP-50 dot-notation covers AMB-core fields (name, description, publisher.name, about.prefLabel.<lang>, …). Like the tag index, it does not currently reach ext.* facets.

Query from the command line with nak:

# All AMB events, newest first (limit 20)
nak req -k 30142 -l 20 wss://amb-relay.edufeed.org

# Filter by subject tag
nak req -k 30142 -t about:id=http://w3id.org/kim/schulfaecher/s1055 wss://amb-relay.edufeed.org

# NIP-50 full-text search
nak req -k 30142 --search "evangelisch" wss://amb-relay.edufeed.org

4. How events are updated or deleted

Kind 30142 is an addressable (parameterized replaceable) event. When a client publishes a new event with the same (kind, pubkey, d-tag) triple, relays keep only the newest created_at; older versions are superseded automatically. There is no explicit "patch" step — the author simply re-publishes the full updated event.

Deletion uses NIP-09 (kind 5): the author publishes a deletion event referencing the addressable coordinate as an a tag:

// NIP-09 deletion event
{
  "kind": 5,
  "tags": [
    ["a", "30142:<pubkey>:<d-tag-value>", "<relay-hint>"]
  ],
  "content": "Resource removed"
}

Relays that honour NIP-09 will stop serving the referenced event. Clients that implement deletion-aware models will filter it from results automatically.

5. Categorisation and controlled vocabularies

Classification uses SKOS-aligned controlled vocabularies. Every concept carries its vocabulary URI (:id), a human-readable label (:prefLabel:<lang>), and the type marker (:type = "Concept"). Multiple concepts in the same field are stored as repeated tag groups (boundary on repeated :id).

AMB field Tag prefix Example vocabulary
about — subject about:id / about:prefLabel:de Schulfächer (Kim)
learningResourceType learningResourceType:id / :prefLabel:de hcrt / new_lrt
audience audience:id / :prefLabel:de LRMI audience vocab
educationalLevel educationalLevel:id / :prefLabel:de Kim educationalLevel

EKW extension vocabularies

The EKW profile — named for the Evangelische Kirche von Kurhessen-Waldeck (EKKW) — adds domain-specific facets under the ext:ekw:* namespace, plus three EKW-specific replacements for AMB-core vocabularies. All of these vocabularies are published as Nostr concept schemes (kind 39737, individual concepts kind 39738) by VocabulOER (npub16f5fut6…) and are browsable on Edufeed's vocabulary tool, nocabs.edufeed.org. Concept :id values on EKW events are therefore Nostr-native coordinates (nostr:39738:<vocab-pubkey>:<concept-d>), not HTTP URIs.

EKW field Tag key(s) Vocabulary
gradeLevel ext:ekw:gradeLevel:id / :prefLabel:de / :type Klassenstufen
schoolType ext:ekw:schoolType:id / :prefLabel:de / :type Schulart
didacticConcept ext:ekw:didacticConcept:id / :prefLabel:de / :type Didaktisches Konzept
method ext:ekw:method:id / :prefLabel:de / :type Methode
methodOther ext:ekw:methodOther (bare value, repeated) Free text — author-supplied method not in the vocabulary
bibleReference ext:ekw:bibleReference (bare value, repeated) Free text — e.g. Gen 1, Ps 104
about — subject (EKW-core) about:id / about:prefLabel:de EKW Fach
learningResourceType (EKW-core) learningResourceType:id / :prefLabel:de EKW LRT
keywords (EKW-core) t (Nostr-native, repeated) EKW Keywords

Per-community metadata forms add further namespaces under ext:<form-d-slug>:* (kind 30168 forms), referenced from the resource via ["a", "30168:<pub>:<d>", <relay>, "form"].

6. Convert events back to plain JSON (AMB)

The amb-nostr-converter library (the same tool powering the widget below) can reconstruct an AMB JSON document from any kind 30142 event. It reverses the tag-flattening, re-groups concept arrays, maps p tags to creator/contributor, maps a tags to relation objects, and surfaces ext:* tags under a sibling ext object in the output.

Install it from the Edufeed npm registry and use the CLI (requires Node.js):

npm install amb-nostr-converter --registry=https://git.edufeed.org/api/packages/edufeed/npm/
amb-convert nostr:amb event.json

Or use the live widget below: pick a sample event — or one of the live EKW resources fetched in Section 7 — from the dropdown, and it loads into the left pane and converts automatically. Edit the JSON and click Nostr → AMB to re-run, or AMB → Nostr to go the other way.

Nostr event JSON (kind 30142)
Reconstructed AMB JSON

Fetch a specific event from wss://amb-relay.edufeed.org and load it into the converter above. Accepts a 64-character hex event id, an addressable coordinate kind:pubkey:d-tag, or a NIP-19 naddr, nevent, or note identifier (with or without a nostr: prefix).

idle

7. Live: EKW resources from the relay kind 30142

The cards below are fetched live from wss://amb-relay.edufeed.org at page load — a direct Nostr REQ for kind 30142 events authored by the EKW publisher (npub1wak8hljj…), the same query any client would use. Each card shows the resource title, description, and the ext:ekw:* facets it carries.

idle

8. Client libraries by language

Everything in this guide is plain Nostr, so any Nostr library can read, write, and query kind 30142 events — no Edufeed-specific SDK is required. A few well-maintained options per language:

LanguageLibraryNotes
JavaScript / TypeScript Applesauce · nostr-tools Applesauce is the high-level toolkit Edufeed itself uses (EventStore, models, EventFactory); nostr-tools covers low-level primitives (keys, NIP-19, relays).
AMB ↔ Nostr (JS/TS) amb-nostr-converter Edufeed's own converter between AMB JSON and kind 30142 — powers the widget in Section 6.
Go go-nostr · khatru go-nostr for clients; khatru for building relays.
Rust rust-nostr (nostr-sdk) High-level SDK; also the source of bindings for several other languages.
Python nostr-sdk Python bindings of rust-nostr.
PHP nostr-php Helper library — docs at nostr-php.dev.
CLI / shell nak The "Nostr army knife" used in the examples above — query, build, sign, and publish from the terminal.

A broader, continuously updated catalogue of libraries and tools lives in awesome-nostr.


The converter widget (Section 6) runs entirely offline. The live feed (Section 7) opens one WebSocket to wss://amb-relay.edufeed.org. Requires a browser that supports ES modules.