Errors
Every error the API returns is a problem document (RFC 9457) with the
content type application/problem+json:
{
"type": "https://developers.i4sea.com.br/errors/quota_exceeded",
"title": "Monthly quota exceeded",
"status": 429,
"detail": "Company quota of 100000 units for 2026-10 is used up.",
"code": "quota_exceeded",
"request_id": "6f1c0e9e-..."
}
| Field | Meaning |
|---|---|
code | stable, machine-readable error code; branch on this |
status | the HTTP status, repeated |
title | short human-readable summary of the code; the same for every occurrence |
detail | explanation of this occurrence; meant for people, may change wording |
type | URI of the code's page in the error catalogue |
request_id | identifier of this request; quote it when you contact i4sea |
The error catalogue lists every code, its status and what to do about it.
Invalid parameters
A 400 invalid_request adds invalid_params, one entry per rejected parameter:
{
"type": "https://developers.i4sea.com.br/errors/invalid_request",
"title": "Invalid request",
"status": 400,
"detail": "One or more parameters are invalid.",
"code": "invalid_request",
"request_id": "6f1c0e9e-...",
"invalid_params": [{ "name": "hours", "reason": "must be between 1 and 360" }]
}
Request ids
Every response, successful or not, carries an X-Request-Id header, and error bodies repeat it as request_id. Log
it with your own request; it lets i4sea find that exact request when you report a problem.
When to retry
| Status | Codes | Retry? |
|---|---|---|
| 400 | invalid_request, key_in_query | No. Fix the request. |
| 401 | unauthenticated | No. Check the key. |
| 403 | insufficient_scope, subscription_inactive, product_not_in_plan, outside_coverage | No. These need a change of key, plan or coverage; contact i4sea. |
| 404 | not_found | No. Check the path against the API reference. |
| 413 | payload_too_large | No. Reduce the request body. |
| 429 | rate_limited | Yes, after Retry-After seconds. |
| 429 | quota_exceeded | Not before Retry-After, which points at the next monthly reset. |
| 500 | internal_error | Yes, a few times with exponential backoff; if it persists, contact i4sea with the request_id. |
| 503 | provider_unavailable | Yes, after Retry-After seconds. |
| 504 | timeout | Yes; if it repeats, ask for fewer hours or variables. |
Errors cost no units, but most count toward your per-minute limit, so a tight retry loop can end in 429
rate_limited. Always honour Retry-After when it is present, and add random jitter to your backoff when several
workers retry at once.
No data is not an error
A point inside your coverage with no forecast for the requested type is a 200 with "status": "no_data" and empty
series. It is a stable answer about that point, so retrying will not change it. A temporary failure to produce the
forecast is a 503 provider_unavailable instead.
Unknown codes
New error codes can be added to v1 (see Versioning policy). Handle a code you do not
recognize by its HTTP status.