Limits
Each workspace is on one plan. A personal workspace is on Free or Pro, and a team workspace on Free or Team (Workspaces). The pricing page shows all three. Team is a beta, open to every account and billed from the start; its features may change during the beta. This page lists the limits and what happens at each.
Plans
| Free | Pro | Team | |
|---|---|---|---|
| Price | $0 | $5 a month or $48 a year | $8 a month or $80 a year per paid seat |
Diagrams (scenes) | 25 | Unlimited, under fair use | Unlimited, under fair use |
Diagram updates a month (updatesPerMonth) | 2,500 | 25,000 | 25,000 per paid seat |
Renders a month (rendersPerMonth) | 5,000 | 50,000 | 50,000 per paid seat |
API keys (apiKeys) | 3 | 10 | 10 per paid seat |
| Private share links | No | Yes | Yes |
Every plan keeps every version of every diagram. A free account unused for 12 months is deleted with its diagrams, after emails 30 and 7 days before the deletion date; Pro accounts and people in a paying team are never deleted for being unused (Privacy). Every plan works from every client (MCP and REST), and can download any version, a diagram’s whole history, or every diagram in the workspace in one file. Every plan’s images print the same line in the bottom-right corner, the version’s address and date, with no setting to remove it. A workspace owner changes the plan signed in, at zindex.ai/settings/billing; there is no API for it. The dashboard shows the workspace’s usage against each limit.
Team’s pooled limits
Each owner and member of a team workspace is a paid seat, with at least 2 seats per workspace. Viewers are free, and so are agents: every key and connected app acts as its person. Team’s limits are the table’s numbers times the paid seats, and everyone in the workspace, with every agent they connect, draws on the same counts, so one busy agent can use up the month’s updates or renders for everyone. A viewer’s keys don’t count toward apiKeys; a viewer can hold 3 keys in a workspace. A team workspace without a subscription has Free’s limits.
What counts
| Limit | Endpoint | Resets |
|---|---|---|
scenes | POST /v1/diagrams, diagram_create, and restoring a deleted diagram (POST /v1/diagrams/{id}/undelete, diagram_delete with undo) | When you delete a diagram |
updatesPerMonth | POST /v1/diagrams, POST /v1/diagrams/{id}/revisions, diagram_create and diagram_edit | Start of the next calendar month (UTC) |
rendersPerMonth | GET /v1/diagrams/{id}/render and diagram_render | Start of the next calendar month (UTC) |
apiKeys | POST /v1/auth/keys | When you revoke a key |
- Every saved version counts toward
updatesPerMonth, however it was made, including a new diagram’s first version, so at the limit a create is refused as an edit is. Restoring a deleted diagram makes no version and doesn’t count. An edit that changes nothing, and a retry that replays an earlier result, make no version, don’t count and aren’t refused at the limit. - Each render of a saved diagram,
GET /v1/diagrams/{id}/renderordiagram_renderwith anid, counts towardrendersPerMonth. Unsaved previews, image downloads and opening an image link never count. - Retrying your own create with the same
keyand content returns the existing diagram, isn’t counted again and isn’t refused at a limit. - Reads and the endpoints that need no key don’t count toward any plan limit.
- An expired or revoked API key frees its slot. Signing in an MCP client uses none.
- A diagram moved into a team workspace counts toward the team’s
scenes, and its versions saved this month count toward the team’supdatesPerMonthinstead of your personal workspace’s. The move itself makes no version. - A workspace that leaves Pro or Team with 25 or more diagrams keeps and can edit every one, but can’t create or restore another until it has fewer than 25.
At a limit
The call that would go over a limit on diagrams, updates or renders is refused: over REST with 403 Forbidden, over MCP with a tool error carrying the same fields:
{
"error": "This workspace's limit is 25 diagrams; it has 25.",
"code": "LIMIT_REACHED",
"limit": "scenes",
"maximum": 25,
"current": 25
}
limit names the limit, and maximum and current give the numbers. Creating an API key past the apiKeys limit returns code: "PLAN_LIMIT_EXCEEDED" instead, with limit, current, maximumAllowed and the same kind of error. Don’t retry either: the limit holds until something is deleted or revoked, the month rolls over or the plan changes. On Pro and Team they are fair-use limits.
Paid-plan features
Creating a share link (POST /v1/diagrams/{id}/links, or diagram_share with action: "link") needs Pro or Team. On Free it is refused, with 403 Forbidden over REST:
{
"error": "Private share links aren't available for this workspace.",
"code": "FEATURE_UNAVAILABLE",
"feature": "privateShareLinks"
}
Over MCP, diagram_share returns this before asking the person to confirm. Don’t retry it. Listing and revoking share links work on every plan, and links made on a paid plan keep working after the workspace moves to Free, until they are revoked. Publishing a diagram works on every plan (Version links).
Rate limits
Every endpoint except GET /health is rate-limited over a sliding one-minute window.
| Caller | Requests per minute | Counted per |
|---|---|---|
| Signed in: an API key, MCP sign-in or the dashboard | 60 on Free, 120 on Pro and Team, plus a burst of 10 | Person, in each workspace. All of a person’s keys and sign-ins in one workspace share one limit, by that workspace’s plan |
| No key | 30, plus a burst of 10 | IP address |
| No key, from Claude’s, ChatGPT’s or Cloudflare Workers’ published addresses | 600 | IP address |
The IP address is the one the request came from. X-Forwarded-For is ignored, so a server that calls Zindex for its users without a key has one no-key limit for all of them; with an API key it has the key’s person’s limit in the key’s workspace. An IPv6 address counts by its /64.
Claude (claude.ai, the Claude apps and the API’s MCP connector) and ChatGPT call the MCP server from their own servers for all of their users, so addresses in their published ranges (Anthropic, OpenAI) have the higher limit. Within it, each ChatGPT user is also held to the no-key limit, counted by the anonymized user ID ChatGPT sends with each MCP tool call. Claude sends no such ID, so its users share their address’s limit until they sign in. A Cloudflare Worker in another Cloudflare account calls from one address that all such Workers share, which has the same higher limit. Clients that connect from your machine (Claude Code, Cursor, VS Code, or @zindexai/mcp in any app) call from your own address.
POST /v1/diagrams/validateandPOST /v1/diagrams/previewalways count as calls without a key, even when a key is sent.- Validation and unsaved previews without a key (those two endpoints, and
diagram_validateanddiagram_renderwithsceneormermaidbefore sign-in) also count toward a ceiling that every caller without a key shares. Past it, they answer429until it frees up. The two endpoints count toward it even when a key is sent; signed-in MCP calls don’t. - Over MCP, each message of a JSON-RPC batch counts as one request.
- The MCP sign-in endpoints (
/authorize,/token,/register,/revokeand/.well-known/oauth-*) allow 600 requests a minute per IP address./registeralso caps how many clients one address can register in an hour, far higher for Claude’s, ChatGPT’s and Cloudflare Workers’ published addresses, and past that answers429with an OAuth error body (erroranderror_description). - Sending feedback has its own limit: 20 items in any 24 hours per account. Past it,
POST /v1/feedbackanddiagram_share’sfeedbackaction answer withcode: "RATE_LIMITED", anerrorthat says when the next item can go, andretryAfterin seconds.
Over a limit, the API answers 429 Too Many Requests with { "error": "Rate limit exceeded", "code": "RATE_LIMITED", "retryAfter": 12 } and a Retry-After header, both in seconds. /mcp answers with the same status and header, and a JSON-RPC error whose data is { "code": "RATE_LIMITED", "retryAfter": 12 }. Wait that long, then try again. Responses carry X-RateLimit-Remaining, the requests left in the current window, and a 429 from these limits also carries X-RateLimit-Reset, the Unix time in seconds when the request would fit again. The feedback limit’s 429 carries Retry-After alone.
Drawing time
Laying out and drawing a scene has a budget per drawing:
| Drawing | Budget |
|---|---|
Without a key or sign-in: checking or previewing an unsaved scene (POST /v1/diagrams/validate and /preview, diagram_validate, and diagram_render with scene or mermaid before sign-in), and a version’s image or PNG drawn for a version link or a signed image link | 5 seconds |
| Every other drawing: checks and previews with an API key, MCP sign-in or the dashboard, saves, edits, renders, and images and PNGs read with a key | 20 seconds |
Signing in, or sending an API key, gives a check or preview the larger budget, though POST /v1/diagrams/validate and /preview still count as calls without a key for the rate limits. A version’s SVG is kept when the version is saved, so reading it through a link draws it only if it wasn’t kept; a PNG, though, is made from the SVG on each read. Through a link, both have the 5-second budget, even when a key is sent. The element limit doesn’t guarantee a drawing fits: a large or dense diagram can take longer, such as a hub with hundreds of leaves.
- A save or an edit whose drawing runs past the budget is refused with
422andcode: "DRAW_TIMEOUT", and nothing is saved. Retrying won’t help; theerrorsays what to change: split the diagram, or draw fewer edges into one node. - A preview, an image or a render past its budget answers the same. The
errornames the budget that applied. - A drawing that needs more memory than a drawing worker has (128 MB by default) is refused with the same
DRAW_TIMEOUT, and anerrorthat says so. POST /v1/diagrams/validateanddiagram_validateanswer as usual, with aDRAW_TIMEOUTwarning instead of the drawing’s warnings. When a check without a key runs out of time, the warning says a save draws within 20 seconds. Otherwise a save has the same time, or the same memory when the check ran out of memory, and the warning says so and what to change.- When every drawing worker is busy and the queue is full, the call answers
503withcode: "BUSY",retryAfterand aRetry-Afterheader: half the budget of the drawing it refused, in seconds. Wait that long, then try again.
Sizes
Mermaid text, and a feedback snippet, can be up to 64 KB, a brief up to 1,000 characters, and an edit’s ops up to 500 operations. A request to /mcp can be up to 4 MiB; a larger one answers 413. The limits on a scene’s elements (1,000, edges included), nesting, text and canvas are under Size limits in Validation rules. They apply however a scene arrives, as JSON or Mermaid: a preview or an edit past them is refused with VALIDATION_FAILED, as a save is. The MCP tools and the OpenAPI spec give each input’s size.