---
title: "Change a diagram (make the next revision)"
method: POST
path: "/v1/diagrams/{id}/revisions"
tags: ["Diagrams"]
---

# Change a diagram (make the next revision)

`POST /v1/diagrams/{id}/revisions`

## Request

- Base URL: `https://api.zindex.ai`
- URL: `https://api.zindex.ai/v1/diagrams/{id}/revisions`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Applies an edit and keeps the old version: every change appends a revision and nothing is overwritten. Give exactly one of ops, mermaid, restoreRevision, or brief alone (brief may also accompany ops or mermaid). An edit that changes nothing returns noop: true. A retry with the same requestId returns the first result (replayed: true). A stale baseRevision returns 409 with the current revision and what changed, unless the current content already equals what the edit asked for (then noop).

## Path parameters

- `id` string, required

## Headers

- `X-Zindex-Client` string

## Request body

- object
  - `baseRevision` integer, required: The revision you last read
  - `message` string: One line on what the edit does and why
  - `requestId` string: Your ID for this edit, e.g. a UUID
  - `ops` Operation[]: Up to 500 operations; more is a 400, INVALID_REQUEST. An edit that would leave the diagram with more than 1,000 elements is refused with VALIDATION_FAILED before it runs.
    - `op` 'createNode' | 'updateNode' | 'deleteElement' | 'createEdge' | 'updateEdge' | 'groupElements' | 'ungroupElements' | 'createFrame' | 'moveElement' | 'resizeElement' | 'setStyle' | 'setText' | 'addConstraint' | 'removeConstraint' | 'autoLayout' | 'updateScene' | 'restoreRevision', required: Operation type
    - `id` string: Target element ID (for most operations)
  - `mermaid` string: The whole diagram as Mermaid, usually read with view=mermaid and edited. The server diffs it against baseRevision into operations: nodes and edges are matched by ID, so unchanged elements keep their IDs and history, and nodes and edges left out are deleted. Frames, groups and text are never changed by a Mermaid edit; an edge to a subgraph that shows a frame or group is an edge to that frame or group. Works on architecture and entity-relationship diagrams; not with ops or restoreRevision.
  - `restoreRevision` union: Bring back an earlier version as a new revision
    - integer
    - object
      - `asOf` string, required
  - `brief` string, nullable: Replace the brief; null removes it

## Response `200`

The write envelope

- DiagramWrite: The write envelope a create and an edit return, kept under 100 tokens.
  - `id` string, required: The diagram ID, e.g. dgm_7Q2kD9a1B2c3
  - `key` string, nullable
  - `revision` integer, required
  - `hash` string, required: sha256: of the RFC 8785 canonical content: the scene as view=dsp and the export return it, without `computed`, the engine's drawing output. The node positions in each node's `layout` are content, so they count.
  - `chain` string, nullable, required: The version's chain hash: sha256: of "zindex-chain/1\n" + the previous kept version's chain hash (empty for the first kept version) + "\n" + this version's content hash + "\n" + its stored image's hash, each as lowercase hex without sha256:. It covers every kept version up to this one. null until Zindex has computed it, normally when the version is saved; a render, an export or the next edit computes a missing one. Reads and the history never compute it. https://zindex.ai/docs/concepts/#verifying
  - `changed` object: The elements the edit added, updated or removed, including nodes a grown node pushed and members a moved frame carried: at most 20 IDs in all, and more counts the rest.
    - `added` string[]
    - `updated` string[]
    - `removed` string[]
    - `more` integer: How many changed IDs were left out of the lists
  - `warnings` DiagramWarning[], required
    - `code` string, required
    - `element` string: The element it concerns, when there is one
    - `fix` string, required: One line on what to change
  - `created` boolean: false when a create with the same key and content returned the existing diagram
  - `noop` boolean: The edit changed nothing; revision is the current one
  - `replayed` boolean: The requestId matched an earlier edit; this is its result

## Other responses

- `400`: INVALID_REQUEST: e.g. nothing to change, or more than 500 ops
- `401`: Missing or invalid API key. Response includes a `code` field that distinguishes the failure mode so clients (dashboard, MCP server) can render actionable copy: `AUTH_REQUIRED` (no key or session was sent), `API_KEY_INVALID` (key not found), `API_KEY_REVOKED` (key was revoked, or its person is no longer in its workspace), `API_KEY_EXPIRED` (key passed its expires_at), and for the site's session cookie `SESSION_EXPIRED` (past its 24 hours), `SESSION_REVOKED` (the account's sessions were ended, for example by a password reset) and `SESSION_INVALID` (not a session this server signed).
- `403`: LIMIT_REACHED, for an edit that would make a revision (a replayed retry or a no-op is answered as usual), EMAIL_NOT_VERIFIED or READ_ONLY
- `404`: NOT_FOUND or NO_REVISION_AS_OF
- `409`: REVISION_CONFLICT: revision is the current one; changes lists what changed since baseRevision
- `413`: INPUT_TOO_LARGE: Mermaid text over 64 KB
- `422`: VALIDATION_FAILED: nothing was saved, and errors lists why: an operation that can't apply (such as moveElement on an edge), a name no operation creates, or a version with an error its base revision didn't have. REQUEST_ID_REUSED: the requestId belongs to a different edit. For Mermaid: PARSE_ERROR (with line and column), UNSUPPORTED_DIAGRAM_TYPE, IMPORT_TIMEOUT, IMPORT_FAILED or MERMAID_FAMILY_MISMATCH. DRAW_TIMEOUT: drawing the scene took longer than the drawing budget (20 s), or needed more memory than it allows; nothing was saved
- `429`: RATE_LIMITED: over the request rate limit (see Rate Limiting). Wait retryAfter seconds (also the Retry-After header), then try again.
- `503`: BUSY: every drawing worker is busy and the queue is full. Wait retryAfter seconds (also the Retry-After header): half the budget of the drawing refused. Then try again.

---

[API](https://skmtc.dev/zindex/apis/zindex-api.md) · [All operations](https://skmtc.dev/zindex/apis/zindex-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zindex/apis/zindex-api/revisions/1d21bd5bbf8e?raw)
