Skip to content

Edit Mode API

What this is

Four HTTP endpoints for managing draft documents through a web editor: open a draft, read a specific draft, save changes, and discard. All require a Firebase ID Token with manager or admin role.

Route prefix: POST /api/projects/:projectId/docs/edit

How it works

Edit Mode is the web portal’s in-browser editing surface. Drafts are created from live pages (clone) or from scratch. Only documents with visibility: "draft" can be edited or discarded — live documents are cloned on open.

The workflow:

  1. open — find or create a draft for a given slug + language. Returns the draft ID and full document plus the resolved template (for rendering metadata form fields).
  2. save — persist changes. Called on explicit save and auto-save. Merges metadata (fields not sent are preserved). New draft: pass draftId: "new".
  3. discard — permanently delete the draft and its version subcollection.

When to use it

  • Building a web editing interface for ComStack documents
  • Resuming an in-progress edit session for a known draft ID
  • Auto-saving editor changes on a timer
  • Discarding a draft that should not be published

Parameters / fields / inputs

POST /edit/open

FieldTypeRequiredDescription
slugstringYesURL slug of the page to open.
languagestringYesBCP-47 language code.

Response:

FieldDescription
draftIdFirestore doc ID of the draft.
docDocument — metadata, content, doc_template_id, language.
templateFull template document — used to render metadata form fields.
action"existing_draft" or "cloned_from_live".

POST /edit/save

FieldTypeRequiredDescription
draftIdstringYesDraft ID. Use "new" to create a brand-new draft.
metadataobjectYesMerged with existing — fields not sent are preserved.
contentstringYesFull markdown body.
languagestringYesBCP-47 language code.
doc_template_idstringOnly for "new"Template ID. Cannot be changed after creation.

Response: { "success": true, "draftId": "abc123" }

POST /edit/discard

FieldTypeRequiredDescription
draftIdstringYesDraft ID to permanently delete.

Response: { "success": true, "draftId": "abc123" }

GET /edit/:draftId

Returns an existing draft by ID. Same response shape as open.

Example

Open a page for editing:

Terminal window
curl -X POST https://api.comstack.ai/api/projects/your-project-id/docs/edit/open \
-H "Authorization: Bearer <firebase-id-token>" \
-H "Content-Type: application/json" \
-d '{"slug": "guides/intro", "language": "en"}'

Save a change:

Terminal window
curl -X POST https://api.comstack.ai/api/projects/your-project-id/docs/edit/save \
-H "Authorization: Bearer <firebase-id-token>" \
-H "Content-Type: application/json" \
-d '{
"draftId": "abc123",
"metadata": {"title": "Updated Title"},
"content": "## Section\n\nBody text.",
"language": "en"
}'

Common errors

400 — non-draft document — attempting to save or discard a live document. Use open first to clone it to a draft.

400 — missing required fieldsslug and language required for open; draftId, metadata, content, language required for save.

401 Unauthorized — missing or expired Firebase ID Token.

403 Forbidden — caller doesn’t have manager or admin role on the project.

404 Not found — no live or draft exists for the given slug/language (for open), or the draft ID doesn’t exist.

Last updated: