Audit log

The audit log is a chronological, append-only record of significant actions taken in your company — order placements, status changes, imports, team-member invites, webhook deliveries, subscription changes, returns, and more. Every entry captures who did what, to which entity, and when.

Find it at /dashboard/settings/audit. OWNER or ADMIN only.

Anatomy of an entry

Each row has:

FieldNotes
WhenTimestamp, local timezone, Apr 17, 2026, 02:22 PM.
ActorThe user's name, the word Customer (for storefront-initiated actions), or System (for cron jobs, webhook side-effects, subscription state changes).
ActionA dotted identifier like order.placed or webhook.secret_rotated.
EntityThe entity type and, when relevant, a truncated ID — e.g. order clxxord1….
DetailsA View disclosure that expands into a JSON metadata blob. Size-capped at 8 KB; oversized payloads are dropped with a log warning.

Actor types

Every entry has one of three actor types:

Actor typeWho / whatExamples
USERA staff member — matched to a row in the Actor column.A dashboard action, an API call with a key (the key's creator is the actor).
CUSTOMERA customer acting on the storefront.Self-registration, placing an order, opening a return.
SYSTEMNon-human actions.Scheduled-report runs, webhook delivery attempts, Stripe webhook side-effects.

Filters

The top bar exposes:

  • Actor typeUSER, SYSTEM, CUSTOMER, or All.
  • Entity type — a dropdown populated from whatever entity types have been written (e.g. order, product, customer, api_key, webhook).
  • From / To — date range. To is inclusive; it snaps to end-of-day.

Filters stack and are encoded in the URL so you can share a filtered view by copying the address bar.

Action catalog

Actions are stable strings — the enum in code is the source of truth, but here's the current catalog organised by area.

Inventory

ActionWhen
product.createdProduct created (dashboard, API, or CSV).
product.updatedProduct edited.
product.deletedProduct deleted.
product.status_changedProduct toggled active/inactive.
product.bulk_importedCSV import applied. Metadata: row counts.
product.bulk_updatedBulk edit applied from the products list.
product.bulk_deletedBulk delete applied from the products list.

Orders

ActionWhen
order.placedOrder created (storefront, API, or dashboard).
order.status_changedStatus transition. Metadata: fromStatus, toStatus.
order.updatedNon-status order edits (e.g. tracking, PO number, notes).

Customers

ActionWhen
customer.createdCustomer created (dashboard, API, self-register, CSV).
customer.updatedAny customer field edited.
customer.status_changedCustomer activated / blocked.
customer.bulk_importedCSV import applied.

Customer contacts & pricing

ActionWhen
customer_contact.createdA sub-user login added to a customer.
customer_contact.updatedRole change on a customer contact.
customer_contact.deletedA sub-user login removed.
price_override.setPer-customer price override created or changed.
price_override.deletedPer-customer price override removed.

Team

ActionWhen
member.invitedStaff invite sent.
member.joinedInvite accepted.
member.removedMember removed from company.
member.role_changedRole updated (OWNER / ADMIN / MEMBER).

API keys & webhooks

ActionWhen
api_key.createdAPI key generated. Metadata: name, scopes.
api_key.revokedAPI key revoked.
webhook.createdWebhook endpoint registered.
webhook.updatedWebhook config edited.
webhook.secret_rotatedSigning secret rotated.
webhook.deletedWebhook endpoint deleted.

Returns & refunds

ActionWhen
return.requestedReturn opened.
return.approvedReturn approved.
return.receivedReturn marked received, with item conditions recorded.
return.rejectedReturn declined.
refund.processedRefund issued.
credit_note.issuedCredit note created alongside a refund.

Reports

ActionWhen
report.exportedOn-demand report CSV/PDF downloaded.
scheduled_report.createdScheduled report configured.
scheduled_report.updatedScheduled report edited.
scheduled_report.deletedScheduled report removed.
scheduled_report.sentA cron run successfully sent a report.
scheduled_report.failedA cron run failed.

Subscription & billing

ActionWhen
subscription.changedPlan or billing interval changed.
subscription.past_dueStripe invoice payment failed.
subscription.canceledSubscription canceled.

Metadata payloads

The metadata column is free-form JSON specific to the action. Shape is stable per action but not formally schemed — inspect a few entries with the View disclosure to see what a given action emits before building dashboards on top of it.

Size cap: 8 KB serialised per entry. Anything larger is dropped with a server-side log warning and the entry is written without metadata (action / actor / entity are always persisted).

Retention

Audit log entries are never automatically deleted. They persist for the life of the company; deleting the company cascades to its audit log (hard delete).

No export button today — if you need a dump, email support@distribu.app.

What the audit log is not

  • Not a webhook delivery log. Per-webhook delivery attempts (status codes, response times) are recorded separately, visible on each webhook's detail page. The audit log only captures config changes to webhooks themselves.
  • Not an API request log. Individual API calls aren't audited — only the key create / revoke events are. Calls update apiKey.lastUsedAt but don't write an audit row.
  • Not a security event stream. Logins, failed logins, password resets, and the like flow through application logs, not the audit log.

What's not here (yet)

  • CSV / JSON export from the UI.
  • Programmatic audit-log API (/api/v1/audit) — not exposed.
  • Per-entity drill-in — clicking an entity doesn't jump to its detail page yet.
  • Custom retention windows. Every entry is kept indefinitely.

Related:

  • Roles & permissions — who can read the audit log.
  • Webhooks — where per-delivery webhook history lives (not here).
  • Notifications — the in-app stream of things you should know about, a curated subset of audit events.