Skip to content

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.

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.

  1. Open Settings → Webhooks.
  2. Enter your endpoint URL (must be https://).
  3. Pick the events you want delivered. Most automations only need asset.analysis.succeeded (= “clips ready”) and asset.analysis.failed.
  4. Click Add webhook. The dialog shows a signing secret once — copy and store it somewhere your endpoint can read it.

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-..."
}
}
FieldDescription
idUnique event id. Use it to dedupe — at-least-once delivery.
typeEvent type. See Event types for the full list.
createdUnix-ms timestamp the event fired
dataEvent-specific payload — flat, snake_case fields. See Event types for the schema per event.

Every delivery includes:

Content-Type: application/json
choppity-signature-256: t=1745800000,v1=5257a869e7ecebed...
choppity-signature: <legacy raw secret>
  • choppity-signature-256the canonical header. HMAC-SHA256 of <timestamp>.<body> keyed by your signing secret, in the format t=<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.
  • At-least-once. Network blips, 5xx responses, and timeouts trigger retries. Use the event id to dedupe.
  • Up to 5 retries with exponential backoff: 1 s, 2 s, 4 s, 8 s, 16 s between attempts.
  • Acknowledge with any 2xx response 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 created timestamp.
PatternSubscribe 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