Skip to main content
Hand an auditor your audit trail with proof it wasn’t edited first. The export returns your audit rows as a hash-chained slice plus a signed manifest, so anyone can re-check the chain and verify the signature offline to confirm nothing was added, removed, or altered. Reach for it when a regulator, customer, or security review needs evidence rather than a screenshot. The export uses the account:read scope, the same as reading the live trail.

Export a window

Narrow the window with from / to (RFC 3339). With neither set, the export covers the last 30 days rather than your whole history; supplying either bound requests an explicit window. A page holds up to 1000 rows; when more remain, the response carries a pagination.nextCursor that you pass back as after to fetch the next page. Each page is its own contiguous, independently verifiable chain segment, so paging never breaks the proof.
You get back the rows and a signed manifest:

How the proof works

Two things make the export tamper-evident, and you can check both yourself:
  • A hash chain over the rows. Each row’s rowHash is computed from the previous row’s hash plus its own contents, so the rows form a chain. Remove or edit one and every hash after it stops matching.
  • A signed manifest. The manifest commits to the window, the row count, and the final row hash, then signs that with Dairo’s key. The signature only checks out if those committed values are exactly what was exported.

Verify an export offline

Anyone — you, an auditor, a customer’s security team — can confirm an export is intact without calling Dairo, using only the published verification key:
  1. Fetch Dairo’s public key from the JWKS by the manifest’s kid.
  2. Verify the manifest signature over its committed fields (window bounds, rowCount, headRowHash).
  3. Walk rows in order: each rowHash is sha256(prevHash || canonical(row)), with the genesis row’s prevHash empty. Confirm the chain is contiguous by chainSeq — a gap means a row was deleted.
  4. Confirm the final rowHash equals the manifest’s headRowHash.
If all four pass, the slice is exactly what Dairo recorded for that window — no additions, no deletions, no edits.
When an export spans more than one page, follow pagination.nextCursor with after to drain the full range. Store each manifest alongside its rows so the proof stays attached to the data.

Next steps

Audit logs

The live trail this export is drawn from.

Data erasure

Subject erasure with signed deletion certificates.

Data residency

Where your data lives and the subprocessor list.

API reference

GET /v1/audit-logs/export.