API de Pasto: guía de uso
Versión 1. Estimación de materia seca (kg MS/ha) de pasturas a partir de imágenes satelitales.
Estado actual: demostración. Mientras el servicio corra en modo demostración, los valores son sintéticos y no corresponden a mediciones reales. Cada respuesta lo indica con
"demo": true.
- URL base:
https://pasto.mateinalab.com - Documentación interactiva (se prueba desde el navegador):
https://pasto.mateinalab.com/docs - Pantalla web (sin programar):
https://pasto.mateinalab.com/?lang=es(en inglés:https://pasto.mateinalab.com)
1. Autenticación
Todas las rutas /v1/... requieren la cabecera X-API-Key con la clave que te entrega Pasto.
Sin clave, o con una clave vencida o dada de baja, la respuesta es 401.
Tratá la clave como un secreto: usala desde tu servidor, no la pongas en páginas web públicas ni en repositorios.
2. Medir los lotes de un archivo KML o KMZ
POST /v1/measurements/kml (multipart/form-data)
| Campo | Descripción | |
|---|---|---|
file |
obligatorio | Archivo .kml o .kmz con uno o más lotes (polígonos). |
species |
obligatorio | Especie de pastura (ver la sección 4). |
date |
opcional | Fecha de interés, AAAA-MM-DD. Si falta, se usa la imagen más reciente. |
include_geometry |
opcional | true para recibir también el GeoJSON de cada lote. |
curl -X POST "https://pasto.mateinalab.com/v1/measurements/kml" \
-H "X-API-Key: pasto_TU_CLAVE" \
-F "file=@lotes.kml" \
-F "species=Verdeo avena"
Sobre el archivo:
- Se miden los polígonos, uno por lote (por cada Placemark, con su nombre). Los puntos y las líneas se ignoran.
- Coordenadas en WGS84 (longitud,latitud, el formato estándar de KML).
- Máximo 25 lotes y 5 MB por pedido; cada lote entre 0,1 y 500 ha.
3. Medir un círculo alrededor de un punto
POST /v1/measurements/point (JSON)
| Campo | Descripción | |
|---|---|---|
latitude, longitude |
obligatorios | Centro, en grados decimales. |
radius |
obligatorio | Radio en metros, entre 20 y 500. |
species |
obligatorio | Especie de pastura. |
date, include_geometry |
opcionales | Igual que en el endpoint de KML. |
curl -X POST "https://pasto.mateinalab.com/v1/measurements/point" \
-H "X-API-Key: pasto_TU_CLAVE" \
-H "Content-Type: application/json" \
-d '{"latitude": -34.9, "longitude": -60.3, "radius": 150, "species": "Verdeo avena"}'
4. Especies
GET /v1/species devuelve la lista vigente, cada especie con su name, su resource y una description legible. Hoy son nueve: Verdeo ryegrass, Promocion ryegrass, Verdeo avena,
Graminea pura, Leguminosa pura, Consociada base gramineas, Consociada base leguminosas,
Consociada gramineas y leguminosas y Campo natural. El name es el identificador que se envía; no distingue mayúsculas ni tildes.
5. Respuesta
{
"request_id": "35241fa2734a449985d7d5534a19d80f",
"species": "Verdeo avena",
"demo": true,
"results": [
{
"name": "Potrero Norte",
"area_ha": 25.1,
"status": "ok",
"satellite_date": "2026-10-09",
"dry_matter_kg_ha": { "mean": 990, "median": 1029, "p10": 864, "p90": 1190 },
"pixels": { "total": 2509, "valid": 2240, "percent_valid": 89.3 },
"warnings": [],
"geometry": null
}
],
"warnings": []
}
Hay un elemento en results por lote. dry_matter_kg_ha resume la materia seca en kg por hectárea (promedio, mediana y
percentiles 10 y 90), calculada sobre los píxeles utilizables de 10 m × 10 m; las nubes y sombras se descartan y se
cuentan en pixels. status es ok, o no_imagery si no hubo una imagen satelital utilizable para ese lote (en ese
caso no hay estadísticas). Los warnings avisan, por ejemplo, de que pocos píxeles fueron utilizables. geometry es
null salvo que envíes include_geometry=true, y entonces trae el lote como GeoJSON.
6. Errores
Siempre tienen el mismo formato, con un request_id para pedir soporte (el ejemplo se pidió con ?lang=es; por defecto el
message viene en inglés):
{ "error": { "code": "unknown_species", "message": "Especie desconocida: 'Soja'.", "request_id": "..." } }
| HTTP | code |
Cuándo |
|---|---|---|
| 401 | invalid_api_key |
Clave ausente, inválida, vencida o dada de baja. |
| 413 | file_too_large |
El archivo supera los 5 MB. |
| 422 | invalid_request, unknown_species, invalid_date, invalid_radius |
Parámetros inválidos. |
| 422 | invalid_kml, no_polygons, invalid_geometry, too_many_features, area_too_small, area_too_large |
Problemas con el KML. |
| 502, 503 | engine_error, engine_not_ready, auth_unavailable |
Falla temporal del servicio: reintentar más tarde. |
7. Ejemplos de código
Python
import requests
URL = "https://pasto.mateinalab.com"
KEY = "pasto_TU_CLAVE"
with open("lotes.kml", "rb") as archivo:
respuesta = requests.post(
f"{URL}/v1/measurements/kml",
headers={"X-API-Key": KEY},
files={"file": archivo},
data={"species": "Verdeo avena"},
timeout=120,
)
respuesta.raise_for_status()
for lote in respuesta.json()["results"]:
print(lote["name"], lote["dry_matter_kg_ha"]["mean"], "kg MS/ha")
JavaScript (Node 20 o superior)
import { openAsBlob } from "node:fs";
const URL_BASE = "https://pasto.mateinalab.com";
const KEY = "pasto_TU_CLAVE";
const form = new FormData();
form.append("file", await openAsBlob("lotes.kml"), "lotes.kml");
form.append("species", "Verdeo avena");
const res = await fetch(`${URL_BASE}/v1/measurements/kml`, {
method: "POST",
headers: { "X-API-Key": KEY },
body: form,
});
const datos = await res.json();
if (!res.ok) throw new Error(`${datos.error.code}: ${datos.error.message}`);
for (const lote of datos.results) console.log(lote.name, lote.dry_matter_kg_ha.mean, "kg MS/ha");
8. Idioma
Los mensajes (errores y advertencias) y las descripciones de las especies vienen en inglés por defecto. Agregá
?lang=es a cualquier pedido /v1/... para recibirlos en español, por ejemplo POST /v1/measurements/kml?lang=es.
Los códigos (code, status) y los nombres de los campos nunca cambian: el code es para tu programa y el message
es para personas.
9. Recomendaciones
- Tiempos de espera: configurá un timeout de al menos 60 segundos. En el entorno de demostración el servicio puede tardar hasta un minuto en responder la primera vez después de un rato sin uso.
- Reintentos: ante un
502o503, esperá unos segundos y reintentá. - Soporte: guardá el
request_idde las respuestas con error. - Prueba rápida:
https://pasto.mateinalab.com/docspermite cargar tu clave y probar cada endpoint sin escribir código.