Webhooks
Webhooks send each entry of the admin audit trail to a URL you control the moment it is recorded: user created, deleted or blocked, roles changed, an import, a deletion awaiting approval, and so on.
Manage them under Settings > Integrations > Webhooks. That page is for instance admins and organization owners. Webhooks belong to the organization they were created in.
Adding a webhook
Section titled “Adding a webhook”Give the URL, optionally a description, and choose All events or particular ones. The signing secret is shown once, when you add the webhook: copy it then. Send test posts a webhook.test event and shows the outcome. You can switch a webhook off, or delete it, at any time. Up to 10 per organization.
The URL must use https and may not contain credentials. By default AUMS refuses to send to private, loopback or link-local addresses (checked again when connecting, so a host can’t change its answer in between) and never follows redirects.
What is sent
Section titled “What is sent”A POST with a JSON body:
{ "id": "0d4f…", "type": "user.delete", "created_at": "2026-10-02T10:00:00.000Z", "organization_id": "org_…", "status": "success", "actor": { "id": "usr_…", "email": "admin@example.com" }, "target": { "type": "user", "id": "auth0|123" }, "details": { "reason": "left the company" }}type is the audit action (user.create, user.delete, user.roles.update…; the Audit Logs filter lists them), status is success or failure. The admin’s IP address and user agent are not sent.
Headers: X-AUMS-Event, X-AUMS-Delivery (unique per delivery), X-AUMS-Timestamp (Unix seconds) and X-AUMS-Signature.
Verifying the signature
Section titled “Verifying the signature”The signature is v1= followed by the hex HMAC-SHA256, keyed with your signing secret, of <timestamp>.<raw body>. Recompute it on the raw body, compare in constant time, and reject old timestamps to stop replays.
import { createHmac, timingSafeEqual } from 'node:crypto'
function verify(secret, headers, rawBody) { const expected = `v1=${createHmac('sha256', secret) .update(`${headers['x-aums-timestamp']}.${rawBody}`) .digest('hex')}` const given = Buffer.from(headers['x-aums-signature'] ?? '') return ( given.length === expected.length && timingSafeEqual(given, Buffer.from(expected)) )}Delivery and retries
Section titled “Delivery and retries”Any 2xx response counts as delivered. Otherwise (or on a timeout of 10 seconds) AUMS retries after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours, then gives up after 6 attempts. Retries run from a scheduled task every minute (a cron trigger on Cloudflare). A delivery can arrive more than once: use X-AUMS-Delivery to ignore repeats. Deliveries are kept 30 days; the settings page shows the recent ones.