Agsemble
Docs/Build

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);