# Fields

> Create, validate, measure, and revise tenant-owned Polygon or MultiPolygon field boundaries.

Human-readable version: https://agsemble.com/docs/api/fields

## List fields

```http
GET /api/v1/fields?limit=100&starting_after=fld_...
```

## Create a field

Send the boundary geometry; Agsemble calculates the authoritative area and perimeter. An optional area input remains accepted for compatibility but is never trusted as the stored measurement.

```json
{
  "name": "North greenhouse",
  "farm_id": "frm_demo",
  "crop_cycle": {
    "crop": "Tomato",
    "variety": "Moneymaker",
    "planted_at": "2026-07-20"
  },
  "geometry": {
    "type": "Polygon",
    "coordinates": [[[103.80, 1.30], [103.81, 1.30],
      [103.81, 1.31], [103.80, 1.31], [103.80, 1.30]]]
  },
  "boundary": {
    "determination_method": "auto_imagery",
    "source": {
      "provider": "Fields of the World",
      "dataset": "Global field boundaries",
      "version": "2025-alpha",
      "license": "CC-BY-4.0"
    }
  }
}
```

> **Validated, not cadastral:** GeoJSON uses longitude, latitude and every ring must be closed. Agsemble rejects self-intersections and malformed topology. Satellite suggestions are starting points—not ownership, cadastral, or legal boundaries.

## Map a boundary visually

Open the Field mapper in the console to draw a boundary, import GeoJSON, or tap a 2025 Fields of the World satellite-derived suggestion. Drag the white vertices to correct the candidate before saving.

```text
https://agsemble.com/console → Field mapper
```

## Save a new boundary version

```ts
const updated = await agsemble.fields.update(fieldId, {
  geometry: correctedGeometry,
  boundary: {
    determination_method: "manual",
    source: { provider: "Field team review" }
  }
});

const history = await agsemble.fields.boundaries(fieldId);
```
