GET /api/v1/apps/{uuid}/deployments.
Webhooks are workspace-level. Manage them under Workspace → Settings → Developers, or over the API at /api/v1/webhooks. Both require the workspace:general permission (workspace admins).
Events
Subscribe to any of them. There is no separate build event: on Miget the build and the deployment are one lifecycle, so a build finishing is the deploy ending.
app_stopped and app_state_changed are not the same thing. The first is the platform giving up on an app that keeps crashing; the second is a person starting, stopping, or restarting one. Subscribe to both if you want to hear about a stop however it happened.
quota_alert belongs to the workspace rather than to any one app, so it reaches every subscribed webhook regardless of app scoping. Every other event carries data.app_id and respects it.
Static site deployments fire the same events, with data.app_id set to the site’s UUID. A zip or SFTP deploy carries no commit, so the commit fields come back null.
Payload
Scoping to Specific Apps
By default a webhook receives events from every app in the workspace, including apps created later. Narrow it by selecting apps in the dashboard, or by passingapp_uuids over the API; an empty list widens it back to the whole workspace. The apps must belong to the same workspace.
Either way the payload carries data.app_id, so a consumer can filter on its own as well.
Preview Environments
A preview environment is created as an app in its own right, with its own UUID. Listing its parent underapp_uuids therefore does not cover it, and a narrowed webhook stays silent while pull requests deploy.
Turn on Also send events from preview environments in the dashboard, or pass include_review_apps: true, to have those events matched against the parent as well. It is off by default, so no existing webhook starts receiving pull-request traffic on its own. A webhook scoped to the whole workspace already receives it - worth knowing before pointing one at a busy repository.
Verifying a Delivery
Deliveries follow the Standard Webhooks specification, so any Standard Webhooks library verifies them as-is. Three headers accompany every POST:
The signature is
HMAC-SHA256(key, "{webhook-id}.{webhook-timestamp}.{body}"), base64-encoded, where key is the base64-decoded part of the secret after the whsec_ prefix.
Testing an Endpoint
Use Send test in the dashboard, orPOST /api/v1/webhooks/{uuid}/test, to POST a signed event to the URL immediately and get the result back. It is signed exactly like a real delivery, so it exercises your signature verification too, and it works on a webhook that is still disabled.
The test event carries "type": "ping" with an empty data object. ping is deliberately not one of the subscribable event types, so a consumer that rejects unknown types will fail the test even though the endpoint is otherwise fine - accept ping explicitly, or ignore types you do not recognise.
The API call responds 200 whether or not your endpoint accepted the event; read status and response_code on the returned delivery.
Retries
A non-2xx response is retried with exponential backoff over roughly 24 hours - 9 attempts in total, spaced 30s, 2m, 8m, 30m, 1h, 3h, 8h, and 12h apart with jitter. Make your endpoint idempotent and deduplicate on the eventid: it is stable across automatic retries and across manual replays.
When an endpoint keeps failing
After three consecutive failed deliveries - each one having already exhausted its own retries - the webhook is disabled and stops being sent to. Miget emails the workspace admins to say which endpoint was turned off and why. Nothing is lost quietly: the deliveries that failed stay in the delivery history with their status codes, and re-enabling the webhook in the dashboard resumes deliveries from the next event. A single failure that later succeeds resets the count, so an endpoint that recovers on its own is never disabled.Delivery History
Every event records one delivery entry, updated in place across retries. The webhook card lists the most recent ones, and the full history opens in a dialog; the same data is available atGET /api/v1/webhooks/{uuid}/deliveries.
Each entry carries:
status-pending,delivered, orfailedattempts- how many times it has been triedresponse_codeandmessage- what your endpoint returned (the transport error when nothing came back)payload- the exact JSON body that was POSTed, so you can compare it with what you received
POST /api/v1/webhooks/{uuid}/deliveries/{delivery_uuid}/retry - it replays the stored payload under the original event id.
Destination Requirements
The endpoint must be publicly reachable. A URL pointing into private address space - loopback, RFC1918, link-local (including169.254.169.254), CGNAT, or the localhost, .local, and .internal hostnames - is rejected.
The hostname is re-resolved before every delivery, so a name that later starts resolving to a private address stops being delivered to rather than being retried.
Developing locally? Expose your endpoint with a tunnel (see ngrok) and register the public URL.
Next Steps
Logs
Search and filter application logs
Metrics API
Query metrics programmatically

