Surqo automatically generates alerts whenever a sensor reading crosses a predefined agronomic threshold. Each violation creates a database record and, if no alert email has been sent for that farm in the last 30 minutes, dispatches a styled HTML email via the Resend API. The 30-minute cooldown is tracked in Upstash Redis, so multiple simultaneous violations all produce DB records but only the first email is sent per window. All alerts endpoints require a valid Supabase JWT in theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ricardomb-tech/surqo/llms.txt
Use this file to discover all available pages before exploring further.
Authorization: Bearer header.
Threshold Reference
| Condition | Threshold | Severity |
|---|---|---|
| Soil moisture | < 25% | warning |
| Soil moisture | < 15% | critical |
| Air temperature | > 38°C | warning |
| Air temperature | > 42°C | critical |
| VPD | > 1.6 kPa | warning |
| VPD | > 2.5 kPa | critical |
| Battery | < 3400 mV | warning |
| Battery | < 3200 mV | critical |
critical, the recommended action is “Revisar condiciones del cultivo inmediatamente” and the response time is set to 2h. For warning alerts the recommended action is “Monitorear de cerca en las próximas horas” and response time is 6h.
Endpoints
GET /api/v1/alerts/active
Returns up to 50 unresolved alerts belonging to the authenticated user’s farms, ordered bycreated_at descending.
Filter to a single farm. The requesting user must own that farm, otherwise
403 is returned.200 OK — list[AlertResponse]
GET /api/v1/alerts/history
Returns resolved and unresolved alerts for the user’s farms.Filter to a specific farm owned by the user.
Maximum number of records to return. Defaults to
20.200 OK — list[AlertResponse]
GET /api/v1/alerts/{alert_id}
Fetch a single alert by its UUID.The UUID of the alert to retrieve. Returns
404 if not found and 403 if the farm does not belong to the requesting user.200 OK — AlertResponse
PATCH /api/v1/alerts/{alert_id}/resolve
Mark an alert as resolved (or un-resolve it). Setsresolved_at to the current UTC timestamp when resolved: true.
UUID of the alert to resolve.
Set to
true to resolve the alert. Set to false to reopen it (clears resolved_at).200 OK — Updated AlertResponse
POST /api/v1/alerts/{alert_id}/notify
Manually re-send the email notification for an alert. Useful for renotifications or testing the email pipeline. Unlike the automatic flow this endpoint does not check the Redis cooldown — it always attempts delivery.UUID of the alert to notify about.
Recipient email address. If the alert has a linked farm with
owner_email configured, that value is used when this field is omitted.Display name for the farm used in the email subject and body. Defaults to
"Finca".200 OK — Updated AlertResponse with email_sent: true
Error responses
| Status | Condition |
|---|---|
403 | Alert belongs to a farm not owned by the user |
404 | Alert not found |
422 | No to_email provided and no email configured on the farm |
502 | Resend API call failed — verify RESEND_API_KEY |
Alert Object
Email Cooldown
The 30-minute Redis cooldown is per farm. When multiple threshold violations arrive in the same 30-minute window, all violations create database records but only the first email is sent. If Redis is unavailable the cooldown check is skipped and the email is sent anyway, so delivery is always guaranteed.
alert_email_cooldown:{farm_id} with a TTL of 1800 seconds (30 minutes). Once an email is sent, all alerts in that batch have their email_sent and email_sent_at fields set to reflect the delivery.