> Public API.
An HTTP API for reading and writing workspaces, 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 token
- Rate limit
- 60 req / min
- Format
- JSON · no-store
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:
Authorization: Bearer mdf_your_token_hereA minimal request:
curl https://mdflow.cz/api/v1/folders \
-H "Authorization: Bearer mdf_your_token_here"The Authorization header accepts either token kind: a Personal Access Token (mdf_…, the simplest path for scripts and direct HTTP calls — every example here uses one), or an OAuth access token that MDflow issues when you connect it as a custom connector in Claude or ChatGPT (see the MCP docs). Either way, the owner needs MDflow Pro.
Endpoints
/api/v1/workspacesList all workspaces owned by the authenticated user, oldest first.
Request
curl https://mdflow.cz/api/v1/workspaces \
-H "Authorization: Bearer mdf_your_token_here"Response200 — array of Workspace
[
{
"id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12",
"name": "Personal",
"description": "Default workspace.",
"created_at": "2026-01-12T09:24:00.000Z",
"updated_at": "2026-02-03T16:40:12.000Z"
}
]/api/v1/workspacesCreate a workspace. Duplicate names are automatically disambiguated.
Request body
{
"name": "Client work",
"description": "Projects shared with clients."
}Request
curl -X POST https://mdflow.cz/api/v1/workspaces \
-H "Authorization: Bearer mdf_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Client work",
"description": "Projects shared with clients."
}'Response201 — Workspace
{
"id": "6e0a2d3f-9b4c-5d8e-af21-3a5b7c9d1e23",
"name": "Client work",
"description": "Projects shared with clients.",
"created_at": "2026-02-03T17:08:24.000Z",
"updated_at": "2026-02-03T17:08:24.000Z"
}/api/v1/workspaces/{id}Update a workspace's name and/or description (send at least one). A renamed workspace is disambiguated against the others.
Parameters
| id | path · string · uuid | Workspace UUID. |
Request body
{
"name": "Client work",
"description": "Active client projects."
}Request
curl -X PATCH https://mdflow.cz/api/v1/workspaces/6e0a2d3f-9b4c-5d8e-af21-3a5b7c9d1e23 \
-H "Authorization: Bearer mdf_your_token_here" \
-H "Content-Type: application/json" \
-d '{ "description": "Active client projects." }'Response200 — Workspace
{
"id": "6e0a2d3f-9b4c-5d8e-af21-3a5b7c9d1e23",
"name": "Client work",
"description": "Active client projects.",
"created_at": "2026-02-03T17:08:24.000Z",
"updated_at": "2026-02-03T17:12:00.000Z"
}/api/v1/workspaces/{id}Delete a workspace, cascading to its folders and their documents. Returns 409 if it is the owner's last workspace.
/api/v1/foldersReturns all folders owned by the authenticated user, each with its workspace_id and full path. Pass ?workspace_id= to list only the folders in one workspace.
Parameters
| workspace_id | query · string · uuid | Optional. Only list folders in this workspace. |
Request
curl https://mdflow.cz/api/v1/folders \
-H "Authorization: Bearer mdf_your_token_here"Response200 — array of Folder
[
{
"id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"name": "API documentation",
"description": "Reference docs and integration notes.",
"parent_id": null,
"workspace_id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12",
"path": [
{ "id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12", "name": "Personal", "type": "workspace" },
{ "id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301", "name": "API documentation", "type": "folder" }
],
"path_string": "Personal / API documentation",
"created_at": "2026-01-12T09:24:00.000Z",
"updated_at": "2026-02-03T16:40:12.000Z"
}
]/api/v1/folders/{id}Returns one folder including its full path (workspace → … → folder) and its compounded description — the labeled cascade of descriptions from the workspace down through each ancestor folder to this folder. A folder owned by another user returns 404.
Parameters
| id | path · string · uuid | Folder UUID. |
Request
curl https://mdflow.cz/api/v1/folders/7c9e6679-7425-40de-944b-e07fc1f90ae7 \
-H "Authorization: Bearer mdf_your_token_here"Response200 — FolderDetail
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"name": "Research",
"description": "Source notes and synthesis drafts.",
"parent_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"workspace_id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12",
"path": [
{ "id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12", "name": "Personal", "type": "workspace" },
{ "id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301", "name": "API documentation", "type": "folder" },
{ "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "name": "Research", "type": "folder" }
],
"path_string": "Personal / API documentation / Research",
"compounded_description": "Workspace \"Personal\": Default workspace.\n\nFolder \"API documentation\": Reference docs and integration notes.\n\nFolder \"Research\": Source notes and synthesis drafts.",
"created_at": "2026-02-03T17:08:24.000Z",
"updated_at": "2026-02-03T17:22:00.000Z"
}/api/v1/foldersCreates a folder owned by the authenticated user. If a sibling folder already uses the requested name, MDflow appends the lowest available numeric suffix. Pass parent_id to create a subfolder nested under an existing folder, or workspace_id to place a top-level folder in a specific workspace (defaults to your oldest workspace).
Request body
{
"name": "Research",
"description": "Source notes and synthesis drafts.",
"parent_id": null,
"workspace_id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12"
}Request
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
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"name": "Research",
"description": "Source notes and synthesis drafts.",
"parent_id": null,
"workspace_id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12",
"created_at": "2026-02-03T17:08:24.000Z",
"updated_at": "2026-02-03T17:08:24.000Z"
}/api/v1/folders/{id}Updates a folder owned by the authenticated user. Provide at least one of name, description, or parent_id. Renaming or moving disambiguates the name against the destination siblings. Setting parent_id reparents the folder (null moves it to the top level); moving a folder under itself, one of its own descendants, or into a different workspace is rejected with 400.
Parameters
| id | path · string · uuid | Folder UUID. |
Request body
{
"name": "Reference",
"description": "Reference docs and integration notes.",
"parent_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301"
}Request
curl -X PATCH https://mdflow.cz/api/v1/folders/7c9e6679-7425-40de-944b-e07fc1f90ae7 \
-H "Authorization: Bearer mdf_your_token_here" \
-H "Content-Type: application/json" \
-d '{ "description": "Reference docs and integration notes." }'Response200 — Folder
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"name": "Research",
"description": "Reference docs and integration notes.",
"parent_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"workspace_id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12",
"created_at": "2026-02-03T17:08:24.000Z",
"updated_at": "2026-02-03T17:22:00.000Z"
}/api/v1/folders/{id}Deletes a folder owned by the authenticated user. Documents inside the folder are deleted by database cascade.
/api/v1/folders/{id}/documentsReturns documents inside the folder. A folder owned by another user returns 404. Bodies are omitted from this list.
Parameters
| id | path · string · uuid | Folder UUID. |
Request
curl https://mdflow.cz/api/v1/folders/3f2504e0-4f89-41d3-9a0c-0305e82c3301/documents \
-H "Authorization: Bearer mdf_your_token_here"Response200 — array of DocumentListItem
[
{
"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"
}
]/api/v1/documentsReturns all documents owned by the authenticated user across every folder. Document bodies are omitted from this list response. Pass ?workspace_id= to list only documents in one workspace.
Parameters
| workspace_id | query · string · uuid | List only documents in this workspace. |
Request
curl https://mdflow.cz/api/v1/documents \
-H "Authorization: Bearer mdf_your_token_here"Response200 — array of DocumentListItem
[
{
"id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"title": "Getting started",
"folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"is_public": false,
"workspace_id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12",
"path": [
{ "id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12", "name": "Personal", "type": "workspace" },
{ "id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301", "name": "API documentation", "type": "folder" },
{ "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d", "name": "Getting started", "type": "document" }
],
"path_string": "Personal / API documentation / Getting started",
"created_at": "2026-01-12T09:30:00.000Z",
"updated_at": "2026-02-01T11:15:42.000Z"
}
]/api/v1/documentsCreates 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
{
"folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"title": "Meeting notes.md",
"body": "# Meeting notes\n\nCaptured from the browser."
}Request
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
{
"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"
}/api/v1/documents/{id}Renames a document owned by the authenticated user. The new title is disambiguated against the other documents in the same folder. Returns the document without its body.
Parameters
| id | path · string · uuid | Document UUID. |
Request body
{
"title": "Quarterly plan.md"
}Request
curl -X PATCH https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d \
-H "Authorization: Bearer mdf_your_token_here" \
-H "Content-Type: application/json" \
-d '{ "title": "Quarterly plan.md" }'Response200 — DocumentListItem
{
"id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"title": "Quarterly plan.md",
"folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"is_public": false,
"created_at": "2026-01-12T09:30:00.000Z",
"updated_at": "2026-02-03T17:25:00.000Z"
}/api/v1/documents/{id}Returns one document including its markdown body. A document owned by another user returns 404.
Parameters
| id | path · string · uuid | Document UUID. |
Request
curl https://mdflow.cz/api/v1/documents/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d \
-H "Authorization: Bearer mdf_your_token_here"Response200 — Document (includes body)
{
"id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"title": "Getting started",
"folder_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"is_public": false,
"workspace_id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12",
"path": [
{ "id": "5d9f1c2e-8a3b-4c7d-9e10-2f4a6b8c0d12", "name": "Personal", "type": "workspace" },
{ "id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301", "name": "API documentation", "type": "folder" },
{ "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d", "name": "Getting started", "type": "document" }
],
"path_string": "Personal / API documentation / Getting started",
"compounded_description": "Workspace \"Personal\": Default workspace.\n\nFolder \"API documentation\": Reference docs and integration notes.",
"created_at": "2026-01-12T09:30:00.000Z",
"updated_at": "2026-02-01T11:15:42.000Z",
"body": "# Getting started\n\nWelcome to your workspace."
}/api/v1/documents/{id}/bodyReplaces the markdown body of one document owned by the authenticated user. Title, folder, and sharing metadata are preserved.
Parameters
| id | path · string · uuid | Document UUID. |
Request body
{
"body": "# Getting started\n\nUpdated from the API."
}Request
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
{
"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."
}/api/v1/documents/{id}/folderMoves one document to another folder owned by the authenticated user. Duplicate titles in the target folder are automatically disambiguated.
Parameters
| id | path · string · uuid | Document UUID. |
Request body
{
"folder_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}Request
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
{
"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"
}/api/v1/documents/{id}/sharingSets public sharing and commenting options. MDflow generates share slugs server-side and never accepts caller-provided slugs.
Parameters
| id | path · string · uuid | Document UUID. |
Request body
{
"is_public": true,
"allow_comments": true
}Request
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
{
"is_public": true,
"allow_comments": true,
"share_slug": "6J4x...",
"share_path": "/share/6J4x...",
"public_url": "https://mdflow.cz/share/6J4x..."
}/api/v1/documents/{id}Deletes one document owned by the authenticated user.
Schemas
Workspace
| Field | Type | Description |
|---|---|---|
| id | string · uuid | Unique workspace identifier. |
| name | string | Workspace name. |
| description | string | null | Free-text workspace description. |
| created_at | string · date-time | ISO 8601. |
| updated_at | string · date-time | ISO 8601. |
Folder
| Field | Type | Description |
|---|---|---|
| id | string · uuid | Unique folder identifier. |
| name | string | Folder name. |
| description | string | null | Free-text description. The primary context signal for the documents inside. |
| parent_id | string · uuid | null | Parent folder UUID, or null for a top-level folder. |
| workspace_id | string · uuid | The workspace this folder belongs to. |
| path | PathSegment[] | Full path from the workspace root down to this folder, workspace first. Returned by list and get; omitted from create and update responses. |
| path_string | string | Path segment names joined by " / ". Returned by list and get; omitted from create and update responses. |
| created_at | string · date-time | ISO 8601. |
| updated_at | string · date-time | ISO 8601. |
PathSegment
| Field | Type | Description |
|---|---|---|
| id | string · uuid | Workspace, folder, or document identifier for this segment. |
| name | string | Workspace, folder, or document name. |
| type | "workspace" | "folder" | "document" | Whether this segment is the workspace root, an ancestor folder, or the document/folder leaf itself. |
FolderDetail
All Folder fields, plus (path and path_string are always present here):| Field | Type | Description |
|---|---|---|
| compounded_description | string | Labeled cascade of descriptions from the workspace down through each ancestor folder to this folder. Empty string when nothing in the chain has a description. |
CreateFolderInput
No extra fields are accepted.| Field | Type | Description |
|---|---|---|
| name | string · 1–100 chars | Requested folder name. Trimmed and automatically disambiguated. |
| description | string · ≤ 5000 chars | Optional folder description. Empty text is stored as null. |
| parent_id | string · uuid | null | Optional parent folder UUID to create a subfolder. Omit or null for a top-level folder. |
| workspace_id | string · uuid | Optional workspace for a top-level folder. Ignored when parent_id is set. Defaults to your oldest workspace. |
PatchFolderInput
No extra fields are accepted. Provide at least one field.| Field | Type | Description |
|---|---|---|
| name | string · 1–100 chars | Optional new folder name. Trimmed and disambiguated against destination siblings. |
| description | string · ≤ 5000 chars | Optional replacement description. Empty text is stored as null. |
| parent_id | string · uuid | null | Optional destination parent folder UUID, or null to move the folder to the top level. |
CreateDocumentInput
No extra fields are accepted.| Field | Type | Description |
|---|---|---|
| folder_id | string · uuid | ID of an existing folder owned by the authenticated user. |
| title | string · 1–100 chars | Requested title. Trimmed before creation and automatically disambiguated against sibling documents. |
| body | string · ≤ 512000 bytes | Markdown document body. UTF-8 encoded content must not exceed 500 KiB. |
UpdateDocumentBodyInput
No extra fields are accepted.| Field | Type | Description |
|---|---|---|
| body | string · ≤ 512000 bytes | Replacement markdown body. UTF-8 encoded content must not exceed 500 KiB. |
MoveDocumentInput
No extra fields are accepted.| Field | Type | Description |
|---|---|---|
| folder_id | string · uuid | ID of an existing destination folder owned by the authenticated user. |
UpdateSharingInput
No extra fields are accepted. share_slug is always generated server-side.| Field | Type | Description |
|---|---|---|
| is_public | boolean | Whether the public share link is active. |
| allow_comments | boolean | Whether signed-in visitors can comment on the shared document. |
DocumentListItem
| Field | Type | Description |
|---|---|---|
| id | string · uuid | Unique document identifier. |
| title | string | Document title. |
| folder_id | string · uuid | ID of the parent folder. |
| is_public | boolean | Whether a public share link is currently active. |
| workspace_id | string · uuid | The workspace this document belongs to (via its folder). Returned by list and get; omitted from create, rename, move, and body responses. |
| path | PathSegment[] | Full path from the workspace root down to and including this document, workspace first. Returned by list and get; omitted from mutation responses. |
| path_string | string | Path segment names joined by " / ". |
| created_at | string · date-time | ISO 8601. |
| updated_at | string · date-time | ISO 8601. |
Document
All DocumentListItem fields, plus (workspace_id, path, and path_string are always present here):| Field | Type | Description |
|---|---|---|
| body | string | The full markdown document body. |
| compounded_description | string | Labeled cascade of descriptions from the workspace down through each ancestor folder to this document's folder. Empty string when nothing in the chain has a description. |
SharingState
| Field | Type | Description |
|---|---|---|
| is_public | boolean | Whether the public share link is active. |
| allow_comments | boolean | Whether signed-in visitors can comment on the shared document. |
| share_slug | string | null | Server-generated share slug, or null when sharing is off. |
| share_path | string | null | Relative share path such as /share/{slug}. |
| public_url | string | null | Absolute share URL only when the app base URL is configured. |
CreateDocumentShareInput
No extra fields are accepted.| Field | Type | Description |
|---|---|---|
| string · email | Recipient email address. Trimmed and lowercased before storage. | |
| allow_comments | boolean | Whether the recipient may comment. Optional, defaults to false (view only). |
DocumentShare
| Field | Type | Description |
|---|---|---|
| id | string · uuid | Private share identifier. Pass it to the remove-one endpoint. |
| string · email | The invited email address. | |
| allow_comments | boolean | Whether the recipient may comment. |
| status | "pending" | "accepted" | pending until the recipient signs in with the invited email, then accepted. |
| created_at | string · date-time | ISO 8601. |
| accepted_at | string · date-time | null | When the recipient accepted, or null while pending. |
Error
| Field | Type | Description |
|---|---|---|
| error | string | Human-readable error message. |
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.
The JSON body is malformed or fails validation.
{ "error": "Invalid request body" }Missing, malformed, invalid, or revoked bearer token.
{ "error": "Invalid bearer token" }The token is valid but its owner is not on MDflow Pro. Agent control (the REST API and MCP) requires Pro, so every endpoint returns 403 without it. Creating a document also returns 403 once the account reaches its document limit.
{ "error": "Pro plan required" }The workspace, folder, or document does not exist, or is owned by another user.
{ "error": "Document not found" }The workspace is the owner's only workspace and cannot be deleted.
{ "error": "Cannot delete your last workspace" }The token or authenticated user exceeded 60 requests/minute. Includes a Retry-After header.
{ "error": "Rate limit exceeded" }Unexpected server error.
{ "error": "Unexpected API error" }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/APIReferenceJSON-LD describing the API. - ›Prefer a turnkey integration? The MDflow MCP server wraps these endpoints as MCP tools.