Video APIv1 Home OpenAPI spec

Docs › Webhooks

Webhooks

Get notified when videos finish or fail, and when you're approaching your plan's limits. Set up a webhook endpoint (URL) in the web app on your Account → Webhooks page, or with the API:

  • GET /webhook — your current configuration.
  • PUT /webhook {url, events?, enabled?} — save or update an endpoint.
  • DELETE /webhook — remove the endpoint.
  • POST /webhook/rotate — generate a new signing secret (keep the URL).
  • POST /webhook/test — send a test event and report the result immediately.
  • GET /webhook/deliveries — the last 30 days of delivery attempts.

Events

Each account has one endpoint that receives events for all types it's subscribed to. The possible events are:

EventSent whenData
video.readyProcessing succeeded.videoId, fileName, statusPath, metadata (if set), durationSeconds, downloadUrl (valid 1 hour), downloadExpiresInSeconds, posterUrl, playbackUrl, posterPlaybackUrl and playbackExpiresAt (locked to your allowed domains), streamUrl and streamExpiresAt if streaming, captions if made with captions, and status.
video.failedProcessing failed or timed out.videoId, fileName, statusPath, metadata, status: FAILED or TIMED_OUT.
video.canceledProcessing was aborted.videoId, fileName, statusPath, metadata.
video.deletedA video was deleted.videoId, fileName, statusPath, metadata.
usage.threshold80% or 100% of your plan's monthly limits is reached (once each per month).measure (minutes, storage or delivery), percent (80 or 100), used, included (plan's allowance), month (YYYY-MM), plan (your plan name), overage (whether you'll be billed for excess).

Webhook envelope

Every event arrives as JSON with metadata about the event:

{
  "id": "evt_a1b2c3d4e5f6g7h8",
  "type": "video.ready",
  "createdAt": "2025-01-15T14:30:45Z",
  "data": { event-specific data }
}

Signature verification (Standard Webhooks)

Each delivery includes headers webhook-id, webhook-timestamp and webhook-signature that implement the Standard Webhooks specification, so libraries for any language can verify them:

// npm install standardwebhooks
import { Webhook } from "standardwebhooks";

const wh = new Webhook(webhookSecret);  // your secret from the account page
try {
  const payload = wh.verify(body, {
    "webhook-id": req.headers["webhook-id"],
    "webhook-timestamp": req.headers["webhook-timestamp"],
    "webhook-signature": req.headers["webhook-signature"],
  });
  // payload is the parsed event; proceed
} catch (err) {
  res.status(401).send("Unauthorized");
}

Reliability and delivery

  • Respond 2xx within 10 seconds. Your endpoint must be HTTPS and reachable from the public internet. Redirects (3xx) are not followed.
  • Retry policy: if you don't answer 2xx or timeout, delivery is retried after 1 minute, 5 minutes, 15 minutes, 1 hour, 3 hours, 6 hours and 12 hours (8 attempts over ~22 hours).
  • At-least-once delivery: events may arrive more than once. Deduplicate using the webhook-id header (unique per event). Events may arrive out of order; use timestamps if order matters.
  • Delivery log: check GET /webhook/deliveries to see recent attempts, their status codes, response bodies and errors (kept for 30 days).

URL safety

Webhook URLs must be HTTPS and resolve only to public internet addresses. Private addresses (like 10.0.0.1, 192.168.1.x, 127.0.0.1, localhost or cloud-internal networks) are rejected when you save the URL or on every delivery attempt. This protects you from SSRF attacks. Redirects are never followed; the URL you set is the URL we connect to.