CapyDB Docs
Operations

Audit log

Every project-affecting action, who did it, and when - the actual event catalog, not an aspirational one.

What gets recorded

Every state-changing action against a project lands in an append-only audit trail. Each event carries:

  • action — a dotted event name from the catalog below
  • actor — who did it: a dashboard user, an API key, a platform operator, or the system itself
  • metadata — action-specific context (job IDs, backup IDs, labels, ticket references)
  • created_at — when

For asynchronous operations, the event is recorded when the action is accepted (the job enqueued), so the trail reflects intent the moment it happens — the job's own success or failure is tracked on the job itself.

Event catalog

These are the events the backend emits today. No others exist.

EventRecorded when
project.deletedProject deletion enqueued
project.credentials_rotatedCredential rotation enqueued
project.restore_overwrite_startedA production-overwrite restore enqueued
project.import_preflightImport preflight run against a source
project.import_upload_createdImport upload slot created
project.import_startedImport enqueued
project.integration.connectedVercel / Netlify / Clerk integration connected
project.integration.upsertIntegration settings created or updated
project.integration.deleteIntegration disconnected
preview.ttl_extendedA preview database's TTL pushed out
restore_point.created / restore_point.deletedRestore point pinned / removed
cutover.requestedCutover request opened
cutover.acked / cutover.rejectedOperator acknowledged / rejected the request
cutover.promote_startedOperator started executing the cutover
production_overwrite_restoreCutover promotion completed (carries the pre-cutover backup ID)
api_key.created / api_key.revokedOrganization or project API key minted / revoked
webhook_endpoint.created / webhook_endpoint.updated / webhook_endpoint.deletedWebhook endpoint lifecycle
webhook_endpoint.secret_rotatedWebhook signing secret rotated
studio.row_inserted / studio.row_updated / studio.row_deletedRow edited through Studio

Worth noticing what is not here: reads. Listing projects, viewing connection strings, and running SELECTs do not generate audit events. The trail answers "who changed what", not "who looked at what".

Viewing the trail

  • Dashboard — the project overview shows recent activity, rendered with friendly actor and action labels.
  • APIGET /v1/projects/{id}/audit-events returns the full trail, newest first, with a limit parameter. See the API reference.
curl -s -H "X-API-Key: $CAPYDB_API_KEY" \
  "https://capydb.dev/api/capydb/v1/projects/$PROJECT_ID/audit-events?limit=50" \
  | jq '.audit_events[] | {action, actor_kind, created_at}'

There is no CLI command for the audit trail today.

Retention and durability

  • No retention window is applied. Events are not pruned on a schedule; the trail persists for the life of the organization.
  • Events survive project deletion. Deleting a project does not erase its audit history — the events remain attached to the organization (with the project reference cleared), so "who deleted it" is itself answerable afterwards.
  • Audit writes on destructive paths are designed not to fail silently: if an audit write ever fails after a destructive action was already accepted, the miss is logged loudly on our side rather than swallowed.

Two trails, two jobs

The audit log records administrative actions against the platform. If you need to know what happened inside the database — slow queries, table activity — that is Observability's job. And if you want events pushed to you instead of queried, webhooks cover lifecycle outcomes.