Skip to content

Index images

GET /v1/fields/{id}/image renders one index over the field for one date. Choose the format by what you do with it:

format Content type Use it for
png (default) image/png Showing the field on a map. Colourised, transparent outside the field.
tiff image/tiff Your own analysis. One float32 band of index values, NaN outside the field, georeferenced in WGS84 (EPSG:4326).

Python and JavaScript examples reuse API, session, headers and the field id from the Quickstart.

Parameter Required Notes
index yes An index from the statistics guide.
date yes YYYY-MM-DD. Use a date returned by dates.
format no png (default) or tiff.
width no Image width in pixels, 64 to 2048, default 512. The height follows the field’s shape.
source no sentinel-2 (default) or planet.

On success the body is the image itself. On failure it is the usual JSON error envelope with Content-Type: application/json, so check the status code before saving the body.

The X-AgroSat-Bounds header gives the geographic bounds of the image in WGS84, as west,south,east,north:

HTTP/1.1 200 OK
Content-Type: image/png
X-AgroSat-Bounds: 68.552,40.3084,68.560,40.3139
X-AgroSat-Units: 42

Stretch the image over exactly these bounds to place it on a map.

curl -sS -D headers.txt -o ndvi.png \
"https://api.agrosat.uz/v1/fields/cmgz7k2qv0004l8p3a9d1x6rt/image?index=ndvi&date=2026-05-14&width=1024" \
-H "X-API-Key: $AGROSAT_API_KEY"
grep -i '^x-agrosat-bounds' headers.txt

With Leaflet, for example, your frontend shows the PNG with L.imageOverlay(pngUrl, [[south, west], [north, east]]). Serve the PNG from your own backend: the API key must not reach the browser.

The GeoTIFF holds the index values themselves, so you can compute your own zones, histograms or differences between dates. With Python and rasterio:

import numpy as np
import rasterio
from rasterio.io import MemoryFile
r = session.get(
f"{API}/fields/{field_id}/image",
params={"index": "ndvi", "date": "2026-05-14", "format": "tiff", "width": 1024},
timeout=120,
)
r.raise_for_status()
with MemoryFile(r.content) as memfile, memfile.open() as ds:
print(ds.crs, ds.bounds, ds.dtypes[0]) # EPSG:4326, the X-AgroSat-Bounds box, float32
ndvi = ds.read(1) # 2-D array, NaN outside the field
values = ndvi[np.isfinite(ndvi)]
print("pixels in field:", values.size)
print("median NDVI:", float(np.median(values)))
print("share below 0.3:", float((values < 0.3).mean()))

r.raise_for_status() also stops on a 202; handle that as in Field readiness when the field may still be pending.

Response When
404 no_imagery_for_date The date is not among the field’s imagery dates, or its imagery cannot be rendered.
400 invalid_request format is not png or tiff, width is outside 64 to 2048, or date is not a valid YYYY-MM-DD.
400 invalid_index Unknown index, or one the chosen source does not support.
202 data_pending The field or the scene catalog for the date is still being prepared. Free.

An image costs ceil(area_ha) units, at least 1, whatever the format and width. The 41.53 ha example field costs 42 units per image.