Subscribe to events with webhooks
Instead of polling GET /deployments/{id} to find out when a deployment changes state, register a webhook: Ring POSTs to your endpoint every time a subscribed event fires. Deliveries go through a durable queue with retry, so a brief outage on your side doesn't drop events.
Register a webhook
ring webhook create https://hooks.example.com/ring --event deployment.status_changed
Ring prints the webhook id on stdout and, on stderr, the generated signing secret, which is shown once:
Webhook registered for https://hooks.example.com/ring events: deployment.status_changed secret: whsec_3f9a… (copy it now — not shown again) 9f1c2d3e-…
Omit --event to receive every event kind. Pass --secret <value> to use your own secret instead of a generated one.
Managing webhooks needs an API token with the webhooks:write scope (see API tokens).
Receive and verify a delivery
Each delivery is a JSON POST with these headers:
X-Ring-Event: deployment.status_changed: the event kindX-Ring-Signature: sha256=<hmac>: HMAC-SHA256 of the raw body, keyed by your secret (only when the webhook has a secret)
Verify the signature before trusting the body. In Python:
import hmac, hashlib def verify(secret: str, body: bytes, header: str) -> bool: expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, header)
The body for deployment.status_changed:
{ "schema_version": 1, "deployment_id": "f3a8b2c4-...", "namespace": "production", "name": "web", "kind": "worker", "old_status": "creating", "new_status": "running", "restart_count": 0 }
Respond with any 2xx to acknowledge. A non-2xx (or a timeout) makes Ring retry with exponential backoff; after repeated failures the event is dead-lettered and stops being retried.
Other event kinds
deployment.status_changed is the headline event, but Ring emits more. Subscribe to all of them by omitting --event, or pick specific ones (--event is repeatable):
deployment.health_check_failed: a probe failed and itson_failureaction (restart / stop / alert) fireddeployment.rolling_update: a rollout drained an instance, completed, or faileddeployment.scaled: the reconciler added or removed an instancedeployment.error: the runtime couldn't bring a deployment up, with areasonand acategory(user/host/transient)
See API reference → Webhooks for each payload, and Deployment status lifecycle for how these relate to a deployment's status.
Idempotency
Delivery is at-least-once: on a retry, an event your endpoint already processed may arrive again. Key your handling on deployment_id + new_status (or carry your own dedup) so reprocessing is a no-op.
List and remove
ring webhook list ring webhook delete <ID>
list shows each webhook's URL, subscribed events and status (active/revoked); secrets are never shown. delete stops further deliveries.