Skip to content

Add notes and links

This guide walks through creating annotations with the shipped commands.notes and commands.links facades.

const api = window.Amnesia; // or this.app.plugins.plugins['amnesia']?.api
// Create a note (requires write-annotations on a scoped handle):
const note = await api.commands.notes.create(/* note payload */);
// List and search:
const all = await api.commands.notes.getNotes();
const hits = await api.commands.notes.searchNotes('chapter 3');
const note = await api.commands.notes.getNoteForHighlight(highlightId);
if (note) {
// a note exists for this highlight
}
// Internal link between annotations/locations:
const link = await api.commands.links.createLink(/* link payload */);
// External (URL) link:
const ext = await api.commands.links.createExternalLink(/* { url, ... } */);
// Read back the in-memory link set:
const links = await api.commands.links.getLinks();
// Follow a link:
await api.commands.links.navigateLink(link);

Remember: getLinks() returns only what was created this session.

Notes and links emit shipped note-* and link-* events. Subscribe and clean up with Disposable:

const sub = api.events.on('note-created', (payload) => {
// update your UI
});
this.register(() => sub.dispose());

See Subscribe to events for the full pattern.

Writes (create / update / delete, createLink / createExternalLink / deleteLink) require write-annotations; reads require read-state. On an under-scoped connect() handle, a gated call throws PermissionError. The facade-level PermissionError is shipped and proven; the connect() capability-scoping that makes a handle under-scoped is itself experimental and untested.

Reference verified as of 2026-06-28.