API Reference
Error Codes
HTTP statuses you can expect from each endpoint, plus how to read error bodies.
There is no typed error envelope — match on the HTTP status.
Error responses are Spring defaults: { "timestamp": "...", "status": 400, "error": "Bad Request", "path": "..." }. The body carries no message or machine-readable code field — the human-readable reason surfaces in confiqure-side logs only. Pattern-match on the HTTP status, not the body. One exception carries a real body: the data API's 409 returns { "status": "migrating", "message": "…" }.
By endpoint
POST /api/{workspaceKey}/embed-tokens
| Status | When |
|---|---|
| 400 | Missing/over-length endUserHandle (max 255) or one starting with the reserved org- prefix; invalid organizationId; an openingContext violation (unknown/unowned referentKeys, over 16384 serialized chars, nested data values); or a configEnd field — no longer accepted since annotation 3.0 (an unknown openingContext.toolClass is ignored, never an error). |
| 401 | Missing or invalid Authorization header. |
POST /api/{workspaceKey}/upload
| Status | When |
|---|---|
| 400 | Manifest is missing or unparseable, or a referenced source file isn't in the multipart body. |
| 401 | Missing or invalid API key. |
| 413 | Upload exceeds the limits — 25 MB per source file, 30 MB per request. |
GET · POST /api/{workspaceKey}/endpoints/{configEnd}/data/…
| Status | When |
|---|---|
| 400 | A reserved org-* handle in the path (never accepted host-facing), or a malformed POST body. |
| 401 | Missing Bearer token, or an invalid API key. |
| 404 | No record for this endUserHandle (GET on a Setting object), no record with that confiqureKey (GET by key, or a keyed POST to an unknown key), or no live config at configEnd. |
| 405 | A PUT — the single POST route is the only write. |
| 409 | The record is held mid-migration — body {"status":"migrating"}. Retry shortly. |
| 409 | A write that would give a second record of a List object the same @Confiqure.Identity value — body {"code":"IDENTITY_CONFLICT","identityField":…,"existingKey":…} names the record that holds it. |
Field-level reasons are in the body, not the status code
A 200 response always deserializes: data holds typed values or null. Per-field problems are not HTTP errors — they ride along in the body as errors (a field that couldn't be populated) and warnings (soft / in progress), each a fieldName → reason map. Inspect them to decide whether to re-prompt the user; deserialization of data never fails on them.
GET /api/{workspaceKey}/upload/status/{id}
| Status | When |
|---|---|
| 401 | Missing or invalid API key. |
| 404 | No push history exists for this id in this workspace. |
Cross-cutting statuses
| Status | Meaning |
|---|---|
| 403 | The API key is valid but doesn't authorize the workspaceKey in the URL (a production key also covers its sb- sandbox; a sandbox key never covers production). Tenant isolation refusal. |
| 500 | Unhandled server error. The body carries no detail — contact support with the timestamp. |
| 503 | Temporarily unavailable. Retries with backoff are appropriate. |
Recommended client behavior
- Retry
409and503with exponential backoff. - Never retry
400or401— they are deterministic. - Treat
404on embed-tokens as "the developer hasn't pushed yet" — surface a helpful empty state instead of an error.