webhook URL when you submit a request and ModelRunner POSTs the result to it when the request settles. No polling loop, no long-lived connection, and nothing lost if your process restarts mid-request.
Best for server-to-server integrations and long jobs (video, training). For a browser UI that shows several requests at once, the SSE stream is usually a better fit.
Attaching a webhook
Add the reserved top-levelwebhook key to the submit body, alongside the model’s own input fields:
The create response echoes both back so you can confirm they were accepted.
Events
start is best-effort — never block on it. A fast request can go from IN_QUEUE straight to a terminal state between two provider polls, in which case only completed is delivered. This is inherent to how status is observed, not a bug.output or logs events: ModelRunner does not stream partial output into the request record, so there is nothing to emit them from. Use completed and read the payload.
The payload
The body is the same objectresponse_url returns, plus event and billingStatus. One shape to learn.
metadata you attached at submit time is echoed back, which is the easiest way to correlate a delivery with your own records without a database lookup.
Verifying a delivery
Every delivery is signed using Standard Webhooks, so you can verify it with an off-the-shelf library rather than hand-rolled crypto. Three headers are sent:Get your signing secret
Verify with a library
Verify manually
If you would rather not add a dependency: HMAC-SHA256 over{webhook-id}.{webhook-timestamp}.{rawBody}, keyed by the base64 portion of the secret after the whsec_ prefix.
Retries and idempotency
A delivery succeeds on any2xx returned within 15 seconds. Anything else — including a 3xx, since redirects are not followed — counts as a failure and is retried on a fixed schedule:
410 Gone, and a URL that resolves to a private address.
Requirements for your endpoint
- HTTPS, on a publicly resolvable host. Private, loopback, link-local and internal addresses are rejected — both when you submit and again at delivery time against the resolved address.
- Respond
2xxwithin 15 seconds. Acknowledge first and process asynchronously; do not do the work inside the request. - Redirects are not followed. Point the webhook at its final URL.
Inspecting deliveries
status (pending, delivering, delivered, failed), attempts, lastResponseStatus and lastError — enough to tell a broken endpoint from a broken payload.

