Agent skill
Vimeo Webhooks Skill
Receive and verify Vimeo app webhooks. Use when setting up Vimeo webhook handlers, debugging X-Webhook-Signature verification, or handling video events like video-transcode-complete, video-deleted, video-upload-failed, and live-event-started.
Install this skill
npx skills add hookdeck/webhook-skills --skill vimeo-webhooks
When to Use This Skill
- How do I receive Vimeo webhooks?
- How do I verify the Vimeo
X-Webhook-Signatureheader? - Why does my Vimeo webhook signature verification fail, or why are deliveries unsigned?
- How do I handle
video-transcode-complete,video-deleted, orlive-event-startedevents? - How do I set a
secreton a Vimeo webhook through the API?
Verification (core)
Vimeo signs a delivery only if the webhook has a secret set. The X-Webhook-Signature header is the lowercase hex HMAC-SHA256 of the raw request body, keyed with that secret. There is no timestamp in the signed content and no prefix on the header value.
Node (check the format first: Buffer.from(x, 'hex') silently truncates invalid hex):
const crypto = require('crypto');
function verifyVimeo(rawBody, signature, secret) {
if (!signature || !/^[0-9a-f]{64}$/i.test(signature)) return false;
const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
// Equal-length lowercase hex strings, compared in constant time
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature.toLowerCase()));
}
Python (encode both sides to bytes so a non-ASCII header returns 401, not 500):
import hashlib, hmac
def verify_vimeo(raw_body: bytes, signature: str | None, secret: str) -> bool:
if not signature:
return False
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected.encode(), signature.lower().encode())
For complete handlers with route wiring, event dispatch, and tests, see:
- examples/express/ (read the body with
express.raw({ type: '*/*' })so any content type verifies)- examples/nextjs/
- examples/fastapi/
Setup: set a secret on the webhook
Vimeo has no dashboard for app webhooks; you create them through the API (POST /apps/{app_) and set secret in the same request, or later with PATCH /apps/{app_. Vimeo recommends a random string of at least 64 bytes. Set a secret on the webhook through the Vimeo API. Without one, deliveries are unsigned and fail verification (whether in your handler or in a Hookdeck source with verification on). See references/setup.md for the requests.
For Hookdeck, create a source of type Vimeo and paste the same secret as its webhook signing secret.
Common Event Types
The event name is in the body's webhook_type field (not a header). Payloads look like { "webhook_.
Event (webhook_type) | Fires when |
|---|---|
video-created | A user creates a video |
video-deleted | A user deletes a video |
video-transcode-playable | A video is ready for playback |
video-transcode-complete | A video finished transcoding |
video-upload-failed | A video upload fails |
transcript-status-complete | A video's transcript completed or failed |
live-event-started | A live event goes live |
live-event-ended | A live event ends |
Other documented types: live-event-updated, live-event-archive-available, live-event-clip-created, video-transcode-fully-playable, automatic-thumbnail-available, content-scan-completed, registration-created, registration-updated, registration-deleted.
For the full event reference, see Vimeo app webhooks and references/overview.md.
Important Headers
| Header | Description |
|---|---|
X-Webhook-Signature | Hex HMAC-SHA256 of the raw body; only sent when the webhook has a secret |
Content-Type | Content type of the payload body |
Vimeo documents no delivery ID header. See references/overview.md for deduplicating.
Environment Variables
VIMEO_WEBHOOK_SECRET=your_webhook_secret # The `secret` you set on the webhook via the Vimeo API
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 vimeo --path /webhooks/vimeo
Reference Materials
- references/overview.md - Vimeo webhook concepts, events, payloads
- references/setup.md - Creating the webhook and its secret through the API
- references/verification.md - Signature verification details and gotchas