Receive project notifications
Continue your automation when captions are ready, an export finishes, or a project needs attention.
Create an endpoint
Once access opens, use Settings → Integrations to add a public HTTPS receiver, choose events and save the signing secret when it appears. You can also create the endpoint with a key that has webhooks:manage:
curl --fail-with-body https://api.captionbolt.com/v1/webhooks \
-H "Authorization: Bearer $CAPTIONBOLT_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"url":"https://receiver.example/captionbolt","events":["project.completed","project.failed"]}'
Use your real receiver URL. Only public HTTPS on port 443 is supported; redirects are not followed. Localhost and private-network receivers cannot receive deliveries directly.
Choose events
project.completed: the finished export is available; subscribed by default.project.failed: processing or export failed; subscribed by default.project.ready: full processing is complete and the video can be reviewed or exported.project.cancelled: the project was cancelled.
Subscriptions cover your account's eligible video projects created in the main app, through REST or through MCP. Standalone Transcripts, deleted projects and projects outside their access window are excluded. Ready is a processing milestone, not confirmation that a person reviewed the video.
{
"id": "event-uuid",
"type": "project.completed",
"createdAt": "2026-09-10T12:00:00.000Z",
"data": {
"projectId": "project-uuid",
"status": "completed",
"stage": "export",
"resultUrl": "https://api.captionbolt.com/v1/projects/project-uuid/result"
}
}
data.resultUrl is an authenticated API endpoint, not a direct video download. Fetch it with your own read-scoped API Key to obtain fresh download links. Events contain metadata, not video bytes or captions.
Verify before processing
CaptionBolt follows Standard Webhooks. Use a compatible verifier or implement these checks before trusting an event:
- Preserve the exact raw request body. Read
webhook-id,webhook-timestampandwebhook-signature. - Remove
whsec_from your signing secret and base64-decode the remaining bytes. Compute HMAC-SHA256 overid.timestamp.rawBodyand compare the base64 signature in constant time. - Reject old or future timestamps outside a bounded tolerance, such as five minutes. During key rotation the header can contain multiple space-separated
v1,signatures; accept a signature that matches a trusted key. - Deduplicate by event ID and persist your work before replying 2xx. Process the business task asynchronously and acknowledge promptly, within the 15-second delivery deadline.
The signing secret verifies events; it is separate from your API Key. Rotation returns a new secret once and allows a 24-hour overlap. Another rotation is blocked until that overlap ends.
Test and recover deliveries
Send a test from settings; it arrives as webhook.test, so handle it separately from project events. Inspect delivery history, correct receiver errors, then manually retry a failed or previously delivered event. History covers the last 30 days.
Deliveries may repeat and arrive out of order. Non-2xx responses, connection failures and missing acknowledgements get three automatic attempts: the initial request, then retries after about one minute and five minutes. A third failure stops automatic delivery. A manual retry keeps the event ID and starts a fresh three-attempt budget, so your receiver must remain idempotent.
Disabling an endpoint stops pending deliveries; an in-flight request may still finish. Deleting it also removes its delivery history. Project deletion or access expiry stops pending project notifications. Webhooks do not extend media access: fetch and save results in time, or poll project status as needed.