Errors
Every error the Evinor API returns is an RFC 9457
"problem detail" document. Branch on the stable type URI or the HTTP status
code — never on the human-readable title or detail, which may change.
Anatomy
Error responses use the application/problem+json content type and this shape:
{
"type": "https://docs.evinor.ai/problems/validation-failed",
"title": "Validation failed",
"status": 400,
"detail": "The request payload failed validation.",
"request_id": "8f0b2c1e-4a7d-4b93-9c2e-1d5a6f0b3c8e",
"errors": [{ "field": "filter.min_reports", "message": "Expected integer" }]
}
| Member | Always present | Meaning |
|---|---|---|
type | yes | Stable, versioned problem-type URI under https://docs.evinor.ai/problems/. Branch on this. |
title | yes | Short, constant, human-readable summary for the type. Not request-specific. |
status | yes | The HTTP status code, repeated in the body. |
detail | usually | Human-readable explanation of this specific occurrence. |
request_id | yes | Correlation id for this request. Include it when contacting support. |
Some problem types add extension members:
validation-failedincludes anerrorsarray of{ field, message }objects, one per failed field.missing-scopeincludes amissing_scopesarray naming the scope(s) the key lacks.
request_id
Every response — success or error — carries an x-request-id header, and every
error body repeats it as request_id. Log it. When you report a problem to
Evinor support, quoting the request_id lets us find the exact request in our
logs.
You may also send your own x-request-id on a request (up to 64 characters of
A-Za-z0-9_-) and Evinor will echo it back, so you can correlate a call with
your own tracing. Any value outside that charset/length is ignored and a fresh
id is generated instead.
Problem-type catalog
Each type URI resolves to a page on this site describing the problem and how
to handle it:
| Status | Problem type | When it happens |
|---|---|---|
| 400 | validation-failed | The request payload, query, or path failed validation. |
| 401 | invalid-api-key | The API key is missing, malformed, unknown, or revoked. |
| 403 | missing-scope | The key lacks a scope the endpoint requires. |
| 404 | not-found | The referenced resource doesn't exist or isn't yours. |
| 409 | idempotency-in-flight | Another request with the same Idempotency-Key is running. |
| 422 | idempotency-key-conflict | An Idempotency-Key was reused for a different request. |
| 429 | rate-limited | The per-key rate limit was exceeded. |
| 502 | upstream-error | An upstream dependency returned an unexpected error. |
| 503 | write-unavailable | A write could not be accepted right now; safe to retry. |
| 500 | internal-error | An unexpected server error. Not your fault; retry or report. |
Handling errors
- 4xx generally means something about the request must change — fix the input, the key, or the scope before retrying.
- 429 and 503 are safe to retry after a backoff; both include a
Retry-Afterheader telling you how long to wait. - 502 and 500 indicate a server-side issue; retry with backoff and, if
it persists, contact support with the
request_id.