Zero-code integrations
Point your auth provider's webhooks at Invoance and every organization in your app starts accumulating signed, independently verifiable audit events — sign-ins, membership changes, role updates — before your team writes a line of instrumentation. Clerk and Auth0 are supported today.
How it works
Dashboard → Audit Logs → Integrations → Connect provider. You get a unique webhook URL — shown once, stored hashed — plus provider-specific setup steps.
Clerk deliveries carry a Svix signature; Auth0 sends the Authorization token you configured. Nothing is trusted before it verifies.
Verified events are translated into a clean audit vocabulary, Ed25519-signed, and sealed into each organization's gap-free sequence — identical to events sent via the API.
Provider events carry the end-customer organization; unknown orgs are auto-created (up to your plan's limit) with their real names, each one a portal link away from being shown to your customer.
Clerk
- Create the integration in Dashboard → Audit Logs → Integrations (provider: Clerk) and copy the webhook URL.
- In the Clerk Dashboard, open Configure → Webhooks → Add endpoint and paste the URL.
- Subscribe to the events you want from the table below — start with the core set.
- Copy the endpoint's signing secret (
whsec_…) into the integration. If you ever rotate it in Clerk, use Roll secret on the source — same URL, nothing else changes.
| Clerk event | Becomes | Organization | Tier |
|---|---|---|---|
| organizationMembership.created | member.added | embedded organization (auto-creates it, with name) | core |
| organizationMembership.deleted | member.removed | embedded organization | core |
| organizationMembership.updated | role.changed (role kept in metadata) | embedded organization | core |
| organization.created | organization.created | the organization itself | core |
| user.created | user.created | none → org-less policy | core |
| user.deleted | user.deleted | none → org-less policy | core |
| session.revoked | session.revoked | session's active organization (nullable) | core |
| session.created | user.signed_in | session's active organization (nullable) | high-volume |
| session.removed | user.signed_out | session's active organization (nullable) | high-volume |
| user.updated | user.updated | none → org-less policy | high-volume |
High-volume tier: session.created fires on every sign-in, session.removed on sign-outs and session expiry, and user.updated on any User-object change including backend metadata writes. They count against your monthly signed-event allotment — subscribe deliberately. session.ended is intentionally not mapped: a single sign-out fires both it and session.removed, which would double-count.
Auth0
- Create the integration (provider: Auth0). Auth0 doesn't issue a secret — you invent one, so hit Generate and copy both the URL and the token.
- In the Auth0 Dashboard, open Monitoring → Streams → Create Stream → Custom Webhook.
- Payload URL: your webhook URL · Content Type:
application/json· Content Format:JSON Array· Authorization Token: the generated value — Auth0 sends it on every delivery and Invoance verifies it matches. - Pick the stream's category filters; only the codes below become events.
| Log code | Auth0 meaning | Becomes |
|---|---|---|
| s | Successful login | user.signed_in |
| slo | User successfully logged out | user.signed_out |
| f / fp / fu | Failed login (generic / wrong password / unknown user) | user.sign_in_failed (exact code kept in metadata) |
| ss | Successful signup | user.created |
| sdu | User successfully deleted | user.deleted |
| scp | Successful password change | user.password_changed |
| sce | Successful email change | user.email_changed |
| limit_wc / limit_mu | IP blocked after repeated failed logins | account.blocked (code kept in metadata) |
Deliveries arrive batched; each entry is processed independently and deduplicated by its Auth0 log id, so replays and partial retries never create duplicates. Events made in an Auth0 Organization context carry org_id / org_name and route (and auto-create) accordingly; events without one follow your org-less policy. Sign-ins and failed logins are high-volume — filter your stream categories with your allotment in mind.
Delivery semantics
The receiver is built for at-least-once delivery: providers retry on failure, idempotency absorbs the retries, and permanent conditions are acknowledged with a 200 so a single odd event can never make your provider disable the endpoint.
Quota: only events that are actually signed count against your allotment — skipped events are free, always. Org routing:each source either auto-creates organizations as their events arrive (up to your plan's org limit) or runs in allowlist mode, accepting only organizations you created yourself; org-less events are skipped or routed to a catch-all org you designate. Everything is switchable per source, live, from the dashboard.
Set it up under Dashboard → Audit Logs → Integrations. The receiver endpoint itself is documented in the API reference, and once events are flowing, the quick start shows how to instrument your product's own actions with one call each.