API documentation

The public Markdown Tidy API. Convert / clean / repair markdown into HTML, plain text, PDF, DOCX, or PNG. Authenticate with an `X-API-KEY` header — create one in your dashboard at /account/api-keys. Each successful /convert call debits 1 credit from your wallet.

Authentication & conventions
The base URL, how to authenticate, and the shape every error takes.

Base URL

https://mdtidy.com

Authentication

apiKeyAuth
Issued via dashboard. Prefix `mt_test_…` for sandbox, `mt_live_…` for production.
bearerAuth
Workspace `/v1` routes accept the same dashboard-issued key as `Authorization: Bearer mt_live_…`. First-party UI uses the session cookie instead.

Quickstart

curl -X POST https://mdtidy.com/api/v1/convert \
  -H "X-API-KEY: $MARKDOWN_TIDY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "markdown": "# Hello\n\nWorld.",
    "format": "html"
  }'

Inline output for HTML/text; base64 outputBase64 for PDF/DOCX/PNG. Every successful /convert debits 1 credit; 4xx/5xx are free.

Error format

Every 4xx/5xx shares the same envelope. The requestId is also returned as the X-Request-ID header — quote it when you contact support.

{
  "error": {
    "code": "invalid_request",
    "message": "format: required",
    "requestId": "f0c7…"
  }
}

Design systems

Pass designSystem on /convert to render in a typographic identity. Defaults to minimal-clean.

  • minimal-cleanMinimal Clean
  • executive-reportExecutive Report
  • developer-docsTechnical Doc
Categories
The API is grouped into 6categories. Here’s what each one is for.
Convert
Clean, repair, and render markdown into any output format.
Usage & credits
Check your wallet balance, plan, and recent activity.
Projects
Create, list, update, and delete workspace projects.
Folders
Organise files into folders within a project.
Files
Save, read, autosave, copy, and delete markdown files.
Sharing
Public links and per-viewer invites for a project.

Endpoints

23 endpoints across 6 categories. Jump from the list, or narrow to a single category with the dropdown.

Convert

Clean, repair, and render markdown into any output format.

post/api/v1/convertAPI key
Clean, repair, and convert markdown
Runs the markdown through the requested pipeline (clean / repair) and renders to the requested output format. Charges 1 credit per successful render; failures are refunded automatically.

Request body

  • markdownstringrequired

    The markdown source to convert. UTF-8. Hard cap: 1 MB.

  • formatstringrequired

    One of: html, text, pdf, docx, png

    Output format.

  • designSystemstringoptional

    One of: minimal-clean, executive-report, developer-docs

    Slug of a built-in design system. Defaults to `minimal-clean`. An unknown slug returns 400 `unknown_design_system`. Available: `minimal-clean` (Minimal Clean), `executive-report` (Executive Report), `developer-docs` (Technical Doc).

  • settingsConvertSettingsoptional

    Optional per-stage configuration envelope. Future stages (render, repair, etc.) will namespace their options under this object alongside `tidy`. Omit to accept all defaults.

  • pagePageSettingsoptional

    Optional per-document page geometry + font scale. Every field is optional; omitted fields inherit from the design system. Geometry (paper size / orientation / margins) affects PDF, DOCX, and PNG; font scale additionally affects HTML and text. No credit cost.

Responses

200
Conversion succeeded.
400
Schema validation failed.
401
X-API-KEY is malformed, unknown, or revoked.
402
Wallet has insufficient credits to satisfy the request.
413
Request body exceeds the 1 MB cap.
422
Requested format is not one of the supported outputs.
429
Per-key rate limit (60/min) exceeded.
500
Server failed to complete the request.

Usage & credits

Check your wallet balance, plan, and recent activity.

get/api/v1/usageAPI key
Read the caller credit balance and recent usage
Returns the current wallet balance + recent API calls for the authenticated principal. Cheap; suitable for a dashboard widget.

Responses

200
Wallet balance + recent calls.
401
X-API-KEY header was not supplied.
500
Server failed to complete the request.
get/api/v1/creditsBearer / session
Read the caller workspace entitlement
Returns the entitlement object the workspace UI gates on (`can_save` / `can_share` / `unlimited_save`). Derived server-side from the wallet balance + plan. Unauthenticated callers receive a 200 with every gate closed.

