Triatomine API · error reference
Every error response uses the same envelope. The code
field is the stable identifier — never parse message. This page is
the canonical doc; error.docs_url deep-links here.
Envelope shape
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded (1 req/sec for tier 'free'). Retry after 1s.",
"retry_after": 1,
"docs_url": "http://www.triatomine.com/errors#rate_limited"
}
}
auth_required#
401
API key is missing, malformed, unknown, or revoked.
- No `X-API-Key` header on the request.
- Key doesn't match the `tri_<8 hex>_<32 hex>` format.
- Key prefix is unknown to this server (typo, wrong environment, or never issued).
- Key was revoked via `triatomine-keys revoke <prefix>`.
- Secret portion of the key doesn't match the stored hash.
Send `X-API-Key: tri_<prefix>_<secret>` on every request. Confirm the key is active with `triatomine-keys list`. If lost, issue a fresh one with `triatomine-keys create <email>` and update your client. The full key is shown ONCE on creation; we only persist the prefix + hash.
validation_error#
422
Request body or query parameters failed validation.
- URL is malformed (`url` must be a valid `http(s)://...` URL).
- `force_tier` or `max_tier` outside the 1..4 range.
- Required field missing or wrong type.
Inspect `error.message` for the field-by-field complaint, fix the request, and retry. Validation errors are deterministic — same body always returns the same 422.
invalid_request#
400 404 405
Endpoint, method, or argument combination isn't supported.
- Hit an undefined route (404). See `/docs` for the supported surface.
- Used the wrong HTTP method on a valid path (405).
- Asked for tier 3 or 4 on the sync `/v1/scrape` endpoint (400). Tier-3+ is forced async — use `POST /v1/jobs`.
For 404/405, check `/docs` or `/openapi.json` for the canonical route surface. For tier-3+ scrapes, switch to `POST /v1/jobs` and poll `GET /v1/jobs/{id}`.
rate_limited#
429
Per-(IP, API key) rate limit exceeded.
- Free tier: 1 req/sec. Starter / Growth / Scale: 10 req/sec.
- Limit is per-(IP, key) — sharing a key across many machines doesn't multiply your budget; same machine across multiple keys does have its limits tracked independently.
Read `Retry-After` (seconds) and `X-RateLimit-Remaining` from the response headers, back off, and retry. For sustained higher throughput, upgrade your tier — see pricing in your dashboard.
timeout#
408
Synchronous scrape exceeded the 30-second budget.
- Tier-1 fetch on a slow site (rare).
- Tier-2 (Playwright) escalation that took too long.
Use `POST /v1/jobs` for any URL that may exceed 30 seconds. Async jobs have a 5-minute budget and tier-3 / tier-4 stealth work routes there automatically.
tier_unavailable#
503
Reserved — a backend tier is temporarily unavailable.
- Not yet emitted by the live API. Reserved for future use when the worker pool is saturated or a tier is in maintenance.
Treat as transient. Back off and retry, or constrain to a lower `max_tier` to stay within available capacity.
email_unverified#
403
API key is valid but the owning email hasn't been verified yet.
- Account just signed up; verification email is sitting in the inbox.
- Verification email landed in spam.
- User clicked a stale verification link.
Open the most recent welcome email and click the verification link. Lost the email? Request a fresh one from the dashboard or hit POST /signup with the same address — we'll resend without creating a duplicate account.
host_blocked#
451
Operator-blocked host (kill-switch). Refuses the request before any work.
- Target site requested removal from our scraping pool.
- Legal/compliance escalation (copyright complaint, ToS violation, etc).
- Operator manually added the host to the global blocklist via the admin dashboard.
This is policy, not a technical block — retrying won't change the outcome. If you believe the block was set in error, contact support@triatomine.com with the host name.
internal_error#
500
Unexpected server-side failure. We log and alert on these.
- Bug in the orchestrator or one of the fetchers.
- Disk / network / dependency outage we didn't degrade gracefully.
Retry the request. If it reproduces, file an issue at https://github.com/PatelVro/triatomine/issues with the request body, the API key prefix (NOT the full key), and the timestamp.