apps/server/src/assets/llm/skills/backend_scripting.md
Backend scripts run in Node.js on the server. They have direct access to notes in memory and can interact with the system (files, processes).
api global)api.getNote(noteId) - get note by IDapi.searchForNotes(query, searchParams) - search notes (returns array)api.searchForNote(query) - search notes (returns first match)api.getNotesWithLabel(name, value?) - find notes by labelapi.getNoteWithLabel(name, value?) - find first note by labelapi.getBranch(branchId) - get branch by IDapi.getAttribute(attributeId) - get attribute by IDapi.createTextNote(parentNoteId, title, content) - create text noteapi.createDataNote(parentNoteId, title, content) - create JSON noteapi.createNewNote({ parentNoteId, title, content, type }) - create note with full optionsapi.ensureNoteIsPresentInParent(noteId, parentNoteId, prefix?) - create or reuse branchapi.ensureNoteIsAbsentFromParent(noteId, parentNoteId) - remove branch if existsapi.toggleNoteInParent(present, noteId, parentNoteId, prefix?) - toggle branchapi.getTodayNote() - get/create today's day noteapi.getDayNote(date) - get/create day note (YYYY-MM-DD)api.getWeekNote(date) - get/create week noteapi.getMonthNote(date) - get/create month note (YYYY-MM)api.getYearNote(year) - get/create year note (YYYY)api.log(message) - log to Trilium logs and UIapi.randomString(length) - generate random stringapi.escapeHtml(string) / api.unescapeHtml(string)api.getInstanceName() - get instance nameapi.getAppInfo() - get application infoapi.dayjs - date manipulationapi.xml2js - XML parserapi.htmlParser - HTML parser (node-html-parser), use api.htmlParser.parse(html) to parseapi.cheerio - DEPRECATED, use api.htmlParser insteadUse the native fetch() API for HTTP requests:
const response = await fetch('https://api.example.com/data');
const data = await response.json();
Note: api.axios was removed in 2026 due to a supply chain security incident. Use fetch() instead.
api.transactional(func) - wrap code in a database transactionapi.sql - direct SQL accessapi.sortNotes(parentNoteId, sortConfig) - sort child notesapi.runOnFrontend(script, params) - execute code on all connected frontendsapi.backupNow(backupName) - create a backupapi.exportSubtreeToZipFile(noteId, format, zipFilePath) - export subtree (format: "markdown" or "html")api.duplicateSubtree(origNoteId, newParentNoteId) - clone note and childrenAvailable on notes returned from API methods (api.getNote(), api.originEntity, etc.).
note.getContent() / note.setContent(content)note.getJsonContent() / note.setJsonContent(obj)note.getJsonContentSafely() - returns null on parse errornote.noteId, note.title, note.type, note.mimenote.dateCreated, note.dateModifiednote.isProtected, note.isArchivednote.getParentNotes() / note.getChildNotes()note.getParentBranches() / note.getChildBranches()note.hasChildren(), note.getAncestors()note.getSubtreeNoteIds() - all descendant IDsnote.hasAncestor(ancestorNoteId)note.getLabels(name?) / note.getLabelValue(name)note.getRelations(name?) / note.getRelation(name)note.hasLabel(name, value?) / note.hasRelation(name, value?)note.setLabel(name, value?) / note.removeLabel(name, value?)note.setRelation(name, targetNoteId) / note.removeRelation(name, value?)note.addLabel(name, value?, isInheritable?) / note.addRelation(name, targetNoteId, isInheritable?)note.toggleLabel(enabled, name, value?)note.save() - persist changesnote.deleteNote() - soft deletenote.cloneTo(parentNoteId) - clone to another parentnote.isJson(), note.isJavaScript(), note.isHtml(), note.isImage()note.hasStringContent() - true if not binary#run label on the script note)#run=backendStartup - run when server starts#run=hourly - run once per hour (use #runAtHour=N to specify which hours)#run=daily - run once per dayThese are defined as relations. api.originEntity contains the entity that triggered the event.
| Relation | Trigger | originEntity |
|---|---|---|
~runOnNoteCreation | note created | BNote |
~runOnChildNoteCreation | child note created under this note | BNote (child) |
~runOnNoteTitleChange | note title changed | BNote |
~runOnNoteContentChange | note content changed | BNote |
~runOnNoteChange | note metadata changed (not content) | BNote |
~runOnNoteDeletion | note deleted | BNote |
~runOnBranchCreation | branch created (clone/move) | BBranch |
~runOnBranchChange | branch updated | BBranch |
~runOnBranchDeletion | branch deleted | BBranch |
~runOnAttributeCreation | attribute created on this note | BAttribute |
~runOnAttributeChange | attribute changed/deleted on this note | BAttribute |
Relations can be inheritable — when set, they apply to all descendant notes.
// Attach via ~runOnAttributeChange relation
const attr = api.originEntity;
if (attr.name !== "mycategory") return;
const note = api.getNote(attr.noteId);
if (attr.value === "Health") {
note.setLabel("color", "green");
} else {
note.removeLabel("color");
}
// Attach #run=daily label
const today = api.getTodayNote();
const tasks = api.searchForNotes('#task #!completed');
let summary = "## Open Tasks\n";
for (const task of tasks) {
summary += `- ${task.title}\n`;
}
api.createTextNote(today.noteId, "Daily Summary", summary);
Child notes of a script act as modules. Export with module.exports = ... and import via function parameters matching the child note title, or use require('noteName').