$cat openapi.json

> Public API.

An HTTP API for reading and writing folders and markdown documents in your MDflow workspace. Authenticate with a Personal Access Token, get clean JSON back. Everything here is also published as a machine-readable OpenAPI 3.1 spec.

Base URL
https://mdflow.cz
Auth
Bearer PAT
Rate limit
30 req / min
Format
JSON · no-store
$./authenticate

Authentication

Every request needs a Personal Access Token. Create one in Settings — it starts with mdf_. Send it in the Authorization header on every call:

$http
Authorization: Bearer mdf_your_token_here

A minimal request:

$bash
curl https://mdflow.cz/api/v1/folders \
  -H "Authorization: Bearer mdf_your_token_here"
Heads up: tokens grant workspace-level API access, including write and delete operations. Keep them in a secret store, never in client-side code or a public repo. Revoke compromised tokens from Settings.
$ls endpoints/

Endpoints

GET/api/v1/folders

Returns all folders owned by the authenticated user.

Request

$bash
curl https://mdflow.cz/api/v1/folders \
  -H "Authorization: Bearer mdf_your_token_here"

Response200 — array of Folder

$json
[
  {
    "id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
    "name": "API documentation",
    "description": "Reference docs and integration notes.",
    "created_at": "2026-01-12T09:24:00.000Z",
    "updated_at": "2026-02-03T16:40:12.000Z"
  }
]
Errors401429500
POST/api/v1/folders

Creates a folder owned by the authenticated user. If a sibling folder already uses the requested name, MDflow appends the lowest available numeric suffix.

Request body

$json
{
  "name": "Research",
  "description": "Source notes and synthesis drafts."
}

Request

$bash
curl -X POST https://mdflow.cz/api/v1/folders \
  -H "Authorization: Bearer mdf_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Research",
    "description": "Source notes and synthesis drafts."
  }'

Response201 — Folder

$json
{
  "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "name": "Research",
  "description": "Source notes and synthesis drafts.",
  "created_at": "2026-02-03T17:08:24.000Z",
  "updated_at": "2026-02-03T17:08:24.000Z"
}
PUT/api/v1/folders/{id}/description

Replaces the description on a folder owned by the authenticated user. Empty descriptions are stored as null.

Parameters

idpath · string · uuidFolder UUID.

Request body

$json
{
  "description": "Reference docs and integration notes."
}

Request

$bash
curl -X PUT https://mdflow.cz/api/v1/folders/3f2504e0-4f89-41d3-9a0c-0305e82c3301/description \
  -H "Authorization: Bearer mdf_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{ "description": "Reference docs and integration notes." }'

Response200 — Folder

$json
{
  "id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
  "name": "API documentation",
  "description": "Reference docs and integration notes.",
  "created_at": "2026-01-12T09:24:00.000Z",
  "updated_at": "2026-02-03T17:12:00.000Z"
}
DELETE/api/v1/folders/{id}

Deletes a folder owned by the authenticated user. Documents inside the folder are deleted by database cascade.

Parameters

idpath · string · uuidFolder UUID.

Request

$bash
curl -X DELETE https://mdflow.cz/api/v1/folders/3f2504e0-4f89-41d3-9a0c-0305e82c3301 \
  -H "Authorization: Bearer mdf_your_token_here"

Response204 — no content

No response body.

GET/api/v1/folders/{id}/documents

Returns documents inside the folder. A folder owned by another user returns 404. Bodies are omitted from this list.

Parameters

idpath · string · uuidFolder UUID.

Request

$bash
curl https://mdflow.cz/api/v1/folders/3f2504e0-4f89-41d3-9a0c-0305e82c3301/documents \
  -H "Authorization: Bearer mdf_your_token_here"

Response200 — array of DocumentListItem

$json
[
  {
    "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
    "title": "Getting started",
    "folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
    "is_public": false,
    "created_at": "2026-01-12T09:30:00.000Z",
    "updated_at": "2026-02-01T11:15:42.000Z"
  }
]
GET/api/v1/documents

Returns all documents owned by the authenticated user across every folder. Document bodies are omitted from this list response.

Request

$bash
curl https://mdflow.cz/api/v1/documents \
  -H "Authorization: Bearer mdf_your_token_here"

Response200 — array of DocumentListItem

$json
[
  {
    "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
    "title": "Getting started",
    "folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
    "is_public": false,
    "created_at": "2026-01-12T09:30:00.000Z",
    "updated_at": "2026-02-01T11:15:42.000Z"
  }
]
Errors401429500
POST/api/v1/documents

Creates a markdown document inside a folder owned by the authenticated user. If a sibling document already uses the requested title, MDflow appends the lowest available numeric suffix.

Request body

$json
{
  "folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
  "title": "Meeting notes.md",
  "body": "# Meeting notes\n\nCaptured from the browser."
}

Request

