# Documents and Markdown

> How pages, bodies, properties, links and the trash work, and how to edit a body safely while people are typing in it.

Everything in a workspace is a document: notes, pages, database rows. Documents form a tree.

## The document

| Field                    | What it holds                                                                    |
| ------------------------ | -------------------------------------------------------------------------------- |
| `id`                     | A ULID. You may choose it when you create the document, or let Lydie make one.   |
| `parentId`               | The parent document, or `null` at the top level.                                 |
| `title`                  | 1 to 255 characters.                                                             |
| `properties`             | Typed frontmatter: strings, numbers, booleans, `null` or lists of strings.       |
| `sortKey`                | Its place among its siblings. Use `afterId` or `beforeId` instead of setting it. |
| `createdBy`, `updatedBy` | Who made the change: a user id, or `agent:<app>:<id>:<user id>` for an agent.    |
| `deletedAt`              | Set while the document is in the trash.                                          |

The body is not part of the document. [Get a document](https://developers.lydie.co/api/documents/get-a-document.md) returns both,
and `includeBody=false` leaves the body out.

A new top-level page goes to your private section unless you pass `teamspaceId`. Subpages always
live in their parent's space.

## Bodies are Markdown

A body is Lydie Markdown: CommonMark with GitHub's tables, task lists, strikethrough, autolinks and
footnotes, plus Obsidian's syntax.

| Syntax                                   | Meaning                             |
| ---------------------------------------- | ----------------------------------- |
| `[[Note]]`, `[[Note\|alias]]`            | A link to another document by title |
| `[[Note#Heading]]`, `[[Note#^block-id]]` | A link to a heading or a block      |
| `![[image.png]]`, `![[Note]]`            | An embedded file or document        |
| `text ^block-id`                         | A block id that links can point at  |
| `> [!note] Title`                        | A callout                           |
| `==text==`, `%%comment%%`, `#tag`, `$x$` | Highlight, comment, tag, math       |

Frontmatter is not part of the body. Read and write it as `properties`.

## Edit a body

[Update a document body](https://developers.lydie.co/api/documents/update-a-document-body.md) takes one of two inputs:

- `markdown` replaces the whole body.
- `edits` is a list of exact replacements, `{ "oldStr": "…", "newStr": "…" }`, matched against the
  Markdown you read. Set `replaceAll: true` to change every match.

Prefer `edits`. They touch only what you change, so they do not undo what someone typed after you
read the page. An edit that does not match exactly once is skipped and listed in `warnings` with
the code `no_match` or `ambiguous_match`. The rest still apply.

Each read returns a `version`. Send it back as `expectedVersion` and the write fails with
`409 conflict` if the body changed since you read it. Read again and retry.

Writes merge into the live document. Someone with the page open sees your change appear.

## Properties

[Set document properties](https://developers.lydie.co/api/documents/set-document-properties.md) merges `set` into the existing
properties and removes the keys in `unset`:

```json
{ "set": { "status": "done", "tags": ["docs"] }, "unset": ["due"] }
```

## Links

Lydie indexes every link in every body. Use these to follow them:

- [List backlinks](https://developers.lydie.co/api/documents/list-backlinks.md): documents that link here.
- [List outgoing links](https://developers.lydie.co/api/documents/list-outgoing-links.md): links in this document and where they
  resolve.
- [List unresolved links](https://developers.lydie.co/api/documents/list-unresolved-links.md): links to pages that do not exist
  yet.
- [List unlinked mentions](https://developers.lydie.co/api/documents/list-unlinked-mentions.md): documents that mention this
  title without linking it.

## Search

[Search documents](https://developers.lydie.co/api/documents/search-documents.md) searches titles and bodies. Every word must
match, as a prefix. Snippets wrap matches in `<mark></mark>`.

## Delete, restore, purge

Deleting moves a document and its subpages to the [trash](https://developers.lydie.co/api/trash.md), and restoring brings them
back. Purging deletes a trashed document for good, along with its body. Links to it become
unresolved. Purging cannot be undone.