Responses

200
Entitlement object.
500
Server failed to complete the request.

Projects

Create, list, update, and delete workspace projects.

get/api/v1/projectsBearer / session
List projects

Parameters

  • scopequerystring

Responses

200
Project list.
401
X-API-KEY is malformed, unknown, or revoked.
429
Per-key rate limit (60/min) exceeded.
post/api/v1/projectsBearer / session
Create a project

Request body

  • namestringrequired
  • descriptionstringoptional

Responses

201
Project created.
401
X-API-KEY is malformed, unknown, or revoked.
409
Name collision, stale write, or a resource limit was reached.
422
Request body failed validation.
429
Per-key rate limit (60/min) exceeded.
get/api/v1/projects/{id}Bearer / session
Get a project with its folders + files

Parameters

  • idpathstring · uuidrequired
  • include_archivedqueryboolean

Responses

200
Project + folders + files.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
429
Per-key rate limit (60/min) exceeded.
patch/api/v1/projects/{id}Bearer / session
Rename / set description / archive / restore a project

Parameters

  • idpathstring · uuidrequired

Request body

  • namestringoptional
  • descriptionstring | nulloptional
  • archivedbooleanoptional

Responses

200
Updated project.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
422
Request body failed validation.
429
Per-key rate limit (60/min) exceeded.
delete/api/v1/projects/{id}Bearer / session
Permanently delete a project (cascade + GCS sweep + revoke shares)

Parameters

  • idpathstring · uuidrequired

Responses

200
Deleted.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
429
Per-key rate limit (60/min) exceeded.

Folders

Organise files into folders within a project.

post/api/v1/projects/{id}/foldersBearer / session
Create a folder under a project

Parameters

  • idpathstring · uuidrequired

Request body

  • namestringrequired
  • parent_folder_idstring · uuid | nulloptional

    Optional parent folder (nesting). When set, the folder is created inside it; omit/null for the project root. Must belong to the addressed project.

Responses

201
Folder created.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
409
Name collision, stale write, or a resource limit was reached.
422
Request body failed validation.
429
Per-key rate limit (60/min) exceeded.
patch/api/v1/folders/{id}Bearer / session
Rename a folder

Parameters

  • idpathstring · uuidrequired

Request body

  • namestringrequired

Responses

200
Updated folder.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
409
Name collision, stale write, or a resource limit was reached.
422
Request body failed validation.
429
Per-key rate limit (60/min) exceeded.
delete/api/v1/folders/{id}Bearer / session
Delete a folder (409 if it holds active files; archived files move to root)
By default a folder holding active files is refused with `409 folder_not_empty` and archived files inside move up to the parent. Pass `cascade=true` to permanently delete the entire subtree (files + subfolders, archived included) and sweep its objects.

Parameters

  • idpathstring · uuidrequired
  • cascadequeryboolean

    Hard-delete the whole subtree instead of refusing on active files.

Responses

200
Deleted.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
409
Name collision, stale write, or a resource limit was reached.
429
Per-key rate limit (60/min) exceeded.

Files

Save, read, autosave, copy, and delete markdown files.

post/api/v1/filesBearer / session
First save — create a file (charges 1 credit)
Writes content to GCS (saga) then atomically charges 1 credit (`file_save`) and inserts the file at version 1. Accepts an `Idempotency-Key` header — replays return the original result with no second charge.

Parameters

  • Idempotency-Keyheaderstring

Request body

  • project_idstring · uuidrequired
  • folder_idstring · uuid | nulloptional
  • namestringrequired
  • contentstringrequired

Responses

201
File created.
401
X-API-KEY is malformed, unknown, or revoked.
402
Wallet has insufficient credits to satisfy the request.
404
Resource not found, or not owned by the caller (IDOR-safe).
409
Name collision, stale write, or a resource limit was reached.
413
Request body exceeds the 1 MB cap.
422
Request body failed validation.
429
Per-key rate limit (60/min) exceeded.
get/api/v1/files/{id}Bearer / session
Read a file (returns version + ETag)

