Przejdź do treści

Webhook protocol

The webhook notification contract — payload shape, HMAC signature, retries, and the safety circuit breaker.

When a job finishes (completed, failed, or cancelled), we send a POST notification to your installation's callback_url. This page describes the notification contract; for a hands-on guide with verification code, see the receiving results tutorial.

Notification format

{
  "event": "job.completed",
  "delivered_at": "2026-06-03T08:00:00.000Z",
  "job": {
    "id": "00000000-0000-0000-0000-0000000000a1",
    "status": "completed",
    "order_id": "00000000-0000-0000-0000-000000000099",
    "completed_at": "2026-06-03T07:59:40.000Z",
    "error": null
  },
  "outputs": [
    {
      "url": "https://…?token=…",
      "type": "image/jpeg",
      "width": 1024,
      "height": 1280
    }
  ],
  "external_metadata": { "your": "tag" }
}
  • event — job.completed, job.failed, or job.cancelled.
  • outputs[].url — download URLs valid for at least 7 days; get fresh ones with POST /jobs/{id}/refresh-url.
  • external_metadata — returns exactly what you sent when creating the session.

Signature

Every notification carries a header:

X-Qamera-Signature: t=<unix-time>,v1=<hmac_sha256_hex>

The string <t>.<raw-body> is signed with the installation's HMAC secret (algorithm HMAC-SHA256, result in hex). Reject notifications whose t is older than 5 minutes. Ready-made verification functions for Node.js and PHP are in the tutorial.

Secret rotation window

After you rotate the secret via POST /installations/{id}/rotate-hmac, the previous secret keeps working for another 48 hours. During that window notifications have two v1= segments — one for each secret; accept either of them:

X-Qamera-Signature: t=1746777600,v1=e3b0…,v1=44a0…

Once the window ends, we sign only with the new secret.

Reliability guarantees

  • Up to 8 delivery attempts, with a growing interval (and random jitter), at most 1 hour between attempts.
  • 5 consecutive failed deliveries pause sending for 30 minutes (safety circuit breaker).
  • 3 such cycles suspend the installation — an administrator is needed to reinstate it.
  • Once the attempts are used up, the notification gets the abandoned status and can be re-sent with POST /webhooks/{delivery_id}/replay.

Your endpoint should:

  1. Respond with any 2xx status for notifications it accepts.
  2. Process idempotently — after a slow 200 response we may re-send a notification that was already delivered.
  3. Record (event, job.id, delivered_at) for diagnostics — we never re-send already-acknowledged notifications on our own initiative.