Know when the video is ready.
Create a destination
Open Webhooks in the console, register your public HTTPS receiver and select the render events you need. Save the signing secret when it is shown. Use “Send test” to check connectivity, then inspect the delivery log for the receiver’s actual response.
/v1/webhooks endpoint. The webhooks.manage scope is reserved; it does not turn an API key into a console session. AI generation completion events are not currently offered—poll the generation job.Verify before processing
Vidmoat sends Vidmoat-Event-Id, Vidmoat-Event-Type and Vidmoat-Signature. The signature has the form t=TIMESTAMP,v1=HEX_HMAC. Compute HMAC-SHA256 over the timestamp, a period, and the exact raw request bytes. Do not parse and reserialize JSON before verification.
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(rawBody, signature, secret) {
const t = /(?:^|,)t=(\d+)(?:,|$)/.exec(signature)?.[1];
const mac = /(?:^|,)v1=([a-f0-9]{64})(?:,|$)/.exec(signature)?.[1];
if (!t || !mac) return false;
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = createHmac('sha256', secret)
.update(t + '.').update(rawBody).digest();
const received = Buffer.from(mac, 'hex');
return received.length === expected.length &&
timingSafeEqual(received, expected);
}
// Verify rawBody first. Then JSON.parse it and deduplicate event.id.Acknowledge quickly and deduplicate
Return a 2xx response after safely accepting an event. Store its ID and avoid processing a repeated delivery twice. Transient failures are retried; ordinary 4xx responses are not, except 408 and 429. Repeated delivery failures can disable a destination; the console shows the reason. Fix the receiver, test it and re-enable the destination.
Keep a recovery path
Use bounded polling of GET /v1/renders/{id} to reconcile a missing notification. Stop on terminal errors and honour rate limits. Do not queue another render just because a notification has not arrived.
v1 — new fields, new endpoints, new enum values. Ignore unknown fields; a client that rejects them can break on a routine release. The Vidmoat-Version header defaults to 2026-08-01 and is echoed back; it is reserved for future versioning and does not currently select different behaviour.