# PostMD — Service overview

**Covers** — what a document, a group, a note, a document graph, edit mode, an API key and a
scope are; who may change or delete a document; how long documents are kept; how images and
links behave.

**Not here** — endpoints, request and response shapes and error codes are in
[/docs/api](/docs/api). Graph data is in [/docs/graph](/docs/graph). The map of the whole
service is [/llms.txt](/llms.txt).

PostMD stores markdown documents and serves them as web pages.

You upload a `.md` file. PostMD saves it and returns a short **document code**.
That code forms the document's viewer URL, and anyone who opens the URL sees the
rendered document. A document can also carry a graph that an agent put together from reading it
— its reading order, the bodies and rules it names, a procedure spread over several chapters —
and the viewer draws it. See "Graph" under Core concepts.

The web app and the HTTP API do the same things. An agent holding an API key can
upload, read, update and delete documents on a member's behalf, exactly as a
person would in the browser. Two MCP servers cover the same ground for assistants that speak MCP:
one hosted at `https://postmd.turink.com/mcp`, and `npx -y postmd-mcp-server`, which runs locally
and adds the tools that need an API key.

## Three ways in

There are three depths of use, each with a different prerequisite. Which one fits depends on
what the person actually needs.

| Need | Prerequisite | What it gives |
|---|---|---|
| Hand one document to someone | none | a link, from one request |
| Keep and organise documents of your own | an API key, issued in the web app | grouped documents, notes, owner access |
| Do this repeatedly | the MCP server, registered once | these endpoints as tools |

Some environments cannot issue arbitrary POST requests. Two things still work there. The MCP
server (`npx -y postmd-mcp-server`) turns these endpoints into registered tools, which a person
sets up once. And the upload command in [/llms.txt](/llms.txt) is complete as written, so a
person can run it with their own filename substituted and have a link without signing up.

## Core concepts

Read this section before using the API. Most integration mistakes come from
misreading one of these terms.

### Document

A single markdown file plus its settings (title, password, viewer theme).

Every document gets a **document code** such as `P-889-419-571`. The code is
assigned once at upload and never changes, so you can store it and use it later
to fetch, update or delete that document.

PostMD does not convert other formats. Only `.md` files are accepted.

### Group

A personal collection of documents for classification.

Every member account has one **default group**, created automatically at signup.
It cannot be deleted. Members can create additional groups for their own organization.

**A document belongs to at most one group.** It goes into the group you name at
upload. If you do not name one, it goes into your default group. Moving it to another
group replaces the group it was in; the document itself, including its address, does not change.

### Note

Text a member attaches to a document while reading it, optionally anchored to a
quoted passage. A highlight is the same object carrying a colour and no text.

Notes exist only on documents a person owns. Anonymous uploads and
service-owned pages take none, because nobody there could act on what is left.

Visibility comes from ownership. On your own document a note is either private
to you or shared with everyone who can read the document. On someone else's
document a note is always shared, and that document's owner can resolve or
delete it. A highlight follows the same rule, so a private highlight is yours
alone.

Anchors are matched by the quoted text, not by position, so notes survive edits
elsewhere in the document. If the quoted passage itself disappears, the note
keeps its text and loses only its place in the body. If the same passage now
appears somewhere else, the note points there instead.

That is why replacing a document's content asks what to do about the notes.
Both the screen and the API require the caller to see it first: the screen says
how many notes are attached to sentences before the replace runs, and the API
takes `notesOnReplace` on every call that sends a new file. Notes are never
deleted by a replace.

Highlight colours are four fixed codes. Each member may name them for
themselves (for example "needs review"); the colour travels with a shared note,
the name never leaves the member who set it.

### Graph

A document can carry graph data that the viewer draws. It shows how
the parts of one document relate, so a reader can take in the structure before reading the whole
of it. Thirteen types are available — prerequisite order, timelines, knowledge graphs, taxonomies,
concept maps, procedures, concepts by chapter, cause and effect, comparisons, quadrants, argument
maps, discourse structure and requirements traces — and an agent can define a type of its own.

PostMD draws the graph and stores it as part of the document. It does not analyse anything:
deciding what the nodes are and how they connect means reading the document, which is the agent's
part. The data goes into the markdown file as an HTML comment, so it needs no separate endpoint
and no store of its own, and every document operation carries it unchanged.

The graph control appears in the viewer only for documents that contain graph data. The format is
in [Graph data](/docs/graph).

### Edit mode

A state a published document enters while it is being revised. The server holds a **working
copy**; the published document keeps serving its previous content until the working copy is
published.

One caller holds a document at a time, for an hour, extended by each save. Looking at the
document does not extend it. When the hour runs out the exclusive hold is released and the
working copy stays, so stepping away loses nothing; the next caller is offered the choice of
continuing that work or discarding it. Someone waiting can ask for the document, which cuts the
holder's remaining time to ten minutes, and the document's owner takes it back immediately.

