REST API reference
The MMD Studio REST API lets you create, read, update, delete, and share diagrams on behalf of a signed-in user. Everything a browser session can do with diagrams, an API token can do too.
Base URL
https://mmd.studio/api Authentication
All endpoints except /api/diagrams/:id/public require
an API token. Pass it in the Authorization header as a
bearer token:
Authorization: Bearer mmd_... Create and manage tokens at API tokens.
The diagram resource
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"title": "User signup flow",
"code": "flowchart TD\n A[Start] --> B[Submit]",
"visibility": "private",
"linkAccess": "read",
"updatedAt": "2026-04-14T22:15:49.862Z"
} | Field | Type | Description |
|---|---|---|
id | string (UUID v4) | Client-generated; the caller picks this when creating. |
title | string (1–200) | Free-form title shown in the UI. |
code | string (≤100k) | The Mermaid source. |
visibility | private | link | invite | Default private. |
linkAccess | read | edit | Only meaningful when visibility = "link". |
updatedAt | ISO-8601 timestamp | Used for last-write-wins on conflicts. |
Endpoints
List diagrams account required
GET /api/diagrams
Returns a snapshot of every diagram you own, plus a list of tombstones for recently-deleted diagrams (so offline clients can reconcile).
curl -H "Authorization: Bearer $MMD_TOKEN" \
https://mmd.studio/api/diagrams Response
{
"diagrams": [
{ "id": "...", "title": "...", "code": "...", "visibility": "private", "linkAccess": "read", "updatedAt": "..." }
],
"deleted": [
{ "id": "...", "deletedAt": "..." }
]
} Fetch a single diagram account required
GET /api/diagrams/:id
Returns the diagram if you own it, 404 otherwise (the server does not distinguish "doesn't exist" from "not yours" to avoid leaking id space).
curl -H "Authorization: Bearer $MMD_TOKEN" \
https://mmd.studio/api/diagrams/$ID Create or update a diagram account required
PUT /api/diagrams/:id
The same endpoint handles both. If the id doesn't
exist, the diagram is created. If it exists and your
updatedAt is newer than the server's, it's updated. If
your updatedAt is older, the server keeps its version
and returns it so you can reconcile.
ID=$(uuidgen | tr '[:upper:]' '[:lower:]')
curl -H "Authorization: Bearer $MMD_TOKEN" \
-H "Content-Type: application/json" \
-X PUT "https://mmd.studio/api/diagrams/$ID" \
-d "{
\"title\": \"User signup flow\",
\"code\": \"flowchart TD\\n A[Start] --> B[Submit]\",
\"updatedAt\": $(date +%s000),
\"visibility\": \"private\",
\"linkAccess\": \"read\"
}" Request body
| Field | Required | Notes |
|---|---|---|
title | yes | 1–200 characters |
code | yes | ≤100k characters of Mermaid source |
updatedAt | yes | Epoch ms or ISO-8601. Use the current time for new writes. |
visibility | no | Defaults to private on create, preserved on update. |
linkAccess | no | Defaults to read on create, preserved on update. |
Response
{ "diagram": { /* canonical server state */ } } Status codes: 200 on success or stale-write bounce; 400 for validation failures; 403 when the id belongs to another user; 410 when the diagram has a newer tombstone.
Delete a diagram account required
DELETE /api/diagrams/:id
curl -H "Authorization: Bearer $MMD_TOKEN" \
-H "Content-Type: application/json" \
-X DELETE "https://mmd.studio/api/diagrams/$ID" \
-d "{\"deletedAt\": $(date +%s000)}" deletedAt is optional; omit it and the server uses its
own now(). A tombstone is written so offline clients
can reconcile their local copies later.
Fetch a public (shared) diagram
GET /api/diagrams/:id/public
Unauthenticated read of a non-private diagram. Returns 404 if the diagram is private or doesn't exist (the two cases aren't distinguished in the response).
curl https://mmd.studio/api/diagrams/$ID/public Response
{
"diagram": { "id": "...", "title": "...", "code": "...", "visibility": "link", "linkAccess": "read", "updatedAt": "..." },
"owner": { "email": "alice@example.com" },
"access": "read"
} Errors
Errors are JSON with a single error field.
{ "error": "invalid title" } | Status | Meaning |
|---|---|
| 400 | Validation failure (bad id, title, code, updatedAt). |
| 401 | Missing or invalid token. |
| 403 | The diagram exists but belongs to another user. |
| 404 | Not found (or private and not yours). |
| 410 | The diagram has been deleted (newer tombstone). |
Rate limits
API requests are limited per account:
| Plan | Daily limit | Reset |
|---|---|---|
| Free | 10 requests / day (across all tokens on the account) | UTC midnight |
| Pro | Unlimited | — |
Over-limit requests return 429 Too Many Requests. The
response includes a Retry-After header (in seconds)
with time until reset. See pricing for the
Pro plan.