Audit logs

Every call between your services, in one searchable place.

Authorizations, requests, responses, errors, and application logs land centrally — searchable by client, endpoint, and status code, with a single request id reassembling the whole call flow.

request 8f2c1a9e-…
  1. authorize allowed · billing-svc · v2
  2. request POST /v2/payments
  3. logs 3 lines
  4. response 201 · 84 ms

The problem this solves

A partner says a call failed at 14:32. Answering that means the gateway log for the request, the application log for what it did, the error tracker for what blew up, and the response log for what the caller actually received — four tools, four search syntaxes, four retention policies, and no shared identifier between them.

Most of the time spent on an integration support ticket is spent reassembling one request from four places.

One request id, the whole flow

Request, logs, errors, and response are correlated by a single id, so one lookup returns the entire journey of a call rather than a fragment of it. You see what the caller sent, what your service did while handling it, anything it raised, and what came back — in order.

Scoped to the organization that owns the data

Records are returned only to the organization that owns the target application environment. Both providers and their clients read from the same store, and each sees exactly their side of the conversation.

Masking happens before the write, not after

Masking rules are resolved per organization, application, and endpoint, and applied at ingest — the record is masked before it is stored, not redacted on the way out. What you choose not to keep is never written down in the first place.

Rules are generic rather than fixed to a list of field names, so they cover whatever your payloads actually carry.

Retention you set, enforced on a schedule

Each organization carries its own retention window, snapshotted from its plan. A daily job removes raw ingest data past that window, so the store does not grow without bound and the data you no longer need stops being your responsibility.

Built to survive bad input

Ingest is bulk-inserted, and a batch that fails is captured to a dead-letter table and retried rather than dropped. Payload text is sanitised for the things that break a Postgres write — NUL bytes, oversized fields — so one malformed body cannot take a batch of good records down with it.

Ready to deprecate with confidence?

Sign up in under a minute. No credit card, no sales call.