job.succeeded, job.failed or job.cancelled, for generation, render, dub and transcription jobs, with workspace_id naming the workspace. Endpoints belong to the account, and any credential of the account manages them.
Registering
POST /api/v1/webhooks with url, an optional description, and event_types to subscribe to some events. When event_types is omitted, the endpoint receives all three. The URL must be HTTPS and publicly reachable; a private or loopback address is refused. PATCH /api/v1/webhooks/{id} changes an endpoint, or with test: true sends one ping now. GET lists endpoints and DELETE removes one.
Payload
timeline_id appears on a language change. The event id is derived from the job and the event type, so a delivery seen twice is the same event.
Signature
Every delivery carriesEversince-Signature: t=<unix seconds>,v1=<hex>, where v1 is the HMAC-SHA256 of <t>.<raw body> with the account’s signing secret. Two v1 values appear while a secret is being rotated, and either verifies. Eversince-Event, Eversince-Delivery and Eversince-Attempt carry the event type, the event id and the attempt number.
The secret is per account and signs every endpoint the account owns. GET /api/v1/webhook-secret reads it. POST creates it, or with rotate: true issues a new one while the old one keeps verifying for 24 hours. DELETE removes it. A script session cannot reach this route.
Delivery
A delivery succeeds on a 2xx within 10 seconds. Redirects are not followed, so register the final URL. A failed delivery is retried after 1, 5, 30, 120, 360, 720 and 1440 minutes, eight attempts in all. After 20 consecutive failures an endpoint disables itself, and enabling it again clears the count.GET /api/v1/webhooks/{id}/deliveries is the log, newest first, with the status code and error the receiver returned. POST with a delivery_id sends that delivery again from the first attempt.
