Skip to main content
A webhook endpoint receives an event when a twin or a batch changes status. Events are signed per the Standard Webhooks specification, so any Standard Webhooks library can verify them.

The webhook endpoint object

Create a webhook endpoint

POST /v1/kennet/webhook_endpoints Creates a webhook endpoint. Send JSON.
Returns 201 with a webhook_endpoint object, including secret. Store the secret; it is not returned again. To rotate it, create a new endpoint and delete the old one. Endpoints are scoped to an organization and mode. Test-mode endpoints receive only test-mode events.

List webhook endpoints

GET /v1/kennet/webhook_endpoints Lists webhook endpoints, newest first. Returns {object: "list", data, has_more, url}, with webhook_endpoint objects in data, without secret.

Delete a webhook endpoint

DELETE /v1/kennet/webhook_endpoints/{id} Deletes a webhook endpoint and drops its pending deliveries. Returns {id, object: "webhook_endpoint", deleted: true}, or 404 resource_missing.

The event object

Event types

Twins in a batch send their own kennet.twin.completed and kennet.twin.failed events. Their pauses and cancels are their batch’s: kennet.batch.paused, kennet.batch.resumed and kennet.batch.cancelled.

The balance object

Delivery and retries

Each event is sent as a POST with the event as a JSON body and these headers: Respond with a 2xx status within 10 seconds. Any other response, a redirect or a timeout is a failed attempt. Failed attempts are retried after 1 minute, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours and 6 hours: 8 attempts over about 24 hours. Delivery is at least once, in no guaranteed order. Deduplicate on webhook-id. For current state, retrieve the twin or batch.

Verify a signature

The signature is an HMAC-SHA256 over <webhook-id>.<webhook-timestamp>.<body>, keyed by the base64-decoded secret without its whsec_ prefix.
  1. Compute the signature over the raw body, before parsing it.
  2. Compare it in constant time with each v1, entry in webhook-signature (space-separated).
  3. Reject timestamps more than 5 minutes from your clock.
Both examples expect lowercase header names.