API Endpoints
The Zindex API is served at https://api.zindex.ai. It implements the Diagram Scene Protocol (DSP) - a structured format for creating, validating, and rendering diagrams.
Most endpoints require authentication via Authorization: Bearer <API_KEY> header. Public endpoints (validate, render, normalize) do not require authentication and are rate-limited at a stricter tier.
Building a custom agent integration over HTTP? Read How AI Agents Should Use Zindex for the recommended request sequence, state-management model, validation behavior, and retry strategy.
The full machine-readable API specification is available at /openapi.json (OpenAPI 3.1).
Scenes
Create scene
POST /v1/scenes
{
"schemaVersion": "0.1",
"scene": {
"id": "my-diagram",
"title": "Architecture",
"units": "px",
"canvas": { "width": 1200, "height": 800, "background": "#ffffff" }
},
"elements": []
}
To enable automatic positioning, add layoutStrategy to the scene document:
{
"schemaVersion": "0.1",
"layoutStrategy": {
"algorithm": "hierarchical",
"direction": "TB"
},
"scene": {
"id": "my-diagram",
"title": "Architecture",
"units": "px",
"canvas": { "width": 1200, "height": 800 }
},
"elements": [
{ "id": "api", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "API" },
{ "id": "db", "kind": "node", "nodeType": "database", "shape": "cylinder", "label": "DB" },
{ "id": "e1", "kind": "edge", "from": { "elementId": "api" }, "to": { "elementId": "db" } }
]
}
When layoutStrategy is present, nodes can omit layout and the engine computes positions from the graph structure.
Response: { "sceneId": "my-diagram", "revision": 1, "diagnostics": [] }
Scenes are validated automatically before persisting. If validation fails, the scene is rejected with a 422 response containing diagnostics. To skip validation during incremental assembly, pass "validate": false - but always re-enable validation before final render or handoff.
Get scene
GET /v1/scenes/:sceneId
GET /v1/scenes/:sceneId?revision=2
GET /v1/scenes/:sceneId?includeComputed=true
Returns the scene at the latest or specified revision.
Query parameters:
| Name | Type | Default | Description |
|---|---|---|---|
revision | integer | latest | Specific revision number to retrieve. |
includeComputed | boolean | false | If true, include the scene’s computed section (layout bounds, edge paths) in the response. Default false to save tokens - the computed data is regenerated on every render. |
Diff revisions
GET /v1/scenes/:sceneId/diff?from=1&to=3
Compare two revisions and return categorized changes (added, removed, modified elements). to is optional - defaults to the current revision.
Response: { "sceneId", "fromRevision", "toRevision", "summary": { "added", "removed", "modified" }, "added": [...], "removed": [...], "modified": [...], "changedConstraintIds": [...] }
Apply operations
POST /v1/scenes/:sceneId/applyOps
{
"schemaVersion": "0.1",
"sceneId": "my-diagram",
"baseRevision": 1,
"ops": [ ... ]
}
Response: { "sceneId": "...", "revision": 2, "applied": 3, "diagnostics": [] }
Operations are validated against the current scene state before applying. Returns 422 with diagnostics if validation fails. Pass "validate": false to skip. Returns 409 if baseRevision doesn’t match the current revision (conflict).
Render scene
POST /v1/scenes/:sceneId/render
{ "format": "svg" }
Formats: svg, png
Theme (optional): clean, dark, blueprint, sketch
Response:
- SVG:
{ "output": { "mimeType": "image/svg+xml", "content": "<svg>..." } } - PNG:
{ "output": { "mimeType": "image/png", "contentBase64": "..." } }
Soft-delete scene
DELETE /v1/scenes/:sceneId?confirm=true
Soft-deletes a scene. The scene becomes invisible to GET immediately and is recoverable for 24 hours via the undelete endpoint. After the 24-hour grace window a scheduled cron permanently removes the scene. Requires ?confirm=true (or {"confirm": true} in the body) to authorize the destructive call. Returns 204 No Content on success, 400 without confirmation, 404 for nonexistent or cross-workspace scenes.
Restore a soft-deleted scene
POST /v1/scenes/:sceneId/undelete
Restores a scene that was soft-deleted within the past 24 hours. Returns 200 with the restored sceneId + current revision. Returns 409 if the scene was hard-deleted by the cron or never existed.
List recently-deleted scenes
GET /v1/scenes/_recently-deleted
Returns the caller’s scenes soft-deleted within the past 24 hours that have not been restored or hard-deleted. Powers the /dashboard/recently-deleted recovery surface.
Account (deletion flow)
Session-authenticated endpoints for account deletion. The destructive nature of these endpoints (cancel Stripe subscription, revoke all API keys, permanently close the account) precludes API-key auth. The workspace is derived from the signed-in user; no :id is carried in the URL.
Pre-flight check
GET /v1/account/deletion-preflight
Returns what will happen if the caller closes their account: subscription state, refund policy (no automatic refund), hard-delete ETA. Enterprise accounts return isEnterprise: true and are blocked from self-service deletion (contact support@zindex.ai).
Request deletion (send email)
POST /v1/account/deletion-request
Body: { "confirmedName": "<exact workspace name>" }. Generates a 256-bit random token (only its SHA-256 hash is stored), captures the requester IP and user-agent for the email body, and sends a confirmation email via the registered address. Token expires in 24 hours. Returns 202 on success; the email recipient must click the link to complete deletion.
Confirm deletion
POST /v1/account/deletion-confirm
Token-authenticated (no session cookie). Body: { "token": "<plaintext-from-email>" }. Cancels the Stripe subscription, deletes the Stripe customer record, and removes all account data atomically (workspace, scenes, API keys, and PII rows in audit / analytics tables). Primary-database removal is immediate on confirm; backup snapshots age out within 30 days. Returns 200 on success, 410 for invalid or expired tokens.
Public endpoints (no auth required)
These stateless endpoints require no API key. They are rate-limited at 30 requests/minute per IP.
Validate scene
POST /v1/scenes/validate
Accepts a full scene document. Returns validation diagnostics without persisting.
{ "valid": true, "diagnostics": [] }
Render scene (stateless)
POST /v1/scenes/render
Renders an inline scene without persisting it.
{
"scene": { "schemaVersion": "0.1", "scene": { ... }, "elements": [ ... ] },
"format": "svg"
}
Formats: svg, png
Theme (optional): clean, dark, blueprint, sketch
Response:
- SVG:
{ "output": { "mimeType": "image/svg+xml", "content": "<svg>..." } } - PNG:
{ "output": { "mimeType": "image/png", "contentBase64": "..." } }
Normalize scene (stateless)
POST /v1/scenes/normalize
Normalizes an inline scene (applies defaults, resolves layout) without persisting.
{
"schemaVersion": "0.1",
"scene": { ... },
"elements": [ ... ]
}
Response: { "scene": { ... }, "computed": { ... }, "diagnostics": [] }
Authentication
Create API key
POST /v1/auth/keys
{ "name": "Production API" }
Use a descriptive name to identify the key’s purpose. Good examples:
Production API- for your deployed serviceClaude Desktop- for MCP agent accessCI/CD Pipeline- for automated testingLocal Development- for local testing
Response: { "id": "...", "key": "dsp_sk_...", "name": "Production API" }
The key is shown only once in the response. Store it securely.
Health
Health check
GET /health
No authentication required. Returns { "status": "ok" }.