Developer guide

Verifying signed completion webhooks

Add webhook_url to the run request. Each delivery carries Encevra-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "t.body"> using the webhook secret issued with your key. Verify in constant time and reject timestamps older than five minutes.

For backend developers. Written by the Encevra engine team. Reviewed 2026-10-12.

Example (Python)

This is an example. Verify against the raw request body before parsing JSON.

import hmac, hashlib, os, time

def verify(raw_body: bytes, header: str) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    t, sig = int(parts["t"]), parts["v1"]
    if abs(time.time() - t) > 300:
        return False  # reject old deliveries
    expected = hmac.new(
        os.environ["ENCEVRA_WEBHOOK_SECRET"].encode(),
        f"{t}.".encode() + raw_body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, sig)

Delivery behaviour

Event types are panel.run.completed and panel.run.failed. Non 2xx responses are retried up to three times. Polling keeps working either way, so treat the webhook as a prompt to fetch, not your only source of truth.

Checklist before going live

  • Compare signatures in constant time
  • Reject timestamps older than a few minutes
  • Verify the raw body, before parsing JSON
  • Return 2xx quickly and process in the background

Frequently asked questions

Where is the signing secret?
Each API key has its own webhook secret.
What header carries the signature?
Encevra-Signature, formatted t=timestamp,v1=signature.
What is signed?
The timestamp, a dot, and the raw request body.

Read next