← API docs
Webhooks
We deliver job results to your endpoint with an HMAC signature so you can verify origin.
Events
video.ready— generation succeeded; payload includesid,doSpacesUrl,previewUrl,aspectRatio.video.failed— generation failed; payload includesidanderrormessage. Tokens are auto-refunded.
Payload example — video.ready
POST https://your-app/webhooks/gvm
Headers:
Content-Type: application/json
X-GVM-Event: video.ready
X-GVM-Delivery: 7c6e1f31-5d53-4f1e-89a4-6a2bdb1d0f47
X-GVM-Signature: t=1714560000,v1=8b2… (HMAC-SHA256, hex)
Body:
{
"id": "vid_01HW…",
"status": "READY",
"prompt": "A golden-hour drone shot…",
"doSpacesUrl": "https://nyc3.cdn.digitaloceanspaces.com/…/video.mp4",
"previewUrl": "https://nyc3.cdn.digitaloceanspaces.com/…/preview.jpg",
"aspectRatio": "16:9",
"createdAt": "2026-04-16T10:42:31.413Z"
}Verifying the signature
The X-GVM-Signature header is built as t=<unix-ms>,v1=<hex>. Compute the expected signature with the webhook secret you stored when creating the endpoint:
// Node
const crypto = require('crypto')
const [tPart, vPart] = req.header('X-GVM-Signature').split(',')
const t = tPart.split('=')[1]
const v1 = vPart.split('=')[1]
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(t + '.' + JSON.stringify(req.body))
.digest('hex')
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))) {
return res.status(401).send('bad signature')
} Reject any payload whose t is older than 5 minutes to defeat replay attempts.
Retries
Non-2xx responses are retried with exponential backoff up to 8 attempts over ~24h. A persistent failure disables the endpoint and emails the account owner.