Audit logging as a service

Audit logs
your customers can read themselves

Emit an event with one call. Santati hash-chains it, scopes it to your customer's organization, and serves it back through one read API — so your customers can answer their own audit questions.

Free up to 1,000 events a day. No credit card required.

SHA-256
hash-chained writes
1
API call to read it back
per-org
scoping and retention
HMAC
signed webhook streams
Live trail

Every event, receipted

Writes are append-only and hash-chained. Reads are filtered by actor, target and organization. Your customer's compliance team self-serves the evidence.

  • Hash-chained, append-only writes
  • Actor, target and organization indexing
  • Streaming export to your webhooks
live tail · org_acme_logistics
12:04:19.221 invoice.voided usr_123 · inv_555 · org_acme_logistics
12:04:19.884 api_key.created usr_9fa2 · key_live_8x · scope=read
12:04:20.130 member.role_changed usr_44c1 · viewer → admin
12:04:22.902 payment.refunded pay_9931 · 42.00 USD
12:04:23.010 export.requested csv · 12,904 events
12:04:25.441 login.succeeded sso/okta · 203.0.113.24
12:04:26.118 key.rotated key_live_8x · 90d expiry
12:04:27.550 retention.updated billing · 2555 days
12:04:28.775 webhook.delivered hooks.acme.io · 200 OK in 84ms
12:04:29.402 actor.merged usr_881 → usr_123
12:04:30.019 export.downloaded acme-audit-2026-09-29.ndjson
12:04:31.664 invoice.paid inv_556 · 4200 USD
Instrument

Emit an event in one call

Drop an SDK in wherever the action happens. One call, typed payload, no queue to run.

santati · emit
import { Santati } from '@santati/node';

const santati = new Santati({ apiKey: process.env.SANTATI_API_KEY, trail: 'billing' });

await santati.events.emit({
  event: 'invoice.voided',
  organizationId: 'org_acme_logistics',
  actor: { type: 'user', id: 'usr_123', name: 'Valentine Michael Smith' },
  targets: [{ type: 'invoice', id: 'inv_555', name: 'INV-555' }],
  data: { amount_cents: 4200, currency: 'usd', status: 'void' },
});

no queue, no schema to register — the API accepts the event and indexes actor, target and organization

Read back

One call to read a customer's log

Filter by organization and hand the page straight to your customer's screen. Team-scoped API keys mean a key can only ever see its own team's events.

GET /api/v0/events/
curl -G https://api.santati.io/api/v0/events/ \
  -H "Authorization: Api-Key $SANTATI_API_KEY" \
  -d organization_id=org_acme_logistics -d limit=50
{
  "next": "https://api.santati.io/api/v0/events/?organization_id=org_acme_logistics&limit=50&cursor=cD0yMDI2LTA5LTI5VDE0JTNBMDMlM0ExMS40ODIwMDAlMkIwMA",
  "previous": null,
  "results": [
    {
      "id": "01J9Z6K3M4QX8RT2VN5B7HCWDA",
      "trail": "billing",
      "event": "invoice.voided",
      "created_at": "2026-09-29T14:03:11.482000Z",
      "received_at": "2026-09-29T14:03:11.913000Z",
      "organization_id": "org_acme_logistics",
      "actor": { "type": "user", "id": "usr_123", "name": "Valentine Michael Smith", "metadata": {} },
      "targets": [{ "type": "invoice", "id": "inv_555", "name": "INV-555", "metadata": {} }],
      "metadata": {},
      "data": { "amount_cents": 4200, "currency": "usd", "status": "void" },
      "context": { "location": "203.0.113.4", "user_agent": "acme-billing/1.4" },
      "hash": "9f2c1d4a5b6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708",
      "schema_version": null
    }
  ]
}
acme logistics · activity
Occurred Event Actor Target
2026-09-29 14:03:11 invoice.voided Valentine Michael Smith inv_555
2026-09-29 14:02:48 payment.refunded Valentine Michael Smith pay_9931
2026-09-29 13:58:02 member.role_changed Jill Boardman usr_44c1
2026-09-29 13:51:37 login.succeeded Valentine Michael Smith sso/okta
What you get

Built for audit evidence

01 / Integrity

Tamper-evident chain

Every live write is hashed into a per-trail append-only chain. Verification is one endpoint your customer's auditor can call without you.

02 / Scoping

Organization-scoped reads

API keys are bound to one team and every read is filtered by organization, so one customer can never see another customer's events.

03 / Export

Streaming export

Relay every event to your own HTTPS webhook as it arrives, signed so you can verify it. Failed deliveries retry and can be replayed.

Ship audit logging this quarter Not next year's platform roadmap.