Export an audit log for an external auditor
Who does this: Any staff role with Activity log access (Payroll Specialist, Payroll Lead, Bookkeeper, Senior Accountant, Platform Admin) When: A statutory or internal auditor asks for evidence of who did what, when, on whose behalfResult: A filtered, immutable record covering the auditor's question, in a form you can hand over and stand behind.
The platform records an audit event every time a state-changing action runs — a cycle is initiated, an issue is overridden, an approval is received, a journal entry is approved, a contact is deactivated. Audit events are append-only and retained per the retention policy. For most external-audit questions you don't need engineering involvement — the Activity log in the staff dashboard sidebar is the front door.
TIP
A typical question shaped like "prove the approval request for Walker & Tan Associates Pte Ltd's April 2026 payroll was sent on April 8 and that the approver actioned it on April 12 at 14:30 SGT" is fully answerable from the Activity log plus a peek at the Outbox. You don't need a database.
Before you start
- [ ] You know what the auditor is asking for — a specific client? A date range? A particular event type (overrides, approvals, deactivations)? A specific person's actions?
- [ ] You have a way to deliver the evidence the auditor will accept (PDF, screenshot, CSV — agree this up front).
- [ ] If the request involves a closed cycle outside the standard retention window, check the retention policy first — older raw uploads may have been purged even though the audit events themselves remain.
Steps — narrow the question down
- Open Activity log in the staff dashboard sidebar (under Administration).
- Use the Filters card at the top to narrow the question:
- Activity — free-text match against the event code. Useful values:
cycle,export,approval,override,staff_user,contact,journal,reconciliation. Match is substring, socycle.exportedandcycle.requestedboth come back when you typecycle. - Actor — Payroll team (a staff user did this), Client (a client contact did this), or Automated (the platform's scheduler / matchers).
- Client — pick the client. Leave as Any client for cross-client questions like "every override our team did in April".
- From / To — date range. Inclusive on both ends.
- Activity — free-text match against the event code. Useful values:
- Click Clear filters to reset and start over if you've over-constrained.
The table below the filters refreshes as you type. Each row has:
- Activity — a humanised description (e.g. Cycle exported rather than
cycle.exported) - Actor — Payroll team — Jane Tan, Client — finance@example.com, or Automated
- Entity — the cycle / batch / contact the action was performed on, with a link back
- Time — when it happened, in the viewing user's local timezone
Steps — capture the evidence
For audit-grade evidence, click any row to open the detail panel on the right. The panel includes:
- Activity badge with the human-readable description
- Timestamp in local time
- Actor — the role + name (or email for client contacts)
- Entity — what was acted on
- Event code — the canonical event type (e.g.
cycle.exported,issue.overridden) - Payload — the JSON snapshot of what changed (before / after fields where applicable)
Capture the row + detail panel however your auditor accepts:
- Screenshot — the simplest path for a single event
- PDF — print the page (Ctrl/Cmd+P) with the detail panel open; the browser PDF is timestamped automatically
- Tabular export — see "For larger date ranges or list-shaped questions" below
NOTE
Audit events are immutable. Once written, they cannot be edited or deleted by anyone (including Platform Admins). If a row exists, that action genuinely happened on that timestamp. If a row is missing for an action you remember performing, the action either never executed or it executed under a different event code — see Recover from a wrong action using the audit log for how to reason about this.
For larger date ranges or list-shaped questions
If the auditor asks for every override across the firm in Q1, capturing 50 rows by screenshot isn't practical.
- Apply the filters that narrow to exactly the rows you need.
- Click Load more at the bottom of the table until every row in the range is loaded — the count keeps climbing each click.
- Capture the loaded table as a single PDF (browser print) and hand that over.
- For each individual override the auditor asks about, open the detail panel and capture the JSON payload as a separate evidence item.
If the auditor needs a structured tabular file (CSV / Excel) and the print-to-PDF route isn't acceptable, ask a Platform Admin — the platform team can produce a signed CSV from the audit log table on request, with a link that expires within an hour of issue.
For a single cycle's full history
Sometimes the question is "give me everything that happened on this cycle, in order". The cycle's own Audit tab is the right surface for that.
- Open the cycle from Cycles in the sidebar.
- Click the Audit tab.
- The table shows only events on that cycle, oldest first by default. Every row is the same shape as the global Activity log, with the same detail panel.
- Print to PDF for evidence — the page header includes the client's legal name and the cycle month, so the resulting file is self-identifying.
How to know it worked
- The Activity log table reflects exactly the rows the auditor asked about — no more, no less.
- Your screenshot / PDF includes both the filter chips (so the auditor can see what you queried) and the rows themselves.
- Every captured event has a matching detail-panel snapshot.
- If you cross-reference Outbox: each
*.requested/*.dispatchedevent in the audit log corresponds to a row in Outbox with the same timestamp (Verify an email was sent).
Common situations
| If you see… | It means… | What to do |
|---|---|---|
| The filters return nothing | The combination is too narrow, or the events are outside the retention window | Widen the date range; if older than the retention horizon, see retention policy |
| The actor column says Automated | The platform's scheduler or matcher performed the action | This is a real, attributable action — automated jobs are an actor in the audit model |
| A client's deactivated contact appears as the actor on an old approval | Correct — past actions stay attributed to the contact who actually did them, even after deactivation | Capture as-is; this is exactly what an auditor wants |
| You can't find an event you remember firing | The action may have failed silently or been blocked. The audit log records successful state changes only | See Recover from a wrong action using the audit log |
| You need to prove something happened outside the retention window | Audit events themselves are retained beyond raw uploads — but check the retention policy for the exact horizon | Read the retention policy; escalate if older than the audit-event retention horizon |
Related
- Recover from a wrong action using the audit log — when the audit log shows the wrong action did happen
- Verify an email was sent — Outbox is the proof for outbound communications
- Manage staff users — actor identity in the audit log is the staff record
- Retention policy — how far back audit events go