Field readiness and data preparation
AgroSat does not compute anything until a field is registered. Registration starts a background job that finds the imagery over the field and computes its statistics. Until that work is done, data requests answer 202 data_pending instead of making you wait on an open connection.
What registration prepares
Section titled “What registration prepares”Registration prepares history from 1 January of the previous calendar year up to the day of registration. A field registered in May 2026 is prepared from 1 January 2025.
If your contract sets a later earliest history date, preparation starts from that date instead.
Field status
Section titled “Field status”GET /v1/fields/{id} reports where the field is:
status |
Meaning |
|---|---|
pending |
The registration history is being prepared. Data requests answer 202. |
ready |
The registration history is prepared. |
A ready field goes back to pending if its boundary is redrawn in the AgroSat web app, until history is prepared again for the new boundary.
202 data_pending
Section titled “202 data_pending”Satellite endpoints answer 202 when the data you asked for is not prepared yet, and start preparing it if nothing is running. The body is the error envelope with code data_pending, and the Retry-After header says how many seconds to wait:
HTTP/1.1 202 AcceptedRetry-After: 30Content-Type: application/json
{"success": false, "error": {"code": "data_pending", "message": "Statistics for this window are being prepared."}}You get 202 when:
- the field is still
pending; - you ask for a window older than the registration history, but not older than your contract allows;
- the scene catalog for a window is still being filled;
- statistics for some dates in the window have not been computed yet.
Treat Retry-After as the source of truth rather than a fixed delay. A simple wait loop:
url="https://api.agrosat.uz/v1/fields/$FIELD_ID/statistics?index=ndvi&from=2025-04-01&to=2025-09-30"while :; do code=$(curl -s -o body.json -D headers.txt -w '%{http_code}' "$url" -H "X-API-Key: $AGROSAT_API_KEY") [ "$code" != "202" ] && break sleep "$(grep -i '^retry-after:' headers.txt | tr -dc '0-9')"donecat body.jsonimport time
def get_when_ready(session, url, params, max_wait=1800): waited = 0 while True: r = session.get(url, params=params, timeout=120) if r.status_code != 202: return r delay = int(r.headers.get("Retry-After", "30")) if waited + delay > max_wait: raise TimeoutError("data still being prepared") time.sleep(delay) waited += delayasync function getWhenReady(url, headers, maxWaitSeconds = 1800) { let waited = 0; for (;;) { const res = await fetch(url, { headers }); if (res.status !== 202) return res; const delay = Number(res.headers.get("Retry-After") ?? 30); if (waited + delay > maxWaitSeconds) throw new Error("data still being prepared"); await new Promise((resolve) => setTimeout(resolve, delay * 1000)); waited += delay; }}If you register many fields at once, poll GET /v1/fields/{id} (free) until each is ready, rather than repeating satellite requests in a tight loop. Both kinds of request count towards your rate limit.
How far back you can go
Section titled “How far back you can go”Your contract sets the earliest date your organization may request. A window that starts before it is refused, not prepared:
{ "success": false, "error": { "code": "date_out_of_range", "message": "The earliest date available to this organization is 2024-01-01." }}Windows between that date and the start of the registration history are prepared on first request: expect a 202 the first time.
Dates that could not be computed
Section titled “Dates that could not be computed”Sometimes a date has imagery but no statistics can be computed for it. When preparation of a window has finished within the last 24 hours and some dates are still missing, the API does not start again. It answers 200 with the dates it has and lists the rest in unavailable_dates:
{ "success": true, "data": { "field_id": "cmgz7k2qv0004l8p3a9d1x6rt", "index": "ndvi", "data": [ { "date": "2026-05-14", "mean": 0.6124, "median": 0.6347, "min": 0.1812, "max": 0.8021, "std": 0.0938, "p10": 0.4783, "p90": 0.7214, "valid_fraction": 0.9871, "cloud_fraction": 0.0129, "cloud_mask": "scl_cld" } ], "unavailable_dates": ["2026-05-19", "2026-05-24"] }}You pay only for dates returned in data; a response with no data costs nothing. After 24 hours the same request tries those dates once more.
