Threshold alert history and irrigation, spray-window and frost advisory history
The append-only record of threshold alerts sent and of advisories generated, sent or held, with metric, rule, channel, delivery status, validity window and suppression reason. 28 fields across 2 datasets.
Catalogue entries: Alert history, Advisory history.
Questions this data answers
Did the farm act on the alerts it paid for: how many fired last month, how many were delivered, how many read?
Which fields trigger the same soil-moisture alert week after week, and is the threshold wrong or the irrigation?
When was the last spray-window advisory, and did the spray happen inside it?
Which advisories were generated but never reached a phone, and why?
Did a frost warning go out before last night's minimum, with how much lead time?
Threshold alerts are frequent and simple: a reading crossed a bound, a message went out, a row records it, nothing more. Advisories work the other way, rare and worth auditing individually: the platform decided something about irrigation, spraying, frost or crop condition, and the row records that decision whether or not a message followed it.
Threshold alerts
Every farm’s readings get checked continuously against the rules for its agro-ecological zone and crop, each carrying a low bound and a high one. A reading hovering right at a bound never fires twice, and 1 notification per metric per day is the hard ceiling on top of that. Anything raised between 22:00 and 06:00 East Africa Time waits and goes out together at 06:00 as 1 digest. Each row keeps the metric, the reading and which bound it crossed, the rule and its context, the type and channel, the delivery status and the exact text as delivered. When nothing crosses a bound, nothing gets written at all, so this table is, by construction, the history of notifications rather than of readings.
Advisories
4 types exist. Irrigation fires when the water balance crosses readily available water with no rain in the forecast, and comes with a recommended depth attached. Spray window fires when a sprayable threat is elevated in the risk dataset and the hours ahead are suitable, naming the window itself; soil-borne threats such as bacterial wilt never trigger spray advice at all. Frost fires on a forecast minimum below the crop’s own threshold. Vegetation anomaly fires when a field’s satellite index falls against its own history. Every advisory carries its validity window, severity, the model detail behind it and the farmer-facing text, and where one wasn’t sent the suppression reason says why: quiet hours, no phone on the account, cooldown, not prioritised, dry run, send failed. Even an account with no phone numbers at all, the zero-notification setting, keeps building the full advisory record and can read it straight from here.
A worked example
Once a day, in the morning, the advisory modules run. A station’s water balance shows depletion above readily available water, and the forecast carries no rain for the next 3 days, so an irrigation advisory gets generated with a recommended depth and a severity set by how far past the threshold the reading sits, valid for the coming day. The farm has 1 phone slot with the irrigation category switched on and the cooldown already passed, so the row lands as sent by SMS with the delivered text attached. That same evening, the hourly spray module finds late blight at moderate with a clear window the next morning, but the farm’s last spray was only yesterday, so a row gets written with cooldown as its suppression reason and nothing goes out at all.
Alert history
Append-only audit of every threshold evaluation that produced a notification: value, direction, channel, delivery status.
The engine cycle
new readingfrom the field
rule for this farmzone, crop and field settings
fires or stays quietat most 1 per metric per day
quiet hours?held for the morning digest
send + logSMS / WhatsApp, alert_events
A rule that does not fire writes nothing, so a quiet week is an empty query, not missing data.
the reading and whether it crossed the low or high bound
threshold_rule_id, aez_zone_id, crop_type_id
which rule fired and the context it was resolved in
notification_type, channel
threshold or digest; sms or whatsapp
status
sent, failed, queued for the 06:00 digest
message_text
the text as delivered
Rows are append-only. A rule that evaluates and does not fire writes nothing, so the table is the history of notifications, not of evaluations.
Dataset idfarm.alert_events
Cadence10 min engine cycle
EndpointGET /farm/alerts
Key scopefarm:read
Declared fields15
History2026-03 to today
Coverageyour own account
StatusOwn sensors, own account
Narrowed to your own gateways and to devices approved for API exposure.
Only for the account that owns the hardware. Readings and everything computed from them are served to keys on the owning account and to nobody else. The way to get this dataset is a station on your own field, or your own sensors sent in through Sensor Ingest. A NuaSense station on the field is what produces these rows; the hardware is described at nuasense.com/products.
Fields
Field
Unit
Note
id
—
gateway_id
—
dev_eui
—
metric
—
value
—
direction
—
triggered_at
—
aez_zone_id
—
crop_type_id
—
threshold_rule_id
—
notification_type
—
channel
—
status
—
message_text
—
created_at
—
Filters
No tag filters. Narrow with start, end, fields and limit.
Through the MCP connector the same read is the platform_dataset tool with dataset=farm.alert_events. Through a scheduled export it is one job with the same filters, delivered as a file. Every dataset takes the same arguments: start and end, every with agg, fields, limit up to 5,000, order, and the tags it declares.
Advisory history
Irrigation / spray-window / frost / NDVI-anomaly advisories, including dry-run rows with suppressed_reason set.
How a spray-window advisory is decided
sprayable threat elevated?disease_risk, Medium or Highno → nothing written
next hours suitable?derived_hourly spray index, forecast wind and rainno → advisory_alerts row, suppressed_reason = not sent
recipient and channelfarm phone slots, quiet hoursheld → quiet_hours · no phone → no_phone · sent → notification_sent
suppressed_reason
Meaning
quiet_hours
generated between 22:00 and 06:00, held for the digest
no_phone
the account has no phone slot with this category enabled
cooldown
the same advisory had gone out shortly before
not_prioritized
a higher-scored threat was sent instead
dry_run
written for the record without sending
send_failed
the provider rejected the message; the row keeps the error
Every advisory is written whether or not it was sent. An account with no phone on file still reads its full advisory history here.
Dataset idfarm.advisory_alerts
Cadencedaily
EndpointGET /farm/advisories
Key scopefarm:read
Declared fields13
History2026-03 to today
Coverageyour own account
StatusOwn sensors, own account
Narrowed to your own gateways and to devices approved for API exposure.
Only for the account that owns the hardware. Readings and everything computed from them are served to keys on the owning account and to nobody else. The way to get this dataset is a station on your own field, or your own sensors sent in through Sensor Ingest. A NuaSense station on the field is what produces these rows; the hardware is described at nuasense.com/products.
Fields
Field
Unit
Note
id
—
gateway_id
—
advisory_type
—
severity
—
valid_from
—
valid_until
—
message_text
—
payload
—
model detail jsonb
notification_sent
—
notification_sent_at
—
channel
—
suppressed_reason
—
set when the advisory was generated but not sent
created_at
—
Filters
No tag filters. Narrow with start, end, fields and limit.
Through the MCP connector the same read is the platform_dataset tool with dataset=farm.advisory_alerts. Through a scheduled export it is one job with the same filters, delivered as a file. Every dataset takes the same arguments: start and end, every with agg, fields, limit up to 5,000, order, and the tags it declares.
Related datasets
Also in Farm records
Field polygons and sensor settings for your farmField polygons as GeoJSON with crop and area, and per-node settings with crop assignment, planting and phenology dates, last spray date and the growing-degree-day accumulator. 25 fields across 2 datasets.
Read together with this page
Disease and pest risk data for potato, onion and coffeeRisk per threat for the station's crop, every hour: percent, level, threat score, accumulated disease severity, the conducive hours behind the score and how much input data backed it. 22 models across potato, onion and coffee.
Root-zone water balance and irrigation need, daily1 row per station per day: root-zone depletion against the water the soil holds, with the day's evapotranspiration and rain, the numbers behind the irrigation advisory.
Spray window, leaf wetness and degree-day data, hourly29 variables computed every hour from the station's own readings: dew point, vapour-pressure deficit, evapotranspiration, delta-T, spray quality with its limiting factor, inversion risk, leaf wetness and degree-days for the crop and 9 pests. Every field carries a calibration tier.