Roots docs

Webhooks

Roots posts an event to your endpoint when something happens on a farm.

roots webhooks add https://example.com/roots --events alert.created,command.done
POST /v1/farms/{farm}/webhooks
{ "url": "https://example.com/roots", "events": ["alert.created", "command.done"] }

The response includes the signing secret once. Use ["*"] for every event.

Events: alert.created, alert.resolved, command.queued, command.done, command.failed, event.created, device.created, animal.created.

Payload

{
  "id": "evt_…",
  "type": "alert.created",
  "farm_id": "farm_…",
  "created_at": "2026-10-18T06:12:00Z",
  "data": { "id": "alr_…", "severity": "urgent", "title": "Ammonia high", "reason": "Ammonia is 27 ppm in Roost 2. …" }
}

Verify the signature

Each request carries Roots-Signature: t=<unix seconds>,v1=<hex>, where v1 is HMAC-SHA256 of "<t>.<raw body>" with your secret. Reject requests more than five minutes old.

import { verifyWebhook } from '@roots-sh/sdk';
if (!(await verifyWebhook(secret, signature, rawBody))) return new Response('bad signature', { status: 400 });

Respond within five seconds with any 2xx.