Skip to main content
A webhook is a small JSON message we POST to your server when something happens to a video — for example, when encoding finishes and the video can play. Use a webhook instead of polling the video route again and again.
Status: Available. Video events are live. See Feature status.
This page shows the events we send, the payload, how to check the Segmnt-Signature header, and what your receiver must do.

Events we send

Subscribe only to the events you handle. We send an event only to the endpoints that subscribed to it.

Are videos held, and does a bulk import change it?

A video can be held for review. A held video does not play, and we send video.held; when the hold ends we send video.ready again.
  • The free-plan review hold is Coming soon and off today, so a new video is not held for it. A paid plan (Starter, Pro and Agency) is never held for it.
  • A team hold, or a video the automatic check flags, can affect any plan. See Moderation and held videos.
  • A bulk import has no separate rule. Every video in the import is one upload, so the same rule above applies to each one.

Create and manage endpoints

Status: Available. Today you create endpoints with the API. The dashboard screen for webhooks is Coming soon. See Feature status.
Add an endpoint:
The answer is 201:
Rules: If you lose the signing secret, delete the endpoint and add a new one. The old secret keeps working until you delete the endpoint. Secret rotation without recreating the endpoint is Coming soon.

The payload

Every event is one JSON object:
  • id — the event id. It is the same on every retry of the same event. Use it to skip duplicates.
  • type — the event name, from the table above.
  • createdAt — when we created the event. RFC 3339 in UTC.
  • projectId — the project the video belongs to.
  • data.video — the same object as GET /v1/projects/{projectId}/videos/{videoId}. Use data.video.id to find the video in your system.
  • data.reason — only on video.held and video.removed, and only when we have a reason to give.

Verify the signature

Every delivery carries a Segmnt-Signature header. It is the only way to know the request really came from us. Do not trust a webhook without checking it.
  • t is the Unix time in seconds of this delivery attempt.
  • v1 is the HMAC-SHA256 of the string <t>.<raw body>, in hex.
  • The key is your signing secret, used exactly as shown. The whsec_ prefix is part of the key, and the key is read as UTF-8. Do not decode it and do not strip the prefix.
To check a delivery:
  1. Split the header on t= and v1=.
  2. Refuse the request if t is more than 5 minutes old, or in the future.
  3. Compute HMAC-SHA256 over <t>.<raw body>. Use the raw body bytes, not the parsed JSON.
  4. Compare your result with v1 in constant time. A simple == is not safe.
The Node.js example below does all four steps. It reads the raw body first and does not call JSON.parse until after the signature is valid.

How to handle deliveries

video.ready, video.failed, video.held and video.removed are delivered in the same way.
  • Answer fast. Return any 2xx status within 10 seconds. Do the real work after you answer, for example in a queue. A slow answer looks like a failure.
  • At least once. The same event can arrive more than once. Every delivery is “at least once”: id, type, createdAt and the body are the same on each try, but t and the signature are new. Dedupe on id and ignore an event you have already processed.
  • Not in order. Events can arrive out of order. Ignore an event whose data.video.updatedAt is older than the one you stored, or read the video again with GET /v1/projects/{projectId}/videos/{videoId} for the current state.
  • Retries. Any answer that is not 2xx, or no answer, means a retry. We retry with a growing wait, up to about 8 tries, then mark that delivery failed.

Rotate, inspect and test (Coming soon)

Status: Coming soon. The three calls below are planned. They are not live today, so do not build on them yet. We add them to the API reference when they ship.

Rotate the signing secret

Returns a new whsec_... once. The endpoint, its URL and its event list stay the same. The old secret stops working as soon as the call returns, so update your server with the new secret before you call this route.

Read the delivery log

Newest first. Each row has the event type, the time we created it, the status (pending, delivered or failed), the number of attempts, and the last HTTP status your endpoint returned. limit sets the page size (1 to 100, default 20). For the next page, pass the nextCursor value back as cursor.

Send a test event

Queues one signed webhook.test event to that endpoint. It uses the same signature header as every other event, and the result appears in the delivery log. The body we POST to your endpoint is:

Also coming soon

  • A dashboard screen to add, list and remove endpoints, and to show the signing secret once.
  • A “send test event” button in the dashboard.

Test your endpoint today

To test your endpoint today, register your own HTTPS receiver and upload a short video. Watch for the video.ready POST and check the signature with the code above. To test video.failed, upload a file that is not a video (for example a .txt file renamed to .mp4).

Where to go next

  • API overview — the base URL, authentication, and every endpoint. The webhook endpoints are in the “Webhooks, usage and billing” list, and under Webhooks in the API reference.
  • Direct upload — upload a video, then wait for the event.
  • Feature status — which features are Available, Beta or Coming soon.