Limits and quotas
Your plan sets three limits. Their values are set by i4sea per plan and can be adjusted per company; ask your i4sea account manager for yours. As an example, the pilot plan allows 60 requests per minute, 100,000 units per month and a 240-hour forecast horizon.
| Limit | Applies to | Resets | When exceeded |
|---|---|---|---|
| Requests per minute | each key | every minute | 429 rate_limited |
| Units per month | your company (all its keys) | 00:00 UTC on the 1st of each month | 429 quota_exceeded |
| Forecast horizon | your company | does not reset | the series are cut, horizon_limited: true |
Units: what each call costs
Each endpoint has a fixed cost in units, shown on its page in the API reference:
| Endpoint | Cost |
|---|---|
GET /i4cast/v1/forecast/point | 1 unit |
GET /i4cast/v1/forecast/variables | 0 units |
Only successful (2xx) responses are charged. A 304 Not Modified, an error and a point outside your coverage cost
nothing. A point inside your coverage with no data for the type is a successful 200 with "status": "no_data", so
it is charged.
Requests per minute
Every request counts toward its key's per-minute limit, including errors and 304 responses. The exceptions are
requests refused before the limits are checked: a missing or invalid key, a key without the endpoint's scope, and a
company whose subscription is inactive or whose plan does not include the endpoint's product.
Limit headers
Responses to an identified key carry the current state of both limits:
| Header | Meaning |
|---|---|
RateLimit-Limit | requests per minute allowed for this key |
RateLimit-Remaining | requests left in the current minute |
RateLimit-Reset | seconds until the current minute's count resets |
X-Quota-Remaining | units left in your company's monthly quota |
Retry-After | on 429 (and 503): seconds to wait before sending the next request |
HTTP/1.1 200 OK
Content-Type: application/json
RateLimit-Limit: 60
RateLimit-Remaining: 57
RateLimit-Reset: 23
X-Quota-Remaining: 98412
ETag: W/"..."
Cache-Control: private, max-age=300
X-Request-Id: 6f1c0e9e-...
The limit headers can be missing, for example on a request that was refused before the key was identified, or while i4sea's limits store is degraded (requests are then served without limits). Treat a missing header as "unknown", not as zero.
When you get a 429
rate_limited: wait the number of seconds inRetry-After, then continue. Spreading requests evenly across the minute avoids it.quota_exceeded:Retry-Afterpoints at the start of next month (00:00 UTC on the 1st). Do not retry in a loop; contact i4sea if you need a larger quota.
Watch X-Quota-Remaining to see the quota running out before it does.
Forecast horizon
hours accepts 1 to 360. When it asks for more than your plan's horizon, the response stops at the horizon and sets
"horizon_limited": true; it is still a 200 and costs the same.
Save units with caching
A forecast only changes when a new model run is published, so you rarely need to download it again:
- Responses carry
Cache-Control: private, max-age=300: you can reuse a response for 5 minutes without asking again. - Responses carry an
ETag. Send it back inIf-None-Match; if the forecast has not changed, the API answers304 Not Modifiedwith no body and charges no units (the request still counts toward the per-minute limit).
curl -s -i "https://api.i4sea.com.br/i4cast/v1/forecast/point?latitude=-23.9545&longitude=-46.3278&type=weather" \
-H "Authorization: Bearer $I4SEA_API_KEY" \
-H 'If-None-Match: W/"..."'
The ETag also changes as the forecast window moves (every hour) and when your parameters change, so store it per
request URL.