Rate limits
Each API key may send a fixed number of requests per minute: 60 unless your contract sets another rate. The owner sees the current rate in Settings → API keys.
The limit counts every request with the key, including field calls and requests that end in 202 or an error. Each key has its own counter, so two keys of one organization can each use the full rate.
When you go over
Section titled “When you go over”Requests over the limit are refused by the API gateway and are not billed:
HTTP/1.1 429 Too Many RequestsRetry-After: 17Content-Type: application/json
{"success": false, "error": {"code": "rate_limited", "message": "Rate limit exceeded."}}Wait the number of seconds in Retry-After, then send the request again.
curl --retry 5 \ "https://api.agrosat.uz/v1/fields" -H "X-API-Key: $AGROSAT_API_KEY"--retry makes curl honour Retry-After on 429. It does not repeat 202.
import time
def request(session, method, url, **kwargs): for _ in range(5): r = session.request(method, url, timeout=60, **kwargs) if r.status_code != 429: return r time.sleep(int(r.headers.get("Retry-After", "60"))) return rasync function request(url, init = {}) { for (let attempt = 0; ; attempt++) { const res = await fetch(url, init); if (res.status !== 429 || attempt === 4) return res; const wait = Number(res.headers.get("Retry-After") ?? 60); await new Promise((resolve) => setTimeout(resolve, wait * 1000)); }}Staying under the limit
Section titled “Staying under the limit”- Spread bulk work, such as registering many fields, over time instead of sending it in a burst.
- Poll
GET /v1/fields/{id}everyRetry-Afterseconds rather than faster. - Keep the responses you already have, such as statistics for past dates, instead of requesting them again.
- Use one key per environment so tests do not eat into production’s rate.
Next steps
Section titled “Next steps”Field readinessWaiting on 202 without wasting requests.
ErrorsAll error codes and retry advice.
