Skip to Content
GuidesWebhooks & events

Webhooks & events

Register an endpoint and Jetwild POSTs a signed JSON event to it when something happens — so you can react instead of poll.

Registration + signing are live; events are coming soon

You can register webhooks, rotate their signing secret, and send a test delivery today. Automatic event emission (the catalog below) is coming soon — right now only the manual test ping fires. Build your receiver + signature check now; events will start arriving when emission ships.

Register a webhook

Manage webhooks in Settings → Developers (an OWNER or DIRECTOR of the workspace). Each webhook gets a signing secret prefixed whsec_, shown once.

Events

The event catalog Jetwild will emit. Coming soon

scene.ready
platform
Intelligence finished — metadata is ready.
scene.shipped
platform
A scene shipped to a channel.
scene.failed
platform
Processing failed for a scene.
shield.flagged
shield
A scan returned a blocking verdict.
shield.cleared
shield
A scan cleared with no risk.
distribution.shipped
platform
A distribution plan event shipped.
batch.completed
platform
A batch finished processing.
credits.low
billing
Workspace credits dropped below threshold.

Payload

Every delivery is a JSON body with the event name and its data, plus an x-jetwild-event header naming the event.

{
"event": "ping",
"data": { "test": true, "timestamp": "2026-07-02T10:00:00.000Z" }
}

Verify signatures

Every request carries an x-jetwild-signature header of the form t={timestamp},v1={signature}, where signature is HMAC-SHA256(secret, "{timestamp}.{rawBody}") as hex. Recompute it over the raw request body and compare before trusting the payload.

import { createHmac, timingSafeEqual } from 'node:crypto'
 
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((kv) => kv.split('=')))
const expected = createHmac('sha256', secret)
.update(`${parts.t}.${rawBody}`)
.digest('hex')
const a = Buffer.from(expected)
const b = Buffer.from(parts.v1 ?? '')
return a.length === b.length && timingSafeEqual(a, b)
}
Use the raw body

Compute the HMAC over the exact bytes you received, before any JSON parsing — re-serializing can change whitespace and break the signature.

Retries

Failed deliveries retry up to 5 times with exponential backoff (starting at 2s). After 10 consecutive failures a webhook is automatically disabled — re-enable it in Settings once your endpoint is healthy.

Last updated on