Webhooks
Webhooks let your endpoint receive events from Choppity in real time. Instead
of polling GET /v1/clips/:jobId, you register an https URL once and we POST
each event to it as it happens.
Registering a webhook
Section titled “Registering a webhook”Webhook management is dashboard-only — it requires a Firebase JWT, so an API-key-authenticated automation can’t register or revoke webhooks. This prevents a leaked key from silently exfiltrating event data to an attacker URL.
- Open Settings → Webhooks.
- Enter your endpoint URL (must be
https://). - Pick the events you want delivered. Most automations only need
asset.analysis.succeeded(= “clips ready”) andasset.analysis.failed. - Click Add webhook. The dialog shows a signing secret once — copy and store it somewhere your endpoint can read it.
What we send
Section titled “What we send”Every delivery is a POST to your URL with a JSON body shaped like:
{ "id": "9f8e7d6c-...", "type": "asset.analysis.succeeded", "created": 1745800000000, "data": { "asset_id": "asset_xyz", "team_id": "team_abc123", "job_id": "fb9a7c3e-..." }}| Field | Description |
|---|---|
id | Unique event id. Use it to dedupe — at-least-once delivery. |
type | Event type. See Event types for the full list. |
created | Unix-ms timestamp the event fired |
data | Event-specific payload — flat, snake_case fields. See Event types for the schema per event. |
Headers
Section titled “Headers”Every delivery includes:
Content-Type: application/jsonchoppity-signature-256: t=1745800000,v1=5257a869e7ecebed...choppity-signature: <legacy raw secret>choppity-signature-256— the canonical header. HMAC-SHA256 of<timestamp>.<body>keyed by your signing secret, in the formatt=<unix-seconds>,v1=<hex>. See Verifying signatures.choppity-signature— legacy header, ships the raw secret. Kept for backward compatibility with consumers registered before HMAC support. Will be removed in a future release. Don’t build new integrations against it.
Delivery semantics
Section titled “Delivery semantics”- At-least-once. Network blips, 5xx responses, and timeouts trigger
retries. Use the event
idto dedupe. - Up to 5 retries with exponential backoff: 1 s, 2 s, 4 s, 8 s, 16 s between attempts.
- Acknowledge with any
2xxresponse within 30 seconds. After that we abort the connection and either retry (if the budget isn’t exhausted) or drop the delivery. We don’t inspect the body. - Deliveries are best-effort, not strictly ordered. If your business
logic depends on ordering, sort by the
createdtimestamp.
Common patterns
Section titled “Common patterns”| Pattern | Subscribe to |
|---|---|
| ”Tell me when clips are ready” | asset.analysis.succeeded, asset.analysis.failed |
| ”Tell me when renders finish” | project.render.succeeded, project.render.failed |
| ”Tell me when posts publish” | post.published, post.failed |
| ”Show progress in my UI” | All *.progress events (high volume!) |
| ”Track every state change” | All events |
- Event types — full catalog with example payloads
- Verifying signatures — HMAC recipes in Node, Python, Go