Guides
Webhooks
Get notified the moment a run finishes — no polling.
Register a webhook endpoint and QuickTane will POST a signed JSON payload to your server every time a run reaches a terminal status. This is the recommended way to consume run results at scale.
Setup
- Add an endpoint URL in your dashboard under Webhooks.
- Copy the generated signing secret — used to verify deliveries.
- Subscribe to the events you care about (or all of them).
Events
| Event | Fires when |
|---|---|
run.completed | A run finished successfully. |
run.failed | The code exited non-zero. |
run.timeout | The run exceeded its timeout. |
run.killed | The run was terminated. |
run.error | An infrastructure error occurred. |
Payload
Each delivery is a JSON body describing the event, with the run object under data:
{
"id": "3f1a…", // unique event id
"type": "run.completed",
"created_at": "2026-07-19T12:00:00+00:00",
"data": {
"run_id": 42,
"status": "completed",
"language": "python",
"exit_code": 0,
"duration_ms": 137,
"output": "45\n",
"created_at": "2026-07-19T12:00:00.000000Z"
}
}Headers
| Header | Value |
|---|---|
X-QuickTane-Signature | sha256=<hmac> of the raw body. |
X-QuickTane-Event | The event type, e.g. run.completed. |
X-QuickTane-Delivery | Unique delivery id (for idempotency/debugging). |
Verifying signatures
The signature is an HMAC-SHA256 of the raw request body keyed with your signing
secret, prefixed with sha256=. Always verify it before trusting a delivery, and
always hash the raw bytes — not a re-serialised object.
from quicktane import verify_signature
# in your webhook handler — use the RAW request body
if not verify_signature(raw_body, request.headers["X-QuickTane-Signature"], signing_secret):
abort(400)Doing it by hand in any language is a one-liner:
import hmac, hashlib
def verify(raw_body: bytes, header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header)Respond fast. Return 2xx quickly and do heavy work asynchronously. Failed deliveries are retried; after repeated failures an endpoint is automatically disabled.