Authentication

Most API requests need an API key. These don’t: POST /v1/diagrams/validate, POST /v1/diagrams/preview, GET /v1/public/diagrams/{id}, POST /v1/public/diagrams/{id}/report, and the signed image links that GET /v1/diagrams/{id}/render returns. The Diagrams API page lists every endpoint.

The MCP server at https://api.zindex.ai/mcp also signs people in with their Zindex account (OAuth 2.1), for clients such as claude.ai and ChatGPT that can’t send a key; Connect over HTTPS explains it. Those sign-in tokens work only on /mcp. Every REST endpoint takes an API key.

API key format

Keys are prefixed for identification: dsp_sk_<64-random-hex-chars>

The server stores only the SHA-256 hash of the key. The plaintext key is shown once on creation and cannot be retrieved again.

Sending your key

Include the key in the Authorization header:

Authorization: Bearer dsp_sk_abc123...

Diagram ownership

A diagram belongs to the user account that saved it. Any of that account’s API keys can read and edit the diagram, and so can the account’s signed-in dashboard session. You can rotate or add keys without losing access. Requesting a diagram owned by another account returns 404 NOT_FOUND, the same as a diagram that doesn’t exist.

Email verification

Until the account has verified its email, saving, editing, deleting, restoring, sharing and reporting a diagram return 403 Forbidden:

{ "error": "Verify this account's email address before saving diagrams: https://zindex.ai/verify-email", "code": "EMAIL_NOT_VERIFIED" }

Send the user to https://zindex.ai/verify-email to clear it. Reads, renders and the endpoints that need no key are never gated.

Creating API keys

Use the key management endpoint to create additional keys:

curl -s https://api.zindex.ai/v1/auth/keys \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Production Key" }'

The response includes the new key - store it securely, as it cannot be retrieved again.

Plan limits

Each workspace is on a plan (free, builder, growth, enterprise) that caps four resources: diagrams, monthly diagram updates, monthly renders, and API keys. The full numbers are on the pricing page. When the account reaches its cap on diagrams, updates or renders, the call that would go over it returns 403 Forbidden:

{
  "error": "This account's plan allows 50 diagrams; it has 50.",
  "code": "LIMIT_REACHED",
  "limit": "scenes",
  "maximum": 50,
  "current": 50
}

limit names the cap that was hit, and maximum and current give the numbers. Creating an API key past the apiKeys cap returns code: "PLAN_LIMIT_EXCEEDED" instead, with limit, current, maximumAllowed, plan and upgradeUrl, and an error that names the plan and the upgrade link.

Which endpoints enforce which cap:

CapEndpointResets
scenesPOST /v1/diagrams and diagram_createWhen you delete a diagram
updatesPerMonthPOST /v1/diagrams/{id}/revisions and diagram_editStart of the next calendar month
rendersPerMonthGET /v1/diagrams/{id}/render and diagram_renderStart of the next calendar month
apiKeysPOST /v1/auth/keysWhen you revoke an existing key

Every saved revision counts toward updatesPerMonth, however it was made. Each call to GET /v1/diagrams/{id}/render counts toward rendersPerMonth; diagram_render is refused once that cap is reached but doesn’t add to the count, and opening an image link never counts. Retrying a create with the same key returns the existing diagram and isn’t counted again. Read endpoints, the endpoints that need no key, and enterprise-plan workspaces are never gated. Don’t retry a LIMIT_REACHED or PLAN_LIMIT_EXCEEDED response. The cap holds until capacity is freed, the month rolls over or the workspace upgrades. The dashboard shows current usage against each cap, so users can see where they stand before they reach one.

Rate limiting

Every endpoint except GET /health is rate-limited over a sliding one-minute window.

CallerRequests per minuteCounted per
Signed in: an API key, MCP sign-in or the dashboard60 on the free plan, 120 on Builder, 600 on Growth and 6,000 on Enterprise, plus a burst of 10Account. All of its keys and sign-ins share one limit
No key30, plus a burst of 10IP address

POST /v1/diagrams/validate and POST /v1/diagrams/preview always count per IP address, at the no-key limit, even when a key is sent.

Over the limit, the API answers 429 Too Many Requests with { "error": "Rate limit exceeded", "retryAfter": 12 } and a Retry-After header, both in seconds. Wait that long, then try again.

Responses carry X-RateLimit-Remaining, the requests left in the current window. A 429 also carries X-RateLimit-Reset, the Unix time in seconds when the oldest request in the window drops out of it.