Error Handling
The Glance API uses standard HTTP status codes, and every failure carries a machine-readable code alongside a human message. Branch on the code, not on the message — the message is Hebrew and is written for a person to read.
Error Response Format
{
"success": false,
"error": {
"status": 404,
"code": "DOCUMENT_NOT_FOUND",
"message": "המסמך לא נמצא"
}
}Validation failures add an issues array — the Zod issues for the fields that failed:
{
"success": false,
"error": {
"status": 400,
"code": "INVALID_FIELD",
"message": "שדה לא תקין",
"issues": [
{
"path": [
"products",
0,
"price"
],
"message": "price must be zero or greater"
}
]
}
}One older shape. A few endpoints — the internal note, the execution status, and the identifier checks on document creation — answer with a bare
{ "error": { "code", "message", "issues" } } and no success key. Read error.code and you handle both shapes.HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
200 | OK | Request succeeded |
201 | Created | Resource created successfully |
400 | Bad Request | Invalid request body or parameters |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | API key lacks required permissions |
404 | Not Found | Resource does not exist |
409 | Conflict | Idempotency-key conflict, or a resource that already exists |
429 | Too Many Requests | Rate limit exceeded — see Rate Limits |
500 | Internal Server Error | Something went wrong on our end |
Common Error Codes
| Code | Status | When |
|---|---|---|
UNAUTHORIZED | 401 | Missing, unknown or expired API key. |
API_KEY_OWNER_INACTIVE | 401 | The user who created the key is no longer an active member of the company. A company owner has to create a new key. |
API_KEY_REQUIRED | 400 | GET /apiKeys/me was called without an API key (for example with a dashboard session). |
NO_ACCESS | 403 | The key is valid but cannot reach this company or this action. |
INVALID_FIELD | 400 | Validation failed — a body field (see `issues`), a non-numeric id, or a date that is not YYYY-MM-DD / ISO 8601. |
DOCUMENT_NOT_FOUND | 404 | No document with that visibleId, externalId or related id. |
DOCUMENT_CLOSED | 400 | The target document is already settled. |
INVALID_STATUS | 400 | The operation does not apply in the document's current state. |
CREDIT_LIMIT_EXCEEDED | 409 | POST /documents/create/{type}: the document would take the client past its credit limit and the company's policy is "block". `error.details` carries `creditLimit`, `totalObligation`, `documentEffect`, `excess` and `canOverride`; an owner-level key may resend with `creditLimitOverride: true`. |
CLIENT_OVERDUE_DEBT | 409 | POST /documents/create/{type}: the client has an open invoice more than `overdueBlockDays` past its due date and the company blocks on it. `error.details` carries `overdueBlockDays`, `overdueAmount`, `overdueDocuments`, `maxDaysOverdue` and `canOverride`; an owner-level key may resend with `creditLimitOverride: true`. |
DUPLICATE_EXPENSE | 409 | POST /expenses/create: the vendor already has an expense or supplier invoice with this `documentNumber`. Resend with `allowDuplicate: true` if it is intended. |
INSTALLMENTS_EXCEED_MAX | 400 | A card charge asks for more installments than the business allows — the body carries `maxInstallments`. |
INVALID_CLIENT_TYPE | 400 | Unknown `type` filter on GET /clients. |
INVALID_CLIENT_IDS | 400 | A `clientIds` token on GET /documents is not a positive integer. |
INVALID_DOCUMENT_TYPE | 400 | Unknown `type` filter — the response names `invalidTypes` and `supportedTypes`. |
INVALID_CURSOR | 400 | The change-feed cursor was not one we issued. |
INVALID_UPDATED_SINCE | 400 | `updatedSince` is not a valid ISO 8601 date. |
INVALID_EXTERNAL_ID | 400 | `externalId` is empty or longer than 64 characters. |
INVALID_IDEMPOTENCY_KEY | 400 | `Idempotency-Key` is not a string, or exceeds 255 characters. |
IDEMPOTENCY_KEY_REUSED | 409 | The same key was already used for a different request body. |
REQUEST_IN_PROGRESS | 409 | A request with this key is still being processed. |
RATE_LIMITED | 429 | Over the per-key limit — the body carries `retryAfter`. |
Tip: check
error.issues for field-level detail before retrying a 400 — the same body will fail again.Retrying a failed write. A 4xx or 5xx on document creation releases the
Idempotency-Key, so you may fix the body and retry with the same key. Never retry a create without one — see Idempotency.