Audit log
The audit log is your organization's administrative memory: an append-only trail of the actions that change who can do what, what is for sale, and what is public. When a course disappears, a price changes, or a member's role is suddenly different, the log answers the question that matters — who did it, when, and what was the value before.
Where it lives
The feed is at Settings → Organization → Audit (/dashboard/settings/organization/audit) and is readable only by organization owners and admins — the read itself is gated in the core, so other roles are bounced back to the settings home.
- Entries appear newest first, grouped by month, showing the most recent 50 events.
- Each entry is a sentence led by the actor's avatar and name — "Ana refunded R$ 199.00 to João on Zero to Production" — with the relative time on the right.
- Events without a human actor (automatic processes) show as System, with a shield icon instead of an avatar.
What gets recorded
The log covers the administrative surface of the organization. The event names below are the real, stable identifiers — the same dotted names carried by each entry.
Money
| Event | Recorded when |
|---|
purchase.refunded | A purchase is refunded, with the amount, learner, and course |
offer.created | An offer is added to a course |
offer.archived | An offer is archived and stops selling |
offer.price.updated | An offer's price changes — the old and new price are both kept |
offer.listed.updated | An offer is shown in or hidden from the school storefront |
campaign.created | A discount campaign is created |
campaign.archived | A campaign is deleted (the event keeps its historical name) |
integration.stripe.connected | Stripe is connected as the organization's payout account |
integration.payments.external.connected | An external payment checkout is connected |
integration.payments.external.secret_rotated | The external checkout's HMAC secret is rotated |
integration.payments.disconnected | The active payment integration is disconnected |
People and access
| Event | Recorded when |
|---|
learner.enrolled | Staff enrolls a learner in a course |
learner.cohort.moved | Staff places or transfers a learner to another cohort, preserving source and destination |
learner.removed | A learner is removed from a course |
learner.progress.reset | A learner's progress is reset (restart) |
learner_request.approved | A pending enrollment request is approved |
learner_request.rejected | A pending enrollment request is rejected |
member.invited | Someone is invited to the organization, with the offered role |
member.removed | A member is removed from the organization |
member.role.updated | A member's role changes — old and new role are both kept |
impersonation.started | An admin starts impersonating another member |
Affiliates
| Event | Recorded when |
|---|
affiliate.program.updated | The program's join mode or default commission changes |
affiliate.joined | Someone joins the affiliate program, with their code and starting status |
affiliate.approved | A pending affiliate is approved (or a blocked one unblocked) |
affiliate.blocked | An affiliate is blocked and their links stop attributing |
affiliate.commission.updated | An affiliate's negotiated rate is set or cleared |
affiliate.settled | Pending commissions are marked paid, with the totals per currency |
Content lifecycle
| Event | Recorded when |
|---|
content.created | A content is created, recording its kind (course or material) |
content.kind.updated | A material is promoted to a course, or a course is turned into a material |
content.published | A course is published |
content.deleted | A course is deleted |
content.listed.updated | A course is listed on, or unlisted from, the public catalog |
content.owner.updated | A course moves to a different owner (member or team) |
Developer and configuration
| Event | Recorded when |
|---|
organization.slug.updated | The organization slug — its public address — changes |
domain.updated | The custom domain is connected, changed, or removed |
domain.ownership_lost | A confirmed DNS ownership or routing change disables a custom domain |
tenant_auth.session_created | A learner authorizes and opens a session on a school host |
tenant_auth.consent_revoked | A learner signs out from a school and revokes its local consent |
tenant_auth.host_revoked | Every learner session for a school host is revoked after a host, slug, or ownership change |
api_key.created | An API key is created |
api_key.revoked | An API key is revoked |
webhook.created | A webhook endpoint is created |
webhook.deleted | A webhook endpoint is deleted |
What is deliberately not recorded
The log is an administrative trail, not a surveillance camera. Two whole categories stay out on purpose:
- Learner activity — progress, quiz attempts, reviews, discussion posts, and completions are learning data, not administration. They live in Insights and reports and on each course's Learners tab.
- Content edits — typing in the editor and saving drafts happen constantly and would drown the feed. Only lifecycle moments — publish, unpublish, delete, listing, ownership — are recorded.
How entries behave
- Append-only — entries cannot be edited or deleted, not even by owners. The trail only grows.
- Actor and before/after — every entry names who acted (or System), and update events keep both values: the old one reads muted, the new one in medium weight.
- Never in the way — recording is best-effort and happens after the action succeeds; the audit trail never blocks or fails the operation it describes.