Build
Prototype recipes
Four narrow product patterns for field monitoring, offline scouting, signal change alerts, and boundary review.
Field monitor
Use one field summary for the initial screen, then refresh granular weather or earth-observation endpoints only when that card needs newer data.
const fields = await agsemble.fields.list({ limit: 20 });
const summaries = await Promise.all(
fields.data.map((field) => agsemble.fields.summary(field.id)),
);
for (const summary of summaries) {
renderWeather(summary.components.weather);
renderNdvi(summary.components.earth_observation);
}Offline scouting
Create the observation ID and persist the complete record in SQLite before sending. A lost connection becomes a queued state, not an error that destroys the note.
const observation = {
id: `obs_${crypto.randomUUID().replaceAll("-", "")}`,
field_id: fieldId,
type: "scouting_note" as const,
note,
captured_at: new Date().toISOString(),
};
await localQueue.insert(observation);
await agsemble.observations.create(observation, {
idempotencyKey: observation.id,
});Field signal change watch
Store the previous normalized value in your own product, compare it with the latest summary, and show the exact rule that fired. Treat a threshold crossing as a review prompt, not a diagnosis.
const summary = await agsemble.fields.summary(fieldId);
const currentNdvi = summary.components.earth_observation.data?.indicator.mean;
if (currentNdvi != null && previousNdvi != null) {
const change = currentNdvi - previousNdvi;
if (change <= -0.15) {
queueReview({ fieldId, change, rule: "NDVI change <= -0.15" });
}
}Field boundary change review
Start from a user drawing, GeoJSON import, or satellite-derived suggestion. Require human review, save provenance, and compare durable versions without treating the boundary as cadastral truth.
const updated = await agsemble.fields.update(fieldId, {
geometry: reviewedGeometry,
boundary: {
determination_method: "auto_imagery",
confidence: modelConfidence,
source: { provider: "Fields of the World", version: "2025-alpha" },
},
});
const history = await agsemble.fields.boundaries(updated.id);