API reference
Errors
eupeak.io returns standard HTTP status codes and a consistent JSON error body. Every error can be resolved programmatically — there are no free-form error strings to parse.
Error body
{
"error": {
"code": "rate_limit_exceeded",
"message": "You have exceeded 100 requests per minute for this API key.",
"status": 429,
"retry_after": 42,
"request_id": "req_01HF2B8R7C3Z9QY1K8T5N4PMDG"
}
}- error.code
- Stable machine-readable identifier. Branch on this — never on the
messagetext. - error.message
- Human-readable explanation suitable for logging but not for display to end users.
- error.status
- Mirrors the HTTP status code for convenience.
- error.retry_after
- Present on
429and transient503responses. Seconds to wait before retrying. - error.request_id
- Always present. Include it when contacting support.
Status code reference
| Status | Code | When it fires |
|---|---|---|
400 | invalid_request | Request body malformed, missing required fields, or unknown option. |
401 | unauthenticated | Missing Authorization header, malformed header, or unknown API key. |
402 | quota_exceeded | The authenticated key has hit its monthly screening limit. Upgrade the plan or wait until reset_date (see GET /v1/usage). |
403 | forbidden | Key is revoked, account is suspended, or the request asks for a feature not available on the current tier (e.g. adverse media on Starter). |
404 | not_found | The requested screening ID or webhook ID does not exist for this account. |
422 | invalid_query | Query string is shorter than 2 characters, longer than 500, contains disallowed control characters, or the type field is not one of entity / person. |
429 | rate_limit_exceeded | More than 100 requests per minute on this key. Back off according to retry_after. |
500 | internal_error | Unexpected server error. Include request_id when reporting. |
502 | all_sources_failed | Every configured upstream source returned an error or timed out. eupeak.io does not return partial results silently — retry after a short delay. |
503 | degraded | Service temporarily unavailable (maintenance, deploy, upstream outage). Retry with exponential back-off. |
Retry guidance
- Retry on
429,502and503. Respect theretry_afterheader when present, otherwise use exponential back-off starting at 1 s with jitter. - Do not retry on
400,401,402,403,404, or422— these will fail again with the same input. - Treat every retry as a new billable screening only if the previous attempt returned a
2xxresponse. Non-2xx responses do not count toward your monthly quota.
Handling errors in TypeScript
async function screen(query: string) {
const res = await fetch('https://api.eupeak.io/v1/screen', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.EUPEAK_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ query, type: 'entity' }),
});
if (!res.ok) {
const { error } = await res.json();
switch (error.code) {
case 'rate_limit_exceeded':
await sleep(error.retry_after * 1000);
return screen(query); // safe to retry
case 'quota_exceeded':
throw new QuotaError(error.message);
default:
throw new EupeakError(error.code, error.request_id);
}
}
return res.json();
}Include the request_id when filing support tickets — it lets us jump straight to the exact request in our audit log.