---
title: "Edit Mode API"
description: "Draft management endpoints for the web editing surface: open, read, save, and discard draft documents. Used by the web portal and Chrome Extension."
url: "https://comstack.ai/docs/api/editing/"
---
## 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

| Field | Type | Required | Description |
|---|---|---|---|
| `slug` | string | Yes | URL slug of the page to open. |
| `language` | string | Yes | BCP-47 language code. |

**Response:**

| Field | Description |
|---|---|
| `draftId` | Firestore doc ID of the draft. |
| `doc` | Document — `metadata`, `content`, `doc_template_id`, `language`. |
| `template` | Full template document — used to render metadata form fields. |
| `action` | `"existing_draft"` or `"cloned_from_live"`. |

### POST /edit/save

| Field | Type | Required | Description |
|---|---|---|---|
| `draftId` | string | Yes | Draft ID. Use `"new"` to create a brand-new draft. |
| `metadata` | object | Yes | Merged with existing — fields not sent are preserved. |
| `content` | string | Yes | Full markdown body. |
| `language` | string | Yes | BCP-47 language code. |
| `doc_template_id` | string | Only for `"new"` | Template ID. Cannot be changed after creation. |

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

### POST /edit/discard

| Field | Type | Required | Description |
|---|---|---|---|
| `draftId` | string | Yes | Draft 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:

```bash
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:

```bash
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 fields** — `slug` 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.

## Related

- [Publish API](/docs/api/publish.md) — how drafts are promoted to live
- [API overview](/docs/api.md) — full endpoint index
- [Authentication](/docs/api/authentication.md) — Firebase token and role requirements
