Errors
The API uses conventional HTTP status codes and returns a JSON body with the details you need to recover.
Error format
Most errors carry a detail field (string or object). Machine-actionable errors — rate limits, validation — add a stable error code to branch on:
{
"error": "rate_limit",
"limit": 20,
"period": "minute",
"retry_after": 42
}
Status codes
| Status | Meaning | Example body & what to do |
|---|---|---|
| 401 | Missing or invalid API key | {"detail": "API key required. Include x-api-key header."} — check the header name and that the key wasn't revoked. See Authentication. |
| 402 | Insufficient credits | {"detail": "Insufficient credits. Have 0, need 1. Purchase more at /billing."} — top up or upgrade on the billing page. Nothing was charged. |
| 404 | Resource not found | {"detail": {"error": "company_not_found", ...}} — the seed company passed to /api/v1/similar doesn't exist, or the domain passed to /companies/{domain}/details is unknown (free; not billed). Resolve names first via /api/v1/lookup. |
| 406 | Streaming not available | Structured search is batch-only — drop the Accept: text/event-stream header, or use NL mode (?q=) for SSE. |
| 422 | Validation error | {"error": "unknown_intent", "value": "...", "valid": [...]} or a mode-combination message — fix the parameter the body names. The response lists valid values where applicable. |
| 429 | Rate limit exceeded | {"error": "rate_limit", "limit": 20, "period": "minute", "retry_after": 42} — wait Retry-After seconds, then retry. See Rate limits. |
| 500 / 502 | Server / upstream error | Transient — retry with exponential backoff. Reserved credits are released automatically, so failed calls never bill. Persisting errors: contact support. |
Partial degradation isn't an error: when part of a request couldn't be honored (e.g. an exclusion that didn't resolve), the response is still 200 with a structured entry in warnings describing exactly what was skipped.