Skip to content
i4seaAPI documentation

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.

LimitApplies toResetsWhen exceeded
Requests per minuteeach keyevery minute429 rate_limited
Units per monthyour company (all its keys)00:00 UTC on the 1st of each month429 quota_exceeded
Forecast horizonyour companydoes not resetthe 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:

EndpointCost
GET /i4cast/v1/forecast/point1 unit
GET /i4cast/v1/forecast/variables0 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:

HeaderMeaning
RateLimit-Limitrequests per minute allowed for this key
RateLimit-Remainingrequests left in the current minute
RateLimit-Resetseconds until the current minute's count resets
X-Quota-Remainingunits left in your company's monthly quota
Retry-Afteron 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 in Retry-After, then continue. Spreading requests evenly across the minute avoids it.
  • quota_exceeded: Retry-After points 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 in If-None-Match; if the forecast has not changed, the API answers 304 Not Modified with 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.