Receive events and manage webhooks
ALYT delivers developer-visible events in two ways: signed webhooks for your server and an event stream for long-lived reads. Both carry the same JSON envelope, and both are scoped by the developer key you attach to them. Webhooks are retried and recorded per delivery; the stream resumes from the monotonic event id so you can continue after a disconnect.
Event model
Section titled “Event model”What you can receive is driven by the event outbox. Producers record an event after the underlying change is stored, not instead of it. The maintained kinds named in the platform are device.online, device.offline, device.telemetry, command.result, notification.raised, thing.state, submission.state, and webhook.ping. Event payload contracts are fixed per kind; if a kind is not defined there, it is not recorded.
The envelope looks like this:
{ "id": "1042", "type": "device.offline", "tenantId": "…", "createdAt": "2026-09-04T21:00:00.000Z", "data": { "deviceId": "…", "name": "Hall sensor", "at": "…", "reason": "heartbeat" } }Use id to resume reads, and treat createdAt as the event timestamp exposed to your code.
Webhooks
Section titled “Webhooks”Create a webhook with POST /developers/webhooks and include url, events, and optional description. The endpoint is bound to one of your developer keys: by default it uses the newest active DEV key, unless you supply keyId. The key determines scope. A DEV key receives events for its sandbox tenant. A LIVE key receives events for every tenant that installed its connector.
The URL must be https on the hosted platform. A self-hosted operator can allow http only with ALLOW_PRIVATE_RUNTIMES=true for private-network delivery.
When the webhook is created, the response includes the signing secret once. Store it immediately; it is not shown again.
Each delivery is a POST to your URL with the envelope as JSON and these headers:
| Header | Value |
|---|---|
X-ALYT-Event | the event kind |
X-ALYT-Delivery | the delivery id, unique per attempt series |
X-ALYT-Signature | t=<unix seconds>,v1=<hex hmac-sha256(secret, "<t>.<body>")> |
Verify the signature over t.body with your secret and reject timestamps older than five minutes. A 2xx response within 10 seconds counts as delivered. Anything else is retried on a doubling schedule: 30 s, 1 min, 2 min, then doubling up to 1 hour, for 20 attempts over one day. After 50 consecutive failures, the endpoint is disabled and the developer is notified; you can re-enable it from the dashboard.
POST /developers/webhooks/:id/test queues a webhook.ping. GET /developers/webhooks/:id/deliveries shows the last fifty deliveries with status, attempts, response code, and the signed payload. The dashboard also lets you remove an endpoint or re-enable a disabled one.
Stream
Section titled “Stream”Use GET /developers/events/stream?events=device.online,device.offline&after=1042 for Server-Sent Events. The response stays open for up to one hour, and the gateway keeps the route alive. Events arrive as event: <kind>, id: <id>, and data: <envelope>, with a comment every 15 seconds to keep the connection alive.
The stream is filtered by the key’s tenants and the events:read scope. A session only sees its sandbox. If the connection drops, resume with after=<id> from the last event you processed.
Access boundaries
Section titled “Access boundaries”Access follows the key that owns the endpoint. Household permissions are narrower than staff. DEV credentials act in the developer sandbox. LIVE credentials only hear events for their own installed connector.
Cloud-dependent connectors still need the provider and network path to be available. Local functions can keep working during a cloud outage, but webhook delivery and the event stream depend on the platform path being reachable.
What to expect in practice
Section titled “What to expect in practice”Use webhooks when your server needs push delivery, retries, and per-attempt records. Use the stream when you want ordered reads and a simple resume token. In both cases, the platform records the event once in the outbox, delivers the same envelope, and exposes the same event id so you can correlate webhook deliveries with streamed events.