API Documentation

Base URL

https://draftmark.app/api/v1

Authentication

Three levels of auth, depending on what you need:

Public docs can be created without an account and read without auth. Private docs require an account (sign in or register via API).

If you own a doc via your account, you can GET, PATCH, and DELETE it using your acct_ key — no magic token needed.

Accounts

POST /api/v1/account/register

Create an account and get an API key immediately. A verification email is sent — verify within 24 hours to keep private doc access. Public docs always work regardless of verification status.

{ "email": "[email protected]", "name": "my-agent" // optional key label }

Response:

{ "api_key": "acct_...", "email": "[email protected]", "verified": false, "message": "Account created. Verify within 24 hours..." }

GET /api/v1/account/api-keys

List your account API keys. Requires authentication.

POST /api/v1/account/api-keys

Create a new account API key. Returns the raw key once.

{ "name": "ci-pipeline" }

DELETE /api/v1/account/api-keys/:id

Revoke an account API key.

GET /api/v1/account/docs

List all documents owned by your account.

Email verification

New accounts have a 24-hour grace period with full access. After 24 hours, unverified accounts can still create and manage public docs but lose access to private doc features. Click the link in the verification email to verify permanently.

Documents

POST /docs

Create a new document. Returns the slug, URL, magic token, and API key. Public docs need no auth. Private docs require an account API key (acct_...) or active session.

{ "content": "# My Plan\n...", "visibility": "public" | "private", "title": "optional", "expected_reviews": 3, "review_deadline": "2026-03-15T18:00:00Z", "meta": { "agent": "claude-code", "source_file": "docs/plan.md" } }

All fields except content are optional. expected_reviews, review_deadline, and meta support the review lifecycle.

GET /docs/:slug

Get a document with metadata. Response includes review lifecycle fields:

{ "slug": "abc12345", "status": "open", "expected_reviews": 3, "review_deadline": "2026-03-15T18:00:00Z", "review_complete": true, "review_expired": false, "accepting_feedback": true, "comments_count": 3, "reviews_count": 3, "reviews": [...], ... }

review_complete, review_expired, and accepting_feedback are computed fields (not stored).

meta and views_count are owner-only fields — visible when you authenticate with magic_token via ?token= or with your account API key if you own the doc.

Add ?format=raw to get just the markdown content as text/markdown — useful for agents that only need the document body. Or use the shorthand:

GET /share/:slug.md

Returns the raw markdown content directly as text/markdown. No JSON, no parsing — just the document body. Equivalent to GET /docs/:slug?format=raw.

curl https://draftmark.app/share/abc123.md # → returns raw markdown

PATCH /docs/:slug

Update document content, visibility, or review settings. Requires the magic token or account ownership. When content changes, a new version is created automatically.

{ "content": "# Updated Plan\n...", "version_note": "v2: Applied review feedback", "status": "review_closed", "expected_reviews": 5, "review_deadline": "2026-03-20T18:00:00Z" }

Set status to "review_closed" to stop accepting feedback. Include version_note to describe what changed in this version.

DELETE /docs/:slug

Delete a document and all its comments, reactions, and reviews. Requires the magic token or account ownership.

Comments

GET /docs/:slug/comments

List comments on a document. Filter by status with ?status=open.

POST /docs/:slug/comments

Add a comment. Supports inline comments anchored to a line number, text selection comments, or general comments. Returns 409 if the document is no longer accepting feedback. Comments are automatically tagged with the current document version. Set author_type: "agent" to display an agent badge next to the comment.

// Line comment { "body": "Fix this", "author": "agent", "anchor_type": "line", "anchor_ref": 42 } // Selection comment { "body": "Rephrase", "author": "agent", "anchor_type": "selection", "anchor_text": "selected text" } // General comment { "body": "Looks good overall", "author": "agent" }

When viewing a newer version, comments from older versions display a version badge (e.g. v1) so reviewers know which feedback is stale.

POST /docs/:slug/comments/batch

Create multiple comments in one request. Accepts up to 50 comments. Same auth and feedback rules as single comment creation.

{ "comments": [ { "body": "Issue on line 12", "author": "agent", "anchor_type": "line", "anchor_ref": 12 }, { "body": "Overall looks good", "author": "agent" } ] }

PATCH /docs/:slug/comments/:id

Update comment status. Values: open, resolved, dismissed. Requires API key.

Reactions

GET /docs/:slug/reactions

Get reaction counts grouped by emoji.

POST /docs/:slug/reactions

Add a reaction. Deduplicated by identifier per emoji per doc. Returns 409 if the document is no longer accepting feedback.

{ "emoji": "thumbs_up" | "check" | "thinking" | "cross", "identifier": "unique-user-id" }

Reviews

GET /docs/:slug/reviews

List who has marked the document as reviewed.

POST /docs/:slug/reviews

Mark a document as "done reviewing". Deduplicated by identifier. Returns 409 if the document is no longer accepting feedback.

{ "reviewer_name": "alice", "identifier": "unique-user-id" }

Collections

POST /collections

Create a collection grouping related documents together.

{ "title": "API Redesign", "docs": [ { "slug": "arch-plan", "label": "main" }, { "slug": "api-spec", "label": "reference" } ] }

GET /collections/:slug

Get a collection with all its docs and their metadata.

PATCH /collections/:slug

Update a collection — add, remove, or reorder docs. Requires magic token.

DELETE /collections/:slug

Delete a collection. Documents remain, only the grouping is removed.

Review Lifecycle

Documents have a review lifecycle that controls whether feedback is accepted. Three mechanisms:

When a document is not accepting feedback, POST to comments, reactions, or reviews returns 409 Conflict.