Webhooks
Receive Auditmark events at your own HTTPS endpoint, verified with a per-endpoint signing secret.
Webhooks deliver Auditmark events to an HTTPS endpoint you host, so an external system gets notified in real time when an inspection changes. You add and manage endpoints in the admin app at app.auditmark.io under Settings, on the Webhooks tab. Webhook management is admin-only and is not part of the /v1 API key surface.
Managing endpoints
The Webhooks tab lists every endpoint with its URL, the events it subscribes to, a status dot, and when it was added. Use Add endpoint to create one. Each endpoint row has a Send test button and a menu with View deliveries, Edit endpoint, Regenerate secret, and Delete.
When you add or edit an endpoint you set:
| Field | What it does |
|---|---|
| Endpoint URL | The public https:// URL Auditmark posts to. |
| Description | An optional label, for example the name of the receiving system. |
| Events | The event types this endpoint receives. Use Select all or Clear all to toggle every subscribable event at once. |
| Active | Whether Auditmark delivers events to this endpoint. Turn it off to pause delivery without deleting the endpoint. |
An endpoint must subscribe to at least one event before you can save it.
Endpoint requirements
Your endpoint must use HTTPS. Auditmark rejects any URL that resolves to a private, loopback, link-local, reserved, multicast, or unspecified address, and it re-checks the destination IP on each delivery to guard against SSRF and DNS rebinding. If a URL fails these checks, the form shows an error and the endpoint is not saved.
Event types
You can subscribe an endpoint to any of these events:
| Event | When it fires |
|---|---|
inspection.started | An inspection moved to in progress. |
inspection.completed | An inspection was completed. |
inspection.pending_approval | An inspection is awaiting approval. |
inspection.pending_sign_off | An inspection is awaiting sign-off. |
inspection.archived | An inspection was finalized (archived). |
directory.user.left_source | An external-directory user left the source and is flagged for admin review. |
A ping event is sent when you choose Send test on an endpoint. It is not a subscribable type and carries no domain data, so you can use it to confirm your receiver is reachable and your signature check works.
Delivery format
Each delivery is a POST request with a JSON body. The body is an envelope:
{
"event_id": "…",
"event_type": "inspection.archived",
"created_at": "2026-06-23T12:00:00+00:00",
"organization_id": "…",
"data": { }
}The data field holds the event-specific payload, for example the inspection ID and its new status.
Auditmark sends these headers:
| Header | Value |
|---|---|
Content-Type | application/json |
X-Auditmark-Event | The event type, for example inspection.archived. |
X-Auditmark-Delivery | A unique delivery ID you can use for idempotency. |
X-Auditmark-Signature | t=<timestamp>,v1=<hex>, an HMAC-SHA256 over <timestamp>.<body>. |
X-Auditmark-Signature-256 | sha256=<hex>, an HMAC-SHA256 over the raw body. |
The X-Auditmark-Signature header includes the request timestamp in the signed content, so you can detect and reject replays by checking that the timestamp is recent.
Verifying a delivery
Each endpoint has its own signing secret. It is shown once when you create the endpoint, and you can regenerate it at any time from the endpoint menu. The secret starts with whsec_. Store it somewhere safe, because it is not shown again. Recompute the HMAC and compare it to the header before you process the payload.
import hmac
import hashlib
def verify_signature(secret: str, raw_body: bytes, signature_header: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(),
raw_body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, signature_header)
# Usage
is_valid = verify_signature(
secret=YOUR_ENDPOINT_SECRET,
raw_body=request.body, # raw bytes, before any JSON parsing
signature_header=request.headers["X-Auditmark-Signature-256"],
)X-Auditmark-Signature-256 follows the same convention as GitHub's X-Hub-Signature-256, so libraries and receivers that support that header (for example Make, Zapier, and n8n) work here too.
Regenerating the secret takes effect immediately: the old secret stops working, so update any system that verifies signatures before you rely on the new one.
Retries and failure handling
Auditmark retries a delivery that does not receive a 2xx response. The retry schedule uses exponential backoff starting at 30 seconds, capped at 3600 seconds (one hour), for up to 12 attempts before the delivery is marked failed.
After 20 consecutive failures on an endpoint, Auditmark auto-disables it and records the reason on the endpoint. Re-enabling the endpoint (set Active back on) clears the failure count and resumes delivery.
Auditmark logs every delivery attempt. Choose View deliveries on an endpoint to see the recent deliveries with their status (Pending, Delivered, or Failed), HTTP code, attempt count, latency, and time. Use Replay on a row to requeue that delivery.
Responding to deliveries
Return a 2xx status code as quickly as possible. If your processing takes time, accept the delivery immediately and handle it asynchronously. Use X-Auditmark-Delivery to deduplicate replays on your side.