API
Errors
When a request fails, the EvoHub API answers with an HTTP status code and a JSON body that says what went wrong in a form your code can act on. This page explains the format and the codes you are most likely to meet.
The error format
Every error body has an error object:
{
"error": {
"code": "FORBIDDEN",
"message": "insufficient permissions",
"request_id": "req_4f1c2a9e7b3d5a6c8e0f1a2b"
}
}
| Field | Meaning |
|---|---|
code |
A stable, machine-readable code in capitals. Branch on this. |
message |
A human-readable explanation. Show or log it, but do not parse it; the wording can change. |
request_id |
The ID of this request. Present on most errors; the same value is always in the X-Request-ID response header. |
Validation errors can add a details array that names each field that failed:
{
"error": {
"code": "VALIDATION_FAILED",
"message": "request validation failed",
"details": [
{ "field": "email", "message": "email is required" }
]
}
}
Status codes
| Status | Meaning | What to do |
|---|---|---|
| 400 Bad Request | The request is malformed or a field is invalid. | Fix the request. Read message and details. |
| 401 Unauthorized | No credentials, or the credentials are not valid: the API key is missing, unknown, revoked or expired. | Check the key and the header. Retrying the same request will not help. |
| 403 Forbidden | You are authenticated, but not allowed to do this. | Give the key the scope it needs, or use a person's account where a person is required. |
| 404 Not Found | The resource does not exist, or you are not allowed to know it exists. | Check the ID and which organization or team the key belongs to. |
| 409 Conflict | The request conflicts with the current state, for example a name already taken or a limit reached. | Change the request; it will not succeed as is. |
| 429 Too Many Requests | You went over the rate limit. | Wait for the Retry-After seconds, then retry with backoff. |
| 500 Internal Server Error | Something went wrong on EvoHub's side. | Retry later. If it persists, contact support with the request ID. |
| 503 Service Unavailable | EvoHub could not complete the request right now. | Retry shortly with backoff. |
401 versus 403
EvoHub keeps these two strictly apart:
- 401 always means "we do not know who you are". The credential is missing or not valid.
- 403 always means "we know who you are, and you may not do this". A missing scope, an action reserved for administrators, or an action that only a person may take all return 403, never 401.
So a 401 is a credential problem, and a 403 is a permission problem. Rotating a key will not fix a 403; changing its scopes or role will.
Note
A resource that belongs to a team the key cannot see answers 404, not 403. Saying "forbidden" would confirm that something with that ID exists.
Common error codes
| Code | Status | Meaning |
|---|---|---|
UNAUTHORIZED |
401 | No valid credential was sent, or the API key is invalid or expired. The message says which header to send. |
FORBIDDEN |
403 | The key or person lacks the permission this endpoint needs. Also returned when you try to give a key or role a permission you do not hold. |
ADMIN_ONLY |
403 | Only an administrator can do this, for example giving a key the Admin role. |
PERSON_REQUIRED |
403 | This action (such as approving a change request) must be done by a person signed in to EvoHub, not with an API key. |
API_KEY_NOT_ALLOWED |
403 | This endpoint is for a signed-in person acting on their own account, such as managing sessions or two-factor authentication. |
NOT_A_PERSON |
403 | An organization key tried to do something that must name a person, such as sending an invitation. Use a personal key. |
VALIDATION_ERROR |
400 | A field is missing or invalid. The message names it. |
VALIDATION_FAILED |
400 | One or more fields are invalid. Each is listed in details. |
INVALID_BODY |
400 | The request body is not valid JSON. |
UNKNOWN_PERMISSION |
400 | A scope or permission name is not one EvoHub knows. |
RATE_LIMITED |
429 | Too many requests. See Rate limits. |
AUTH_UNAVAILABLE |
503 | The key could not be checked right now. Your key is fine; retry shortly. |
INTERNAL_ERROR |
500 | An unexpected error on EvoHub's side. |
Not-found errors often name the resource, for example MONITOR_NOT_FOUND. Treat any 404 the same way, whatever its code.
Request IDs
Every response, successful or not, carries an X-Request-ID header, and most error bodies repeat it as request_id. Log it with every failed call. When you contact support at info@evosync.io, include the request ID and the time of the request; it lets us find that exact call.
You can also set your own X-Request-ID header on a request, for example your CI job's run ID, and EvoHub uses it instead of generating one.
Handling errors well
- Branch on
codeand the status, not onmessage. - Retry only 429, 500 and 503, with exponential backoff. Do not retry 400, 401, 403, 404 or 409 unchanged.
- On 401 from a key that used to work, check whether it was revoked or has expired in My Account → API Keys or Organization → Organization Keys.
Related
Was this page helpful?
