Browse documentation
2026-09-28AutoDataOpen in dashboard

Webhooks

Get an HTTP call when your runs complete or fail: events, payload, signature verification, delivery log and API.

What webhooks do

A webhook is a URL of yours that AutoData calls with a JSON POST when one of your runs finishes. Manage them on Listeners → Webhooks or at /api/v1/webhooks. To start a run from an incoming request instead, see Triggers.

Creating a webhook

  1. Click Add Webhook.
  2. Enter an optional name and the URL. It must be http or https, resolve, and point to a public address.
  3. Select events (the form pre-selects error, job.completed, job.failed).
  4. Optionally enter a secret to sign calls.
  5. Save, then use the test button.

Events

EventSent when
job.completedOne of your runs completes, from any surface.
job.failedOne of your runs fails.
job.heldAn automated run is held because its estimated price is above the limit set for it.
errorPlatform-wide error notices from the operators only; not sent for your runs.
warningAccepted, not currently sent.
infoAccepted, not currently sent.
successAccepted, not currently sent.
quality.breachAccepted, not currently sent.

A webhook created through the API without events subscribes to ["error"] only. Quality alert rules store webhook_ids, but those webhooks are not called when a rule fires. There is no job.cancelled event.

Choosing webhooks per run

A finished run calls every active webhook subscribed to the event, unless the run names webhook_ids; then only those are called. Set it as webhookIds on a dashboard upload, webhook_ids on a connector run, or pipeline_config.webhook_ids on listeners, the SFTP inbox and schedules (target_pipeline_config.webhook_ids on triggers).

Payload

{
  "event": "job.completed",
  "data": {
    "session_id": "3971e9cc-...",
    "status": "completed",
    "original_filename": "orders.csv",
    "timestamp": "2026-09-28T14:32:00.123456",
    "files": ["dsm_output.csv", "dsg_output.csv"]
  },
  "timestamp": "2026-09-28T14:32:00.130001",
  "webhook_id": "b6a4c1f0-..."
}

job.failed has "status": "failed" and error instead of files. The test call has "event": "test".

Verifying the signature

With a secret, each call carries X-Webhook-Signature: sha256=<hex>: HMAC-SHA256 with your secret over the payload serialised with sorted keys, exactly as Python's json.dumps(payload, sort_keys=True) produces it. The body on the wire is not sorted, so parse and re-serialise before hashing.

import hashlib, hmac, json

def verify(raw_body: bytes, header: str, secret: bytes) -> bool:
    canonical = json.dumps(json.loads(raw_body), sort_keys=True).encode("utf-8")
    expected = "sha256=" + hmac.new(secret, canonical, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header or "")

Delivery

  • One attempt, 10-second timeout, no automatic retries.
  • 2xx counts as delivered; redirects are not followed.
  • The URL is re-checked at delivery; private addresses are blocked.
  • The delivery log keeps the 50 most recent attempts with event, status code, duration, response excerpt and error.

API

MethodPathNotes
GET/api/v1/webhooksList.
POST/api/v1/webhooksurl (required), name, events, secret. 201.
GET/api/v1/webhooks/{id}One webhook.
PUT/api/v1/webhooks/{id}Any of url, name, events, secret, active.
DELETE/api/v1/webhooks/{id}Also deletes its log.
POST/api/v1/webhooks/{id}/testSends the test payload; reports your status code.
GET/api/v1/webhooks/{id}/deliveriesLatest 50 attempts.

Python SDK: list_webhooks(), create_webhook(url, events=None, name=None, secret=None), get_webhook(id), update_webhook(id, **fields) (use active=), delete_webhook(id), test_webhook(id), webhook_deliveries(id).