Webhooks overview

Webhooks are how asynchronous outcomes reach you. Rendering is fire-and-forget — POST /videos/render/{videoId} returns before validation runs — so a webhook is the only push notification that a video finished or failed.

Events

There are exactly two:

EventTriggered when
video_readyThe video's status changes to ready
video_errorThe video hit a validation or rendering error

📘

Moderation is not a webhook event

A video sent to moderation does not emit anything. If you need to observe that state, poll
GET /videos/{videoId} and read status.

Payload

Each delivery is a POST with these headers:

HeaderMeaning
Delivery-IDUnique per delivery attempt. Log it — it is what support will ask for
Elai-TimestampMilliseconds since the epoch, sent only when a signing secret is set
Elai-SignatureHMAC-SHA256 of the delivery, sent only when a signing secret is set
{
  "event": "video_ready",
  "error": null,
  "video": {
    "_id": "627e1c5ef461482766f35f4a",
    "name": "Hello John!",
    "status": "ready",
    "public": false,
    "deleted": false,
    "tags": ["api"],
    "userId": "61b1529d2055d2805c0",
    "accountId": "61b1529d2055d2805c",
    "duration": 3.456,
    "data": {},
    "thumbnail": "https://elai-media.s3.eu-west-2.amazonaws.com/videos/627e1c5ef461482766f35f4a/thumbnail.jpg",
    "url": "https://elai-media.s3.eu-west-2.amazonaws.com/videos/627e1c5ef461482766f35f4a/hello-john.mp4",
    "createdAt": "2022-08-25T09:25:56.228Z",
    "updatedAt": "2022-08-26T09:40:03.337Z"
  }
}
FieldDescription
eventvideo_ready or video_error
errorOn video_error, a summary of what went wrong. null otherwise
requestIdPresent only for videos created through the Personalization API — the id returned by POST /videos/renderTemplate/{videoId}
batchRowIdPresent only for Personalization API videos — this video's index within the batch
videoThe video document

Delivery is a single attempt

This is the part worth reading twice.

We send one POST and wait up to 10 seconds for a 2xx. There is no retry, no backoff and
no dead-letter queue. If your endpoint is down, slow, or returns a 500, that event is gone
it is not redelivered when you recover.

The failure counter is about your subscription, not about one event:

  • Each failed delivery increments a counter and emails your techEmail.
  • After 10 failed deliveries the webhook is disabled. That is ten separate lost events, not
    ten attempts at one.
  • Re-enable by subscribing again with POST /webhook, or from your
    API settings page.

So if you cannot afford to miss a video_ready, do not rely on the callback alone. Reconcile
periodically with GET /videos, filtering on status, and treat the webhook as
the fast path rather than the source of truth. Returning 2xx immediately and processing the
payload afterwards also helps — a slow consumer is indistinguishable from a broken one after 10
seconds.

Verifying that a delivery came from us

Set a signing secret and check the signature on every request. See
Set secret token for a working verifier — and note the ordering
trap: the secret is only stored if a webhook is already enabled.