"Audit log"

Tether records who changed what in each organisation and project. Admins and owners can read it from **Organisation settings → Audit log** (every project) or a project's **Settings → Audit log** (that project only).

What's recorded

Area Actions
Deploys deploy.functions, deploy.schema
Environments environment.create, environment.delete, environment.update, environment.default.update, environment.export, environment.domains.update, environment.auth_provider.update
Keys environment.key.regenerate, environment.publishable_key.create, environment.publishable_key.revoke, api_key.create, api_key.rotate, api_key.revoke, db_token.create, db_token.revoke
Projects project.create, project.rename, project.settings.update, project.transfer, project.delete
Members member.join, member.leave, member.remove, member.role.update
Invites invite.create, invite.resend, invite.revoke
Organisation organisation.create, organisation.rename, organisation.delete
Account oauth_app.create, oauth_app.update, oauth_app.delete, oauth_app.secret_rotate, oauth.consent, oauth.access_revoke, device.approve, device.deny, session.revoke (in your personal organisation's log)
Access access.denied: a request from a signed-in person or key that its role or scopes didn't allow
Configuration env_var.set, env_var.delete, cron.create, cron.update, cron.delete, cron.trigger, backup.create, backup.delete, backup.restore, backup.download, backup.config.update, bridge.*, rls.*, logs.clear
Data data.table.delete, data.sql (SQL console), data.exec; and data.row.insert, data.row.update, data.row.delete, asset.delete when a person makes the change

Successful changes are recorded, and so are denied attempts. Ordinary reads, function calls and data written by API keys aren't, so the log stays readable.

Entries are kept for 400 days.

Tamper evidence

Each entry stores a hash that covers the entry and the one before it in the same organisation. Changing or deleting an entry breaks the chain from that point on. Check it with:

GET /api/v1/organisations/{id}/audit/verify

It returns { "intact": true }, or { "intact": false, "firstAlteredEntry": "<id>" }.

Each entry has:

  • actor: the person (user), API key (api_key), OAuth app (oauth_app) or publishable key that made the change
  • action and target (for example the cron id, table name or invited email address)
  • project and environment, where relevant
  • details such as the old and new role
  • the caller's IP address and the time

Variable values, keys and other secrets are never written to the log.

Filtering

Filter by activity type, who made the change (people, API keys or OAuth apps), project, environment and date range. Entries are newest first; Load older entries pages back through history.

API reference

GET /api/v1/organisations/{id}/audit
GET /api/v1/projects/{id}/audit

Both need the admin or owner role and accept these query parameters:

Parameter Meaning
action An exact action, or a prefix ending in . such as environment.
actorType user, api_key, oauth_app or publishable_key
actorId A user id or scoped key id
projectId Organisation log only
environment Environment name
from, to Dates (2026-10-01) or RFC 3339 times; to is exclusive
before Return entries older than this time (use nextBefore from the previous page)
limit 1 to 500, default 100
{
  "entries": [
    {
      "id": "...",
      "projectId": "...",
      "environment": "production",
      "actor": { "type": "user", "id": "...", "name": "Sam Taylor" },
      "action": "deploy.functions",
      "target": null,
      "createdAt": "2026-10-18T09:12:44.381Z"
    }
  ],
  "nextBefore": null
}