API Reference

Base URL: /api

Authentication

All write endpoints require authentication via API key. Generate a key in Settings → API Keys and include it as a Bearer token:

Authorization: Bearer mb_your_key_here

Scopes:

  • Read Only — view documents and collections
  • Read / Write — create and update documents and collections
  • Full Access — all permissions including delete

API keys are managed exclusively through the web interface at Settings → API Keys. There are no API endpoints for key management.

Get Current User

GET /api/user

Requires authentication. Returns the authenticated user.


Documents

List Documents

GET /api/documents

Requires authentication. Returns a paginated list of the authenticated user’s documents.

Response: 200

{
  "data": [
    {
      "slug": "my-document",
      "short_id": "a3f9b2c1",
      "url": "/@username/my-document-a3f9b2c1",
      "title": "My Document",
      "description": null,
      "version": 3,
      "visibility": "public",
      "markdown": null,
      "html": null,
      "toc": [...],
      "frontmatter": {},
      "commit_message": null,
      "created_at": "2026-03-31T00:00:00.000000Z",
      "updated_at": "2026-03-31T00:00:00.000000Z",
      "version_url": "/api/documents/my-document/versions/3",
      "latest_url": "/api/documents/my-document"
    }
  ],
  "links": { ... },
  "meta": { ... }
}

Create Document

POST /api/documents

Requires authentication.

Body:

Field Type Required Description
title string yes Document title (max 255)
markdown string yes Markdown content
slug string no Custom slug (lowercase, hyphens, unique per user)
description string no Short description (max 1000)
visibility string no public, unlisted, or private (defaults to user setting)
commit_message string no Version commit message (max 255)

Response: 201

{
  "data": {
    "slug": "my-document",
    "short_id": "a3f9b2c1",
    "url": "/@username/my-document-a3f9b2c1",
    "title": "My Document",
    "description": null,
    "version": 1,
    "visibility": "public",
    "markdown": "# My Document\n...",
    "html": "<h1>My Document</h1>...",
    "toc": [...],
    "frontmatter": {},
    "commit_message": null,
    "created_at": "2026-03-31T00:00:00.000000Z",
    "updated_at": "2026-03-31T00:00:00.000000Z",
    "version_url": "/api/documents/my-document/versions/1",
    "latest_url": "/api/documents/my-document"
  }
}

Get Document

GET /api/documents/{slug}

Public and unlisted documents are accessible without auth. Private documents require authentication as the owner.

Response: 200 — same structure as create response.

Update Document

PUT /api/documents/{slug}

Requires authentication as the owner. Creates a new version.

Body:

Field Type Required Description
markdown string yes Updated markdown content
title string no Updated title
commit_message string no What changed

Response: 200

Update Metadata

PATCH /api/documents/{slug}/meta

Requires authentication as the owner. Updates title, description, or visibility without creating a new version.

Body:

Field Type Required
title string no
description string no
visibility string no

Response: 200

Delete Document

DELETE /api/documents/{slug}

Requires authentication as the owner. Soft-deletes the document.

Response: 200

{ "message": "Document deleted." }

Preview Markdown

POST /api/documents/preview

Requires authentication. Renders markdown to HTML without saving.

Body:

Field Type Required
markdown string yes

Response: 200

{
  "html": "<h1>Hello</h1>",
  "toc": [{ "level": 1, "id": "content-hello", "text": "Hello" }],
  "frontmatter": {}
}

List Versions

GET /api/documents/{slug}/versions

Returns paginated list of all versions.

Response: 200

{
  "data": [
    {
      "version_number": 2,
      "commit_message": "Fixed typo",
      "created_at": "2026-03-31T00:00:00.000000Z"
    }
  ],
  "links": { ... },
  "meta": { ... }
}

Get Specific Version

GET /api/documents/{slug}/versions/{version_number}

Response: 200 — document data with the specified version’s content.


Collections

List Collections

GET /api/collections

Requires authentication. Returns a paginated list of the authenticated user’s collections with their documents.

Response: 200

{
  "data": [
    {
      "slug": "my-collection",
      "title": "My Collection",
      "description": "...",
      "visibility": "public",
      "documents": [
        { "slug": "doc-one", "title": "Doc One", "position": 0 }
      ],
      "created_at": "2026-03-31T00:00:00.000000Z",
      "updated_at": "2026-03-31T00:00:00.000000Z"
    }
  ],
  "links": { ... },
  "meta": { ... }
}

Create Collection

POST /api/collections

Requires authentication.

Body:

Field Type Required Description
title string yes Collection title (max 255)
slug string no Custom slug
description string no Description (max 1000)
visibility string no public, unlisted, or private

Response: 201

{
  "data": {
    "slug": "my-collection",
    "title": "My Collection",
    "description": "...",
    "visibility": "public",
    "documents": []
  }
}

Get Collection

GET /api/collections/{slug}

Response: 200 — collection with nested documents.

Update Collection

PUT /api/collections/{slug}

Requires authentication as the owner.

Body:

Field Type Required
title string no
description string no
visibility string no

Response: 200

Manage Collection Documents

Set documents (sync):

POST /api/collections/{slug}/documents

Body:

{
  "documents": [
    { "slug": "doc-one", "position": 0 },
    { "slug": "doc-two", "position": 1 }
  ]
}

This replaces the collection’s document list with the provided set.

Remove a document:

DELETE /api/collections/{slug}/documents/{document_slug}

GET /api/search?q={query}

Searches public documents by title and description.

Parameters:

Param Type Required Description
q string yes Search query (1-255 characters)

Response: 200

{
  "data": [
    {
      "slug": "my-doc",
      "title": "My Document",
      "description": "...",
      "visibility": "public"
    }
  ]
}

Error Responses

All errors return JSON:

{
  "message": "Error description.",
  "errors": {
    "field": ["Validation message"]
  }
}
Status Meaning
401 Unauthenticated — missing or invalid credentials
403 Forbidden — you don’t have permission
404 Not found
410 Gone — document has expired
422 Validation error — check errors field
429 Rate limited

Rate Limits

API requests are rate-limited per user. The current limits are returned in response headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59