$bash
curl -X POST https://mdflow.cz/api/v1/documents \
  -H "Authorization: Bearer mdf_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
    "title": "Meeting notes.md",
    "body": "# Meeting notes\n\nCaptured from the browser."
  }'

Response201 — DocumentListItem

$json
{
  "id": "b42e6ff7-7d9a-4f25-9305-1ce41f8b7eb3",
  "title": "Meeting notes.md",
  "folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
  "is_public": false,
  "created_at": "2026-02-03T17:08:24.000Z",
  "updated_at": "2026-02-03T17:08:24.000Z"
}
GET/api/v1/documents/{id}

Returns one document including its markdown body. A document owned by another user returns 404.

Parameters

idpath · string · uuidDocument UUID.

Request

$bash
curl https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d \
  -H "Authorization: Bearer mdf_your_token_here"

Response200 — Document (includes body)

$json
{
  "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "title": "Getting started",
  "folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
  "is_public": false,
  "created_at": "2026-01-12T09:30:00.000Z",
  "updated_at": "2026-02-01T11:15:42.000Z",
  "body": "# Getting started\n\nWelcome to your workspace."
}
PUT/api/v1/documents/{id}/body

Replaces the markdown body of one document owned by the authenticated user. Title, folder, and sharing metadata are preserved.

Parameters

idpath · string · uuidDocument UUID.

Request body

$json
{
  "body": "# Getting started\n\nUpdated from the API."
}

Request

$bash
curl -X PUT https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d/body \
  -H "Authorization: Bearer mdf_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{ "body": "# Getting started\n\nUpdated from the API." }'

Response200 — Document

$json
{
  "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "title": "Getting started",
  "folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
  "is_public": false,
  "created_at": "2026-01-12T09:30:00.000Z",
  "updated_at": "2026-02-03T17:20:00.000Z",
  "body": "# Getting started\n\nUpdated from the API."
}
PUT/api/v1/documents/{id}/folder

Moves one document to another folder owned by the authenticated user. Duplicate titles in the target folder are automatically disambiguated.

Parameters

idpath · string · uuidDocument UUID.

Request body

$json
{
  "folder_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}

Request

$bash
curl -X PUT https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d/folder \
  -H "Authorization: Bearer mdf_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{ "folder_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7" }'

Response200 — DocumentListItem

$json
{
  "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "title": "Getting started",
  "folder_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "is_public": false,
  "created_at": "2026-01-12T09:30:00.000Z",
  "updated_at": "2026-02-03T17:22:00.000Z"
}
PUT/api/v1/documents/{id}/sharing

Sets public sharing and commenting options. MDflow generates share slugs server-side and never accepts caller-provided slugs.

Parameters

idpath · string · uuidDocument UUID.

Request body

$json
{
  "is_public": true,
  "allow_comments": true
}

Request

$bash
curl -X PUT https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d/sharing \
  -H "Authorization: Bearer mdf_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{ "is_public": true, "allow_comments": true }'

Response200 — SharingState

$json
{
  "is_public": true,
  "allow_comments": true,
  "share_slug": "6J4x...",
  "share_path": "/share/6J4x...",
  "public_url": "https://mdflow.cz/share/6J4x..."
}
GET/api/v1/documents/{id}/shares

Returns the people a document is privately shared with. Revoked shares are omitted.

Parameters

idpath · string · uuidDocument UUID.

Request

$bash
curl https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d/shares \
  -H "Authorization: Bearer mdf_your_token_here"

Response200 — DocumentShare[]

$json
[
  {
    "id": "1f2e3d4c-5b6a-7980-abcd-ef0123456789",
    "email": "teammate@example.com",
    "allow_comments": true,
    "status": "pending",
    "created_at": "2026-02-03T17:22:00.000Z",
    "accepted_at": null
  }
]
POST/api/v1/documents/{id}/shares

Privately shares a document with one email address, optionally allowing comments. Re-posting the same email updates its commenting permission. No invitation email is sent — the invitee gains access the next time they sign in with that email.

Parameters

idpath · string · uuidDocument UUID.

Request body

$json
{
  "email": "teammate@example.com",
  "allow_comments": true
}

Request

$bash
curl -X POST https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d/shares \
  -H "Authorization: Bearer mdf_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{ "email": "teammate@example.com", "allow_comments": true }'

Response201 — DocumentShare

$json
{
  "id": "1f2e3d4c-5b6a-7980-abcd-ef0123456789",
  "email": "teammate@example.com",
  "allow_comments": true,
  "status": "pending",
  "created_at": "2026-02-03T17:22:00.000Z",
  "accepted_at": null
}
DELETE/api/v1/documents/{id}/shares/{shareId}

Revokes one private share. Get share ids from the list endpoint. A share id that does not belong to this document returns 404.

Parameters

idpath · string · uuidDocument UUID.
shareIdpath · string · uuidPrivate share UUID.

Request

$bash
curl -X DELETE https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d/shares/1f2e3d4c-5b6a-7980-abcd-ef0123456789 \
  -H "Authorization: Bearer mdf_your_token_here"

Response204 — no content

No response body.

DELETE/api/v1/documents/{id}/shares

Revokes every private share on the document. Idempotent — succeeds even when nothing was shared.

Parameters

idpath · string · uuidDocument UUID.

Request

$bash
curl -X DELETE https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d/shares \
  -H "Authorization: Bearer mdf_your_token_here"

Response204 — no content

No response body.

DELETE/api/v1/documents/{id}

Deletes one document owned by the authenticated user.

Parameters

idpath · string · uuidDocument UUID.

Request

$bash
curl -X DELETE https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d \
  -H "Authorization: Bearer mdf_your_token_here"

Response204 — no content

No response body.

$cat schemas/

Schemas

Folder

FieldTypeDescription
idstring · uuidUnique folder identifier.
namestringFolder name.
descriptionstring | nullFree-text description. The primary context signal for the documents inside.
created_atstring · date-timeISO 8601.
updated_atstring · date-timeISO 8601.

CreateFolderInput

No extra fields are accepted.
FieldTypeDescription
namestring · 1–100 charsRequested folder name. Trimmed and automatically disambiguated.
descriptionstring · ≤ 500 charsOptional folder description. Empty text is stored as null.

UpdateFolderDescriptionInput

No extra fields are accepted.
FieldTypeDescription
descriptionstring · ≤ 500 charsReplacement folder description. Empty text is stored as null.

CreateDocumentInput

No extra fields are accepted.
FieldTypeDescription
folder_idstring · uuidID of an existing folder owned by the authenticated user.
titlestring · 1–100 charsRequested title. Trimmed before creation and automatically disambiguated against sibling documents.
bodystring · ≤ 512000 bytesMarkdown document body. UTF-8 encoded content must not exceed 500 KiB.

UpdateDocumentBodyInput

No extra fields are accepted.
FieldTypeDescription
bodystring · ≤ 512000 bytesReplacement markdown body. UTF-8 encoded content must not exceed 500 KiB.

MoveDocumentInput

No extra fields are accepted.
FieldTypeDescription
folder_idstring · uuidID of an existing destination folder owned by the authenticated user.

UpdateSharingInput

No extra fields are accepted. share_slug is always generated server-side.
FieldTypeDescription
is_publicbooleanWhether the public share link is active.
allow_commentsbooleanWhether signed-in visitors can comment on the shared document.

DocumentListItem

FieldTypeDescription
idstring · uuidUnique document identifier.
titlestringDocument title.
folder_idstring · uuidID of the parent folder.
is_publicbooleanWhether a public share link is currently active.
created_atstring · date-timeISO 8601.
updated_atstring · date-timeISO 8601.

Document

All DocumentListItem fields, plus:
FieldTypeDescription
bodystringThe full markdown document body.

SharingState

FieldTypeDescription
is_publicbooleanWhether the public share link is active.
allow_commentsbooleanWhether signed-in visitors can comment on the shared document.
share_slugstring | nullServer-generated share slug, or null when sharing is off.
share_pathstring | nullRelative share path such as /share/{slug}.
public_urlstring | nullAbsolute share URL only when the app base URL is configured.

CreateDocumentShareInput

No extra fields are accepted.
FieldTypeDescription
emailstring · emailRecipient email address. Trimmed and lowercased before storage.
allow_commentsbooleanWhether the recipient may comment. Optional, defaults to false (view only).

DocumentShare

FieldTypeDescription
idstring · uuidPrivate share identifier. Pass it to the remove-one endpoint.
emailstring · emailThe invited email address.
allow_commentsbooleanWhether the recipient may comment.
status"pending" | "accepted"pending until the recipient signs in with the invited email, then accepted.
created_atstring · date-timeISO 8601.
accepted_atstring · date-time | nullWhen the recipient accepted, or null while pending.

Error

FieldTypeDescription
errorstringHuman-readable error message.
$cat errors/

Error responses

Errors return the matching HTTP status and a JSON body shaped like the Error schema. All error responses are sent with Cache-Control: no-store.

400
Bad Request

The JSON body is malformed or fails validation.

{ "error": "Invalid request body" }
401
Unauthorized

Missing, malformed, invalid, or revoked bearer token.

{ "error": "Invalid bearer token" }
404
Not Found

The folder or document does not exist, or is owned by another user.

{ "error": "Document not found" }
429
Too Many Requests

The token or authenticated user exceeded 30 requests/minute. Includes a Retry-After header.

{ "error": "Rate limit exceeded" }
500
Server Error

Unexpected server error.

{ "error": "Unexpected API error" }
$cat for-agents.txt

For AI agents & crawlers

  • /openapi.json — the full OpenAPI 3.1 spec, served as JSON with open CORS.
  • /llms.txt — a concise index of MDflow's docs for language-model agents.
  • This page embeds schema.org/APIReference JSON-LD describing the API.
  • Prefer a turnkey integration? The MDflow MCP server wraps these endpoints as MCP tools.