Webhooks are how Amps pushes events to you. When an action reaches a terminal state or a device’s connection status changes, a signed HTTP POST lands on your registered endpoint. Delivery is retried with exponential backoff; endpoints are managed from the dashboard. Subscribe to anything you would otherwise poll. Polling is the right default for dashboards where the user accepts visible cache freshness. Events are the right default for any state change a user is waiting on. Pick once at integration time and the rest of the design follows. Events are also how you give end users fast feedback. A user waiting for a charge to start expects the UI to update when the device confirms; a polling cadence that runs every minute can’t deliver that.Documentation Index
Fetch the complete documentation index at: https://docs.amps.ai/llms.txt
Use this file to discover all available pages before exploring further.
Event taxonomy
Two categories exist. Lifecycle events track device connection state. Push-action events track command outcomes.| Event | Category | When it fires |
|---|---|---|
device.connected | Lifecycle | A new device finishes registration via the Auth Journey. |
device.reconnected | Lifecycle | An existing device’s credentials are refreshed. |
device.disconnected | Lifecycle | Stored credentials become invalid. May carry a reconnectionUrl when the OEM’s auth flow supports re-entry. |
push.completed | Push | The OEM accepted the command. The action is in completed. |
push.failed | Push | The OEM rejected, or a transient failure exhausted the path. The action is in failed. |
schedule.created, schedule.updated, schedule.cancelled, schedule.slot_failed, schedule.slot_skipped) flow through the same delivery path. They are documented under scheduling.
completed means the OEM API accepted the command, not that the device verified end-state. Verifying end-state would mean polling the OEM after every command, doubling latency without telling you anything the next pull cannot. Tail the device pull or wait for a state-change webhook if end-state confirmation matters.Payload shape
Webhook bodies are flat; the event type is delivered in headers (svix-id, svix-timestamp, svix-signature) rather than in the body.
Lifecycle events carry the device identifiers:
device.disconnected may add a reconnectionUrl pointing at the Auth Journey in reconnection mode, when the OEM’s auth flow supports re-entry:
Delayed delivery
Webhook delivery is delayed by a fixed interval after the trigger:| Environment | Delay |
|---|---|
| Live | 10 seconds |
| Sandbox | 180 seconds |
Retries
A 2xx from your endpoint marks the delivery successful. Anything else triggers a retry on a backoff schedule. The retry policy and delivery history are configurable from the dashboard. Idempotency on your side is mandatory. Treat each event as potentially deliverable more than once. Dedupe byactionId for push events and by deviceId plus type plus timestamp for lifecycle events.
Signature verification
Every webhook carries three headers (svix-id, svix-timestamp, svix-signature). Verify the signature before processing; the SDK reads all three. The signature is computed over the raw request body; verifying after JSON parsing or whitespace normalisation will fail.
Endpoint configuration
You get a separate webhook consumer per environment. Webhook delivery targets the consumer matching the API key that produced the event. Sandbox events go to your sandbox consumer; live events go to your live consumer. Configure endpoints from the dashboard’s webhook settings. Multiple endpoints per environment are supported. Each endpoint is delivered independently, so failing one does not affect the others.Operational behaviour
A few specifics worth knowing:| Scenario | Behaviour |
|---|---|
| Push action delivered while still in a non-terminal state | Skipped at the delivery step; the task is acknowledged. |
| Action ID present in the task but absent from storage | Same as above. Logged and acknowledged. |
Pull failure with INVALID_CREDENTIALS | Emits a device.disconnected lifecycle webhook in addition to whatever the operation produced. |
Push failure with INVALID_CREDENTIALS | Emits both a push-action webhook and a device.disconnected lifecycle webhook. |
| Webhook delivery URL not configured | Push and pull operations complete without error; no webhook is scheduled. The misconfiguration is logged. |
What webhooks do not do
- No per-event-type filtering at the subscription level. Every endpoint receives every event in scope. Dispatch from your handler.
- No batch delivery. Each event is one HTTP request.
- Replay is exposed through the dashboard rather than an in-product UI.
Sandbox vs live
Sandbox webhooks let you test your handler before you have a live device. Simulated devices emit realistic action lifecycle events. The 3-minute sandbox delay covers initial wiring; the 10-second live delay matches production once you switch keys. The same delivery infrastructure backs both environments: same signature scheme, same retry behaviour, same payload shape. Switch from sandbox to live by switching the API key and updating the consumer endpoint. Your handler logic does not need to change.Frequently asked questions
How quickly are webhooks delivered after an action completes?
Live webhooks land roughly 10 seconds after the action reaches its terminal state. Sandbox webhooks land after 180 seconds. Webhook delivery is isolated from the dispatch path, so webhook volume does not affect command latency. The sandbox delay exists for developer ergonomics: it gives you time to set up a tunnel and an endpoint between submitting the action and the webhook landing.What happens if my webhook endpoint is down?
The platform retries on a backoff schedule. A 2xx from your endpoint marks the delivery successful; anything else triggers retry. The retry policy and visible delivery history are configurable from the dashboard. Persistent failures eventually exhaust the retry budget and stop. Idempotency on your side is mandatory: treat each event as potentially deliverable more than once. Dedupe byactionId for push events and by deviceId plus type plus timestamp for lifecycle events.
How do I verify a webhook signature?
Every webhook carries ansvix-signature header computed over the raw request body. Verify before processing using the Svix SDK or its equivalent in your language. The signature is computed over raw bytes, so verifying after JSON parsing or whitespace normalisation will fail. The webhook secret is per-endpoint and surfaced in the dashboard. Rotate it from the dashboard; rotation does not affect your API key. Never process webhooks without verifying signatures.
What does completed mean in a push.completed webhook?
It means the OEM API accepted the command, not that the device verified end-state. Verifying end-state would require polling the OEM after every command, doubling latency without adding value the next pull cannot deliver. Tail the device pull or wait for a state-change webhook if end-state confirmation matters. The webhook payload is loaded fresh at delivery time, so it reflects the latest truth on delivery.Can I filter which events my endpoint receives?
Not at the subscription level. Every endpoint receives every event in scope. Use your handler to dispatch on the event type from thesvix-id and headers. Multiple endpoints per environment are supported and each is delivered independently; failing one endpoint does not affect delivery to the others. Filtering, batching, and replay are exposed through the dashboard.
Related concepts
Scheduling
Action lifecycle states that produce webhooks.
Auth Journey
device.connected fires when registration completes.Webhook Security
Signature verification reference.
Device State
Polling versus webhook patterns for state changes.