Overview
Crop Zones enable you to track field-specific agronomic data within production seasons, providing detailed temporal and spatial context for each field's usage.
Cardinality summary
- Workspace β 1..* Organizations
- Organization β 1..* Properties
- Property β 1..* Fields
- Field β 0..* Crop Zones (max 1 per Season)
- Season β 0..* Crop Zones (max 1 per Field)
- (Field, Season) pair β 0..1 Crop Zone (UNIQUE)
Workspace
βββ Organization
βββ Seasons 1..*
βββ Properties 1..*
βββ Fields 1..*
βββ Crop Zones (0..1 per Season)
The Crop Zone references:
Key Concepts
Concept | Description |
---|
Crop Zone | Unique seasonal representation of a field (Season Γ Field) |
Period | Start / end datetimes start_date / end_date (UTC+0 ISO 8601) defining active crop window |
Agronomic Info | Nested object aggregating varieties, planting/emergence, yield, spacing, irrigation, etc. |
Varieties | Set of variety UUIDs planted in that season on the field |
Uniqueness | At most one Crop Zone exists for a given Season + Field pair |
Geometry | Optional valid GeoJSON Polygon (WGS84 lon/lat, closed ring, non self-intersecting) |
Uniqueness & Integrity Rules
Rule | Rationale |
---|
(season_id, field_id) must be unique | Prevent conflicting agronomic data |
Field must belong to a Property under same Organization as Season | Consistent ownership & ACLs |
Period start_date < end_date | Valid temporal interval |
(Recommended) Period lies inside Season timeframe | Logical containment |
Geometry (if provided) valid GeoJSON Polygon | Spatial integrity |
Attempting to create a second crop zone for the same Season + Field returns a conflict (409) or validation error. Query first or use idempotent logic.
Business Rules (Create & Update)
Permissions
- Caller must have create permission for every involved organization (derived from each property's company) or request is rejected.
Existence & Ownership
- All referenced properties, seasons, and fields must exist.
- Each field must belong to the referenced property; mismatches fail validation.
- Season and property must belong to the same company.
- Fields must be available (not archived / blocked).
Duplicate Handling & Soft-Deleted Reuse
- (season_id, field_id) uniqueness enforced; creation path reuses an existing (even soft-deleted) crop zone record (reactivates & overwrites data) instead of inserting a new row.
Geometry
- If payload includes geometry (no geometry_id) a new geometry is persisted; calculated area stored.
- Geometry MUST be a valid GeoJSON Polygon: WGS84 [longitude, latitude], first and last coordinate identical, no self-intersections, coordinates within [-180..180, -90..90].
- If geometry is omitted today no automatic derivation occurs (planned future enhancement: derive from field geometry when absent).
- On update, existing geometry reference retained unless a new one is supplied.
- Spatial & temporal overlap checks run at property level; field-level collision checks ensure no active overlapping zones for same field.
Varieties & Agronomic Info
- If season has a crop_id, any variety IDs must exist in the crop's catalog.
Temporal Adjustments
- On update the new period is applied before validations so overlap checks use incoming dates.
- After create/update, affected season start/end may be recomputed (aggregate across its crop zones / land scope).
Batch Transaction
- Each batch is atomic: any failure aborts all creates/updates.
- Preloads: existing crop zones (by property/field), previous versions (for update), seasons, properties, fields, geometries.
API Documentation
For complete API reference including request/response schemas, authentication, and interactive testing, visit:
π Crop Zones API Documentation - Interactive API documentation with request/response examples
Available Endpoints
Method & Path | Purpose |
---|
POST /v3/cropzones | Create a crop zone |
PUT /v3/cropzones | Update (single) crop zone (full body) |
DELETE /v3/cropzones | Delete multiple crop zones (IDs in body) |
POST /v3/cropzones/batch | Batch create |
PUT /v3/cropzones/batch | Batch update |
DELETE /v3/cropzones/batch | Batch delete |
GET /v3/cropzones/{uuid} | Retrieve by ID |
DELETE /v3/cropzones/{uuid} | Delete by ID |
GET /v3/cropzones/org/{uuid} | List by organization |
GET /v3/cropzones/property/{uuid} | List by property |
POST /v3/cropzones/list | Filter / paginate |
Best Practices
Practice | Why |
---|
Enforce (season_id, field_id) uniqueness client-side | Reduce conflicts & retries |
Use batch endpoints for bulk ingestion | Efficiency & atomicity at request level |
Normalise geometry on create | Stable spatial comparisons |
Record all planting/emergence events | Better agronomic analytics |
Avoid geometry in frequent polling | Lower bandwidth |
Avoid large (> 100) batch sizes in POST and PUT | Excessive load and possible timeouts |
Error Codes
Detailed (non-exhaustive) errors surfaced during create & update flows. Some codes listed for completeness though not always triggered in standard paths.
Permission / Auth
Code | HTTP | Message | Trigger |
---|
EIAM001 | 403 FORBIDDEN | Account does not have permission to perform this operation | Missing crop zone create/update org permission or RBAC denial |
Property
Code | HTTP | Message | Trigger |
---|
EPRO007 | 404 NOT_FOUND | Property does not exist | Referenced property id missing |
Season
Code | HTTP | Message | Trigger |
---|
ESEA009 | 404 NOT_FOUND | Season does not exist | Referenced season id missing |
ESEA012 | 400 BAD_REQUEST | Seasons org and properties org must be the same | Season & property company mismatch |
ESEA006 | 400 BAD_REQUEST | Invalid variety | New variety ids not in catalog for season crop |
ESEA007 | 400 BAD_REQUEST | Invalid Start Date | (Indirect) recomputed season start invalid after adjustments |
ESEA008 | 400 BAD_REQUEST | Start date cannot be after end date | (Indirect) recomputed bounds inverted |
Crop Zone
Code | HTTP | Message | Trigger |
---|
CZE003 | 404 NOT_FOUND | There no CropZone with this ID | Missing existing crop zone during update lookup |
CZE002 | 400 BAD_REQUEST | One or more IDs at the UPDATE section does not exist | Batch update includes non-existent IDs |
CZE001 | 400 BAD_REQUEST | ID null in bulk (not typical) | Bulk validation (other flows) |
CZE004 | 400 BAD_REQUEST | All IDs in section do not exist | Bulk validation (other flows) |
CZE005 | 400 BAD_REQUEST | CropZone already exists for %s | Legacy duplicate path (creation now reuses existing) |
CZE006 | 400 BAD_REQUEST | Either cycle_ids and season_ids may be present. Not both | Conflicting list/filter parameters (not create/update) |
Geometry & Spatial / Temporal
Situation | HTTP | Description |
---|
Spatial overlap (property) | 400 BAD_REQUEST | Overlap with other crop zones in same property |
Field-level collision | 400 BAD_REQUEST | Another active crop zone for same field conflicts |
Invalid geometry | 400 BAD_REQUEST | Malformed / self-intersecting polygon |
Period invalid | 400 BAD_REQUEST | start_date >= end_date or violates internal constraints |
Generic / Other
Situation | HTTP | Description |
---|
Resource not found | 404 NOT_FOUND | Generic missing referenced entity |
Duplicate Season Γ Field (attempt) | 409 CONFLICT | Uniqueness attempt when reuse logic not applied |
Permission denied (any stage) | 403 FORBIDDEN | Lacking required scope / RBAC |
Next Steps