An agent writes the working copy and the person looks at it in the viewer, which redraws within
about five seconds of each save. The working copy reaches readers only when it is applied: by that
person, with the viewer's **Apply to document** button, or by the agent when that is what it was
asked to do. Applying takes the same permission as any other change to the document.

A working copy untouched for seven days is deleted. A document has one working copy and no
version history.

Entering edit mode needs the same permission as changing the document. While a document is held,
anyone else trying to update it is refused. Deleting it is not blocked, and the working copy goes
with the document.

### API key

The credential an agent uses to call the API. It always starts with `pmk_`.

A member issues API keys from the web app. At issue time they choose:

- **Scopes** — which operations the key may perform.
- **An expiry date** — required, and at most one year away.

The key itself is shown **once**, in the response to the issue request. PostMD
stores only a hash of it and cannot show it again. If it is lost, revoke the key
and issue a new one.

### Scope

A permission attached to an API key.

| Scope | Allows |
|---|---|
| `documents:read` | Reading documents |
| `documents:write` | Uploading, updating and deleting documents |
| `groups:read` | Reading groups |
| `groups:write` | Creating, updating and deleting groups |

**Read and write are separate permissions.** Holding `documents:write` does not
allow reading documents. If your integration both uploads and reads back, grant
both scopes.

## Permissions and retention

A document's viewer URL works for anyone who has it.

### Modification and deletion permissions

- **Official documents** (`docs@turink.com`) cannot be modified or deleted by anyone.
- **Documents without a password** can be modified or deleted by anyone (including anonymous callers).
- **Documents with a password** can be modified or deleted by their authenticated owner without a password, or by any caller supplying the correct password via the `X-Document-Password` header.

### 30-day retention
 
All documents (except official documents) are kept until 30 days after they were last published, changed or read. This applies to members' documents as well as anonymous ones.
- When a document is published, its retention is set to 30 days from publication.
- Whenever its content or settings are changed, including applying a working copy from edit mode, the deadline is reset to 30 days from that moment.
- Whenever someone reads the document content (`GET /documents/{docCode}` or `/raw`), if less than 29 days remain until its retention deadline, the deadline is extended to 30 days from that moment (at most once per day).
- When the retention deadline passes without any reads, the document is cleaned up by background batch processing.

## Behaviour worth knowing

### Images and links

PostMD renders markdown content directly. A reference to a file on your own computer works only
for you and breaks at the published address, so such references are replaced with a short notice
instead of being rendered — except images a member uploads together with the document.

- **Images** accept web URLs (`https://...`, `http://...`) and inline `data:` URIs. A member can
  also upload the pictures the file references by local paths along with the file: PostMD stores
  them and replaces those paths in the stored text with their addresses. Up to 30 images and 10 MB
  per document; anonymous documents do not take images. See "Images from your computer" in
  [/docs/api](/docs/api).
- **Links** accept those plus `#anchor` links into the same document, so a hand-written table
  of contents keeps working.
- Other relative paths (`./other.md`, `../image.png`), absolute paths and `file:` references are
  replaced with a notice.

### Deletion

Deleting a document takes effect immediately: it disappears from listings and its URL stops
working. Deleting a group removes the group only; the documents in it move to the member's
default group.

There is **no endpoint to undo this**, so treat deletion as permanent.

### Anonymous upload

A request with no credential can still upload a document. Ownership is assigned
to an internal anonymous account.

Like all documents, it is kept until 30 days after it was last changed or read. If no password
is set, anyone can update or delete it; if a password is set, the `X-Document-Password` header
is required.

An anonymous document's text may be up to 1 MB. A member's may be up to 20 MB, and a member's
documents together may use up to 50 MB of storage.

### Encryption at rest

Document content is encrypted before it is written to disk, and decrypted when served.
This changes nothing for API clients — you send and receive plain markdown.

### Account withdrawal

Withdrawal starts a one-month grace period. Nothing happens to the documents until it
ends; the account can only sign in during that time. When the period ends:

- **Documents without a password** move to the internal anonymous account, so their links
  keep working. Notes on them are removed.
- **Documents with a password** are deleted and their stored files are erased.
- The member's groups are removed, and every document leaves its group.
- Account details are masked, and all sessions and API keys are revoked.

## Documents

- [API reference](/docs/api) — endpoints, authentication, error codes.
- [Document graphs](/docs/graph) — graph data carried inside a document, and the graph types.
- [Changelog](/docs/changelog) — what changed and when.
- [OpenAPI spec](/api-docs) — machine-readable API description.

## Service

<https://postmd.turink.com>