Parameters

  • idpathstring · uuidrequired

Responses

200
File metadata + content pointers.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
429
Per-key rate limit (60/min) exceeded.
patch/api/v1/files/{id}Bearer / session
Autosave / rename / move / archive / restore a file
Content writes require an optimistic-lock precondition: send `version` in the request body (recommended). The `If-Match: "<version>"` header is also accepted, but callers behind a CDN should prefer `version` — `If-Match` is a reserved HTTP conditional header (RFC 9110 §13.1.1) that an intermediary may evaluate at the edge and answer with 412 even when the write succeeds. The origin itself never returns 412. A stale precondition returns 409 with the current server copy. Content writes overwrite the working blob and bump the version; they do not create version-history rows. 0 credits.

Parameters

  • idpathstring · uuidrequired
  • If-Matchheaderstring

    Legacy optimistic-lock precondition (quoted version, e.g. `"3"`). Accepted, but prefer the `version` body field — a CDN may evaluate this reserved conditional header at the edge and return 412.

Request body

  • contentstringoptional
  • namestringoptional
  • folder_idstring · uuid | nulloptional
  • archivedbooleanoptional
  • versionintegeroptional

    Optimistic-lock precondition for content writes; recommended over the If-Match header (which a CDN may 412 at the edge).

Responses

200
Updated file.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
409
Name collision, stale write, or a resource limit was reached.
412
Edge-injected: a CDN evaluated the `If-Match` request header and rejected it (the origin never returns 412, and the write may have already committed). Use the `version` body field instead.
413
Request body exceeds the 1 MB cap.
422
Request body failed validation.
428
A content write omitted the required If-Match / version precondition.
429
Per-key rate limit (60/min) exceeded.
delete/api/v1/files/{id}Bearer / session
Permanently delete a file (hard delete + GCS sweep)

Parameters

  • idpathstring · uuidrequired

Responses

200
Deleted.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
429
Per-key rate limit (60/min) exceeded.
post/api/v1/files/{id}/copyBearer / session
Copy a file as a new file (charges 1 credit)

Parameters

  • idpathstring · uuidrequired
  • Idempotency-Keyheaderstring

Responses

201
File copied.
401
X-API-KEY is malformed, unknown, or revoked.
402
Wallet has insufficient credits to satisfy the request.
404
Resource not found, or not owned by the caller (IDOR-safe).
409
Name collision, stale write, or a resource limit was reached.
422
Request body failed validation.
429
Per-key rate limit (60/min) exceeded.

Sharing

Public links and per-viewer invites for a project.

get/api/v1/projects/{id}/shareBearer / session
Current share state for a project

Parameters

  • idpathstring · uuidrequired

Responses

200
Share state.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
429
Per-key rate limit (60/min) exceeded.
post/api/v1/projects/{id}/share/invitesBearer / session
Invite viewers (restricted mode; 1 credit per call)

Parameters

  • idpathstring · uuidrequired
  • Idempotency-Keyheaderstring

Request body

  • emailsstring[]required

    Up to 25 viewer emails. 1 credit per call; already-invited emails are free.

Responses

200
Invitees added; share is now restricted.
401
X-API-KEY is malformed, unknown, or revoked.
402
Wallet has insufficient credits to satisfy the request.
404
Resource not found, or not owned by the caller (IDOR-safe).
409
Name collision, stale write, or a resource limit was reached.
413
Request body exceeds the 1 MB cap.
422
Request body failed validation.
429
Per-key rate limit (60/min) exceeded.
delete/api/v1/projects/{id}/share/invites/{email}Bearer / session
Remove an invitee (0 credits)

Parameters

  • idpathstring · uuidrequired
  • emailpathstring · emailrequired

Responses

200
Invitee removed (or already absent).
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
429
Per-key rate limit (60/min) exceeded.
post/api/v1/projects/{id}/share/privateBearer / session
Make the project private (retain slug + invitees inactive; 0 credits)

Parameters

  • idpathstring · uuidrequired

Responses

200
Project is now private.
401
X-API-KEY is malformed, unknown, or revoked.
404
Resource not found, or not owned by the caller (IDOR-safe).
429
Per-key rate limit (60/min) exceeded.