Skip to Content
Developer APIAPI GuidesErrors

Errors

EUnifyer returns errors in the RFC 9457 Problem Details  format using Content-Type: application/problem+json.


Error shape

{ "type": "https://problems.eunifyer.com/forbidden", "title": "Forbidden", "status": 403, "detail": "Required scope: drive:read", "code": "forbidden", "instance": "/api/v1/drive/browse" }
FieldTypeDescription
typeURIStable machine-readable identifier for this error class
titlestringShort human-readable summary
statusintegerHTTP status code repeated in the body
detailstringSpecific explanation for this occurrence
codestringShorter machine-readable code (same as last path segment of type)
instancestringThe request path that produced this error

All fields except instance are always present. Additional fields may appear for specific error types.


HTTP status codes

StatusCodeWhen
400 Bad Requestvalidation_errorRequest body or query parameter fails validation
401 UnauthorizedunauthorizedMissing, expired, revoked, or malformed token
403 ForbiddenforbiddenToken is valid but lacks the required scope or permission
404 Not Foundnot_foundResource does not exist or is not visible to this token
409 ConflictconflictIdempotency key collision with a different request body
410 GonegoneEndpoint was deprecated and removed
412 Precondition Failedprecondition_failedIf-Match header did not match the current ETag
422 Unprocessable Entityunprocessable_entityBusiness logic violation (e.g. seat limit exceeded)
429 Too Many Requestsrate_limit_exceededRate limit hit — see Retry-After header
500 Internal Server Errorinternal_errorSomething went wrong on the server

Validation errors (400)

Validation errors include a errors extension listing field-level problems:

{ "type": "https://problems.eunifyer.com/validation_error", "title": "Validation Error", "status": 400, "detail": "Request body failed validation", "code": "validation_error", "errors": [ { "field": "name", "message": "field required" }, { "field": "scopes", "message": "value is not a valid list" } ] }

Rate limit errors (429)

{ "type": "https://problems.eunifyer.com/rate_limit_exceeded", "title": "Too Many Requests", "status": 429, "detail": "Rate limit exceeded", "code": "rate_limit_exceeded", "limit": 300, "reset_in_seconds": 42 }

The response also includes a Retry-After: 42 header. Wait that many seconds before retrying.

See Rate Limits for limits by plan.


Gone (410)

Removed endpoints return 410 with a successor field:

{ "type": "https://problems.eunifyer.com/gone", "title": "Gone", "status": 410, "detail": "This endpoint was removed on 2026-10-01. Use /api/v2/sites instead.", "code": "gone", "successor": "/api/v2/sites" }

Handling errors in code

async function apiFetch(path: string, token: string) { const resp = await fetch(`https://api.eunifyer.com/api/v1${path}`, { headers: { Authorization: `Bearer ${token}` }, }); if (!resp.ok) { const err = await resp.json(); if (resp.status === 429) { const retryAfter = parseInt(resp.headers.get("Retry-After") ?? "60"); throw new RateLimitError(err.detail, retryAfter); } throw new ApiError(err.code, err.detail, resp.status); } return resp.json(); }
import httpx def handle_response(r: httpx.Response) -> dict: if r.status_code == 429: retry_after = int(r.headers.get("Retry-After", "60")) raise RateLimitError(retry_after) if not r.is_success: err = r.json() raise ApiError(code=err["code"], detail=err["detail"], status=r.status_code) return r.json()

Correlation IDs

Every response includes X-Correlation-ID. Include this header value when contacting support — it ties your request to a specific trace in EUnifyer’s logs.