# Errors and limits

## Error responses

API errors normally return JSON with an `error` code and, when available, a
`description`. Some validation responses contain only the error code.
Check the HTTP status before decoding a response; upstream failures may
return a different body format.

```json
{
  "error": "revision_conflict",
  "description": "The sheet changed; reload before saving"
}
```

| HTTP status | Meaning | What to do |
| --- | --- | --- |
| 400 | Invalid JSON, query, range, workbook, or cell edit. | Correct the request using the description, when present. |
| 401 `invalid_token` | Missing, expired, revoked, or otherwise invalid credential. | Reconnect with a valid personal API token or OAuth access token. |
| 403 `insufficient_scope` | Token lacks the endpoint's scope. | Create a token with the required scope. |
| 403 | Account lacks permission for the operation. | Check the account's workbook role and verification status. |
| 404 `not_found` | Workbook is missing or inaccessible to this account. | List accessible spreadsheets again and check the `pid`. |
| 409 `revision_conflict` | Workbook changed since the read. | Reread and recompute the write against the new revision. |
| 413 | JSON request body exceeds the size limit. | Reduce the request size. |
| 415 | Missing or unsupported content type. | Send `Content-Type: application/json`. |
| 422 | Wrong types, missing required fields, or unknown request fields. | Match the endpoint's request schema. |
| 429 `rate_limited` | Credential exceeded its request rate. | Wait for the `Retry-After` duration in seconds. |
| 5xx | Server could not complete or confirm the operation. | Read the current state before retrying a write. |

## Revision conflicts and retries

Every cell write and complete save requires `expected_revision`. The API
compares it with the current workbook revision and rejects stale writes.
This check also applies when another client edits a different worksheet
inside the same workbook.

On an explicit **409 `revision_conflict`**, the proposed write was rejected.
Read again, reconsider the intended changes, and retry with the new revision.
For example, an append must find the next available row again; changing only
the revision could overwrite another client's new row. Use a bounded retry
count so a busy workbook cannot cause an endless loop.

After a timeout, lost connection, or server error, the write may already
have succeeded. Inspect the current data before retrying. These endpoints
do not provide an idempotency-key contract or an exactly-once append
guarantee. For event ingestion, storing a source event ID in a column can
help you identify duplicates.

## Rate limits

Production allows **600 read requests and 300 write requests per minute per
credential**. Creation counts as a write. On HTTP 429, honor the
`Retry-After` header. After waiting to retry a write, read the current
revision again.

## Data limits

| Limit | Value |
| --- | --- |
| JSON request body | 2 MiB, including the request envelope. |
| Workbook structure and snapshot-based cell operations | Canonical `visigrid-json` version 2; workbook validation is bounded to 4 MiB. |
| Worksheet tabs in a validated v2 workbook | 1–256, with distinct names ignoring case. |
| Range read | At most 5,000 cell positions in the requested rectangle, including empty positions. |
| Cell write | 1–1,000 edits per request, each to a distinct cell. |
| Literal string | At most 32,767 bytes. |
| Formula | Must start with `=` and contain an expression; at most 8,192 bytes. |
| Cell coordinates | Rows 1–1,048,576 and columns A–XFD (16,384 columns). |
| Spreadsheet name on creation | 1–255 characters after trimming. |

The full snapshot endpoint returns the stored JSON document; create and save
accept JSON objects and are subject to the 2 MiB request limit. Successfully
storing a document does not guarantee that the bounded workbook or cell
operations support it. Use a canonical v2 document for interoperability.

Cell writes can reject workbook features that cannot be safely recalculated,
including spilled arrays and stale custom-function values. Do not remove
workbook metadata to work around a rejection.