Concepts
The note primitive
Notr knows what a note is and nothing more. Understanding that one primitive — and what it deliberately leaves out — is most of what there is to learn.
Anatomy of a note
type Note = {
id: string // stable, never changes
ydoc: Uint8Array // canonical Yjs document (source of truth)
markdown: string // derived projection, read-only
metadata?: Record<string, unknown> // yours — Notr never interprets it
createdAt: Date
updatedAt: Date
} - The Yjs document is the source of truth. It's a CRDT — concurrent edits from any number of collaborators merge deterministically. You never read or write it directly; the editor and the collaboration server do.
- Markdown is a projection. Notr re-derives it from the Yjs document every time the note is stored. It's what you read over the REST API. Writing to it is not supported — it would immediately be overwritten by the next sync.
- Metadata is an uninterpreted bag. Tag notes with anything your integration needs (an external ID, a source label). Notr stores and returns it, nothing else.
The consumer ownership model
Your application keeps its own entities and its own database. A Notr note never knows what it's for — the association lives on your side:
// 1. create the note in Notr
const res = await fetch('https://notr.example/api/notes', {
method: 'POST',
headers: { 'x-api-key': process.env.NOTR_KEY }
})
const note = await res.json()
// 2. attach it to YOUR entity, in YOUR database
await db.meetings.create({
title: 'Weekly Sync',
noteId: note.id
}) The same pattern covers wiki pages, documentation, CRM records, support tickets, and AI agent memory. One primitive, any domain.
What Notr will never model
Hierarchies, folders, projects, meetings, tasks, calendars, permissions between your end-users — these are application concepts, and different applications model them differently. Notr's rule of thumb: if two consumers would reasonably implement something in two different ways, it doesn't belong in the infrastructure.
The same line holds for files and images. A note can contain media, but Notr
stores only a reference — a URL plus a little metadata — never the bytes. Your
application owns storage, just as it owns the database. The editor's onUpload hook is the seam: you take the file, put
it wherever you keep blobs, and hand back a URL. Notr stays a note engine, not a file manager.
Lifecycle
- Create —
POST /api/notesfrom your backend. The note starts empty. - Edit — collaborators connect through the editor; changes sync live and are persisted automatically (debounced, at most a few seconds behind).
- Read —
GET /api/notes/:idreturns the markdown projection and metadata whenever you need the content outside the editor. - Delete —
DELETE /api/notes/:idremoves the note permanently. YournoteIdreference stops resolving; clean it up on your side.
Next: Identity & keys — who owns notes and how requests authenticate.
