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.
Request
Section titled “Request”| 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.
Image bounds
Section titled “Image bounds”The X-AgroSat-Bounds header gives the geographic bounds of the image in WGS84, as west,south,east,north:
HTTP/1.1 200 OKContent-Type: image/pngX-AgroSat-Bounds: 68.552,40.3084,68.560,40.3139X-AgroSat-Units: 42Stretch the image over exactly these bounds to place it on a map.
Download a PNG
Section titled “Download a PNG”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.txtr = session.get( f"{API}/fields/{field_id}/image", params={"index": "ndvi", "date": "2026-05-14", "width": 1024}, timeout=120,)if r.headers["Content-Type"].startswith("application/json"): raise RuntimeError(r.json()["error"])west, south, east, north = map(float, r.headers["X-AgroSat-Bounds"].split(","))with open("ndvi.png", "wb") as f: f.write(r.content)import { writeFile } from "node:fs/promises";
const url = new URL(`${API}/fields/${fieldId}/image`);url.search = new URLSearchParams({ index: "ndvi", date: "2026-05-14", width: "1024" });const res = await fetch(url, { headers });if (!res.ok || res.status === 202) throw new Error(JSON.stringify(await res.json()));const [west, south, east, north] = res.headers.get("X-AgroSat-Bounds").split(",").map(Number);await writeFile("ndvi.png", Buffer.from(await res.arrayBuffer()));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.
Read a GeoTIFF
Section titled “Read a GeoTIFF”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 npimport rasteriofrom 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.
Errors
Section titled “Errors”| 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.
