Audit log
One log of who did what across your organisation, to search, download as JSON Lines or CSV, and stream to Datadog, Splunk or your own endpoint as it happens.
A project’s history shows changes to its flags. The audit log is the whole organisation’s record, for security reviews and compliance: every change in every project and in the organisation itself, plus the security events that aren’t changes, such as sign-ins and API tokens.
featflags records every organisation’s events on every plan and keeps them as long as the plan keeps history: 7 days on Free, 1 year on Team, 3 years on Business. Reading, downloading and streaming them is on Business, so an upgrade shows the history you already have. Admins and owners read the log; owners manage where it streams.
What’s recorded
- Every change, in every project and in the organisation: flags, targeting, segments, environments, SDK keys, triggers, release plans, experiments, members, invites, domains, SSO settings, the organisation itself. A change that waits for approval or a schedule is recorded at each step: requested, scheduled, approved, rejected, cancelled, failed and applied.
- Sign-ins by your members, through Google, GitHub or SSO, including an owner signing in past enforced SSO. Refused sign-ins that concern you: a disabled user, someone blocked by your enforced SSO, or your identity provider asserting an email at a domain you haven’t verified.
- API tokens created, given other roles and revoked, and AI assistant connections made and disconnected.
- featflags support reading anything in your organisation. Its changes are recorded as changes, under its own name.
- Exports of the organisation’s data and of the audit log itself.
- Webhooks and audit destinations added, changed and removed.
Events carry no IP addresses: featflags doesn’t keep any with your data.
An event
Every event has the same shape in the app, the API, downloads and every destination:
{
"id": 9812,
"time": "2026-10-15T09:00:00Z",
"organization": "acme",
"actor": "token:ci-deploy",
"person": "user:ana@acme.com",
"action": "flag_state.updated",
"target": { "type": "flag_state", "key": "new-checkout/production" },
"project": "web",
"environment": "production",
"outcome": "success",
"change": { "id": 412, "url": "https://app.featflags.io/api/orgs/acme/projects/web/changes/412" },
"comment": "launch",
"details": {}
}
| Field | What |
|---|---|
id |
Increases in the order events happened. Use it to order them and to drop repeats. |
actor |
Who did it: user:<email>, token:<name>, trigger:<name>, experiment:<key>, release-plan:<flag>/<env> for a guarded release, platform:<email> for featflags support. |
person |
The person behind it: the token’s owner, the person who connected an AI assistant, or the actor again. |
action |
What happened, as <type>.<what>: flag_state.updated, member.created, change.approved, session.signed_in, api_token.revoked… |
outcome |
success, or failure for a refused sign-in or a held change that failed. |
change |
The change it records, with a link to it and its diff in the API; null for events that aren’t changes. |
details |
What the action carries, such as a sign-in’s provider or a token’s roles. |
Search and download
Settings → Audit log lists events newest first. Filter by time, by who did it (an email finds that person’s own actions, their tokens’ and their AI assistant’s), by action or type of action (member finds every member event), and by project. Download JSONL and Download CSV export what the filters show, oldest first.
The same from the API, with an admin’s API token:
curl -H "Authorization: Bearer $TOKEN" "$API/audit-log?actor=ana@acme.com&action=flag_state&from=2026-10-01T00:00:00Z" # newest first, paged with before=<id>
curl -H "Authorization: Bearer $TOKEN" "$API/audit-log/export?format=csv&from=2026-10-01T00:00:00Z" -o audit.csv # or format=jsonl
In the CSV, a text field that starts with =, +, - or @ gets a leading ', so a spreadsheet never runs a comment as a formula.
Stream it
Owners send events to a log tool as they happen, under Settings → Audit destinations:
- Datadog: your Datadog site and an API key; events arrive as logs from
featflags. - Splunk: an HTTP Event Collector URL and token.
- HTTPS: any endpoint of yours. Each
POSTcarries{ "events": [...] }, up to 100 events, signed like webhooks with a secret shown once.
A destination gets every event from the moment you add it, in order. If it’s down, events wait for it, retried at most an hour apart, and arrive when it’s back, for as long as your plan keeps them. Each destination shows whether it’s delivering, what’s waiting and its recent attempts, and Send test event checks the setup. Destinations only go to public internet addresses.
Over the API: POST $API/audit-destinations with, for Datadog, { "kind": "datadog", "name": "Datadog", "site": "datadoghq.eu", "api_key": "…" }.
If the organisation moves off Business, existing destinations keep streaming and can be changed or removed; reading the log and adding destinations need Business again.