Guide: Error Handling
Every Intentgine API error returns a consistent JSON shape:
{ "error": "error_code", "message": "Human-readable description", "code": 400}Validation errors include an additional details field with per-field messages:
{ "error": "validation_error", "message": "Validation failed", "code": 400, "details": { "query": "Query must be 500 characters or less." }}Status Code Reference
Section titled “Status Code Reference”| Code | Error | Meaning | Action |
|---|---|---|---|
400 | bad_request | Invalid input or missing fields | Fix the request. Check message for details. |
400 | validation_error | Field value exceeds limits or is malformed | Fix the flagged fields. Check details for per-field messages. |
401 | unauthorized | Invalid or missing token | Verify your JWT is valid and not expired. Re-exchange your API key via POST /v1/auth if needed. |
402 | payment_required | Request balance exhausted | Purchase an overage pack or upgrade your plan in the Console. |
403 | forbidden | App suspended or action not allowed | Check your App status in the Console. |
404 | not_found | Resource not found (bank, toolset, classification set) | Verify the signature or ID exists and is assigned to your App. |
413 | payload_too_large | Request body exceeds size limit | Reduce payload size. See Handling Large Payloads. |
429 | too_many_requests | Rate limit exceeded | Back off and retry. Use Retry-After header. |
500 | internal_error | Server error | Retry with backoff. Contact support if persistent. |
502 | bad_gateway | Upstream provider error | Retry with backoff. |
503 | service_unavailable | Service temporarily down | Retry after the Retry-After header value (default 30s). |
Handling Rate Limits (429)
Section titled “Handling Rate Limits (429)”Rate limits are per-minute and proportional to your plan tier. When you hit the limit, the response includes headers to guide your retry:
{ "error": "too_many_requests", "message": "Rate limit exceeded", "code": 429}Headers:
Retry-After— seconds until the limit resetsX-RateLimit-Remaining—0when limitedX-RateLimit-Reset— Unix timestamp of next window
Retry with Backoff
Section titled “Retry with Backoff”async function callWithRetry(url: string, options: RequestInit, maxRetries = 3) { for (let attempt = 0; attempt <= maxRetries; attempt++) { const res = await fetch(url, options);
if (res.status === 429 || res.status >= 500) { if (attempt === maxRetries) throw new Error(`Failed after ${maxRetries} retries`);
const retryAfter = res.headers.get('Retry-After'); const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, attempt) * 1000; await new Promise(r => setTimeout(r, delay)); continue; }
return res; }}Handling Payment Required (402)
Section titled “Handling Payment Required (402)”When your request balance hits zero, all API calls return 402 until you add credits:
{ "error": "payment_required", "message": "Monthly request limit reached. Upgrade your plan or purchase additional credits.", "code": 402}To handle this proactively, monitor requests_remaining in every successful response’s metadata:
const data = await res.json();
if (data.metadata?.requests_remaining < 1000) { alertOps('Intentgine credits running low', data.metadata.requests_remaining);}Handling Validation Errors (400)
Section titled “Handling Validation Errors (400)”Validation errors use the validation_error code and include a details object with per-field messages:
{ "error": "validation_error", "message": "Validation failed", "code": 400, "details": { "query": "Query must be 500 characters or less. Keep it concise and focused. (650/500 characters). See https://docs.intentgine.dev/guides/large-payloads/ for strategies to handle large inputs." }}See the Handling Large Payloads guide for strategies to reduce input size.
Production Checklist
Section titled “Production Checklist”- Retry on 429, 500, 502, 503 with exponential backoff
- Don’t retry on 400, 401, 402, 403, 404 — these require a fix, not a retry
- Monitor
requests_remainingto avoid hitting 402 unexpectedly - Log error responses for debugging — include the
errorcode andmessage - Set timeouts on your HTTP client (recommended: 30s for resolve, 60s for batch)