Webhooks
Receive notifications when renders complete and files finish processing.
Webhooks push event notifications to your server so you don't need to poll.
Configure a webhook
Webhooks are configured in Dashboard → Settings → Webhooks. Add your endpoint URL and select the events you want to receive.
Supported events
| Event | Fired when |
|---|---|
render.created | A render job is accepted and queued |
render.pending | A render job is waiting to start |
render.rendering | Frame capture has begun |
render.completed | A render job finishes successfully |
render.failed | A render job fails |
file.created | A file record is created |
file.uploading | File upload is in progress |
file.processing | File is being processed |
file.ready | File finishes processing successfully |
file.failed | File processing fails |
file.updated | A file's status changes to an unlisted value |
unprocessed_file.created | A raw upload is received |
Payload shape
All payloads include topic and data containing the relevant resource. Example for render.completed:
{
"topic": "render.completed",
"data": {
"id": "rnd_abc123",
"status": "completed",
"width": 1920,
"height": 1080,
"fps": 30,
"created_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:30:00Z",
"failed_at": null,
"byte_size": 15728640,
"duration_ms": 5000,
"md5": "d41d8cd98f00b204e9800998ecf8427e",
"metadata": null,
"download_url": "https://cdn.editframe.com/renders/rnd_abc123/output.mp4"
}
}
Verifying signatures
Every webhook request includes an X-Webhook-Signature header. The value is an HMAC-SHA256 of the raw request body, hex-encoded, keyed with your webhook secret (shown in the Dashboard when you create the webhook).
import crypto from "crypto";
function verifyWebhook(rawBody, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature, "hex"),
Buffer.from(expected, "hex")
);
}
// Express example
app.post("/webhooks/editframe", express.raw({ type: "*/*" }), (req, res) => {
const sig = req.headers["x-webhook-signature"];
const valid = verifyWebhook(req.body, sig, process.env.EDITFRAME_WEBHOOK_SECRET);
if (!valid) return res.status(401).send("Invalid signature");
const payload = JSON.parse(req.body.toString());
console.log(payload.topic, payload.data?.id);
res.sendStatus(200);
});
Use express.raw() (not express.json()) to preserve the exact bytes used to compute the signature.
Retry behavior
Editframe retries webhook deliveries up to 3 times with exponential backoff when your endpoint responds with a non-2xx status. Return 200 promptly and process the event asynchronously if needed.