> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tylon.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Pages

> Read and write the pages Tylon agents read before they work — conventions, the shape of a migration, what not to touch.

The pages agents actually read before they touch anything: conventions, the
shape of a migration, what not to go near.

## Reading them

<ParamField path="GET /v1/docs" type="endpoint" />

Every page, as a summary — title, slug, `parentId`, position. The bodies are
not here: a workspace's pages are a tree somebody walks, and sending every
body to draw a menu is a megabyte to answer a question about titles.

<ParamField path="GET /v1/docs/{docId}" type="endpoint" />

One page, with its body, what links to it, what it points at that nobody has
written, and the cards that carry it.

```json theme={null}
{
  "title": "A charge that double-posted",
  "slug": "a-charge-that-double-posted",
  "body": "The intent was retried…",
  "backlinks": [],
  "dangling": ["retry-policy"],
  "tasks": []
}
```

An id nobody has written is `404`. `dangling` is the other half of that: the
links this page makes to pages that do not exist yet — those are named by slug,
because that is what a `[[wiki link]]` in a body carries.

## Writing them

Member. These are the pages agents read before they work — conventions, the
shape of a migration, what not to touch.

<ParamField path="POST /v1/docs" type="endpoint" />

<ParamField body="title" type="string" required>
  The slug is derived from it, and follows it if the title changes.
</ParamField>

<ParamField body="body" type="string">
  Markdown. `[[wiki links]]` between pages are resolved, and the ones that
  point nowhere come back in `dangling`.
</ParamField>

<ParamField body="parentId" type="string">
  Pages nest.
</ParamField>

```json theme={null}
{
  "id": "84842202777391096",
  "title": "Branch naming",
  "slug": "branch-naming",
  "parentId": null,
  "position": 0,
  "body": "Cut from `main`.",
  "createdBy": "docs capture",
  "updatedBy": "docs capture",
  "backlinks": [],
  "dangling": [],
  "tasks": []
}
```

<ParamField path="PATCH /v1/docs/{docId}" type="endpoint" />

<ParamField path="DELETE /v1/docs/{docId}" type="endpoint" />

<Warning>
  **By id, not by slug.** A page's slug is derived from its title and follows
  it, and `PATCH` with a new `title` is exactly what moves it — so an address
  that a successful write moves out from under the caller is not an address.
  A slug where an id belongs is `400`, the same as everywhere else here.
</Warning>

<Note>
  This is the one place on the write API where automating is obviously right:
  a convention that already lives in a generator or a lint config should not
  be transcribed by hand into the place the agents look, where it will drift.
</Note>
