Skip to main content
A backlink is a clickable reference to another Knowledge Base document, embedded directly in content. In a markdown body it renders as an inline chip in the middle of a sentence. In a report or slide deck it is any element you mark as clickable — a card, a table row, a name. A backlink points at a document by ID, never by URL. Moxn resolves navigation from that ID, which is why the link keeps working when the target is renamed or moved. Backlinks also write through to Moxn’s reference graph. After the commit that carries the link, it appears in the source document’s outgoing references and in the target document’s incoming backlinks — no separate bookkeeping call.
  • The ID an agent already has is the link. find and search hand back document IDs; embedding one in the prose is the whole authoring step. There is no URL to construct and no path to keep in sync.
  • Reading a document reveals its neighbors. A read with references or backlinks turns any document into a starting point for traversal, so an agent can follow the graph instead of re-searching the workspace.
  • The graph cannot drift from the prose. Rows are derived from committed content, so a link that no longer appears in the text no longer appears in the graph.
An inline link and a sidecar reference (add_reference) are the same concept at different grains. They both produce rows in the same reference graph and both show up in the same panels — they differ in whether the link lives in the content. Reach for an inline link when the link belongs in a sentence — that is the default. Reach for a sidecar when you want to relate two documents without touching the body, which is also the only option for file-kind documents (a PDF or an image has no prose to embed a tag in).

The Syntax

Markdown bodies

The optional section attribute pins the link to one section of the target. The display text between the tags is ordinary content that you choose — it is stored, searchable, and yours to edit.

Report and slide HTML

Any element can carry data-moxn-doc (plus optional data-moxn-section). No href is needed and no client JS — Moxn paints the click affordance and opens the target in a new tab. Put the attribute on the element a reader should click rather than wrapping it in extra markup.

Where the IDs Come From

find and search are where link targets come from. This is the pipeline: discover the document, take its ID, embed the ID. find returns { id, path, name, description, defaultBranch } per document and { id, documentId, name, position } per section. search matches on content and returns items that each carry a documentId (section matches also carry a sectionId).
To pin a section, you need that section’s ID. Two sources: find({type: "section", ...}), or a read with forEdit: true, which keeps the {#id} anchor suffix on each H2 line of the returned markdown.
find is anchor-based — names and paths always reflect the document’s default branch. That is fine for grabbing an ID (the ID is branch-independent), but use read with branchName when you need branch-correct metadata.

Worked Example: A Team Directory Report

A report where every person’s card links to that person’s document — the motivating case for data-moxn-doc.
1

Find the documents you want to link

Each result carries the id you need:
2

Put the ID on the element you want clickable

Write it with the documents toolaction: "create" or action: "update" with kind: "report" and the html field. Every write auto-commits.
3

Verify the links landed

You should see one row per card, each with derived: true. Reading Jane Doe’s document with backlinks: true now shows the report’s path among her incoming links.
The markdown equivalent is the same three moves — find the ID, embed the tag, commit:
Write it with the edit tool like any other content. There is no separate “create link” call. A read carries the graph in its front-matter when you ask for it:
  • references: trueoutgoing: the documents and sections this one links to.
  • backlinks: trueincoming: the documents that link to this one, as a deduped list of source paths.
From the CLI, the same two flags:
Backlinks are current-state only. They reflect who links here right now, and they are omitted entirely on historical (commitId) reads. Outgoing references do work point-in-time — a historical read returns the references as of that commit.
The <moxn:ref> tags themselves also come back verbatim in the markdown body of a read, so an agent editing prose sees the links it is editing around. documents with action: "list_references" is the only source of a referenceId:
direction is outgoing (the default), incoming, or both. Each row carries: From the CLI:
remove_reference refuses derived rows. A row the content asserts — an inline <moxn:ref> tag or a data-moxn-doc attribute — is owned by that content, so removing the row by ID is rejected with INVALID_OPERATION; the next commit would just recreate it. Unlink it by deleting the tag or attribute from the content. The row goes with it on the next commit.remove_reference works normally on sidecar rows (derived: false).
These five rules cover almost every question people have about link behavior.
The link survives renames; your display text does not follow them. doc names the document anchor, so renaming or moving the target leaves the link working. The display text is content you wrote, and deliberately stays as written — hovering the chip in the editor reveals the target’s current name when it has since changed. Rows appear only after commit. Until the commit that carries the tag lands, the link is in no panel, no list_references listing, and no read. An uncommitted link is not yet part of the graph. A dead section pin degrades; only a deleted document breaks. If a section pin names a section that no longer exists, the link still opens the target document — the fragment is simply ignored. Only a deleted target document is genuinely broken: the chip renders in an amber degraded state and stops being clickable, and the listing shows a null path for that end. Grain is not provenance. A link in a document’s preamble derives a document-grain row; a section can equally own a hand-authored section-grain sidecar. So “can I remove this row?” is answered by derived, never by grain. Links are branch-scoped, because content is. A link is asserted by content, and content belongs to a branch. A link committed on a feature branch is visible on that branch, and reaches the default branch when the branch merges — the same lifecycle as the words around it. See Branching & Merging.

In the Web Editor

Two ways to insert a link while writing:
  • Type @ — a picker opens, searching documents by name and path. Choose one and Moxn inserts the chip with the document’s name as the display text, which you can then edit like any other text.
  • Paste a document URL — pasting a …/knowledge-base/<uuid> link converts it into a chip. If the ID names nothing you can read, the paste stays an ordinary link rather than guessing.
A backlink chip opens its target in a new tab, leaving your place in the document you were reading.
A link to a document you don’t have permission to read renders as plain text — no chip, no title, no navigation. Access is checked when the link is resolved, so a document you cannot see never leaks its name through someone else’s prose.
  • documentslist_references, add_reference, remove_reference
  • find — discover documents and sections, and their IDs
  • search — full-text search returning document IDs
  • readreferences, backlinks, and forEdit section anchors
  • Documents & Sections — the structure links point into