quotastack Docs
Docs / Concepts / Audit Log

Audit Log

Every mutation, who did it, and what the record looked like before and after — plus the dashboard stats endpoint.

Mental model — The audit log is the ship's logbook. Every change is written down as it happens, with who made it and what the entry looked like before and after. Pages are never torn out — the log is append-only.

Quick take

  • Every mutation is recorded, including ones the scheduler makes
  • action is a bare verb and entity_type is a noun — not a dotted subscription.created
  • before_state and after_state are full snapshots; before is null for creates
  • actor_type is api, admin, or system
  • Filter by action, entity type, actor type, and a time window

Audit Log

Every change QuotaStack makes to your data is written to the audit log. Who did it, what they did, and what the record looked like before and after. The log is append-only: nothing in it is ever updated or deleted.

Old rows are thin. Before 2026-07-31, the log held our own jobs and nothing else. The changelog says why.

Reading it

curl https://api.quotastack.io/v1/audit-log \
  -H "X-API-Key: qs_live_..."

Filters, all optional:

ParameterValues
actionA verb — created, updated, granted, and so on. See the list below.
entity_typeA noun — subscription, customer, plan. See the list below.
actor_typeapi, admin, or system.
from / toTimestamps bounding the search.
limitHow many entries to return.
cursorThe pagination.next_cursor from the previous page.

What an entry holds

FieldMeaning
actor_idWho did it. An API key ID, an admin user ID, or the name of a system job.
actor_typeapi for an API key, admin for the dashboard, system for a scheduler job.
actionThe verb.
entity_typeThe kind of thing that changed.
entity_idWhich one.
before_stateThe record before the change. Null for creates — there was nothing before.
after_stateThe record after the change.
environmentlive or sandbox.
created_atWhen.

Action is a verb, entity_type is a noun

This trips people up, so it is worth being blunt. An action is not a dotted name like subscription.created. Those are webhook event types, and they are a different vocabulary.

In the audit log, the two are separate fields. A created subscription is action: "created" with entity_type: "subscription".

To find every subscription that was cancelled:

curl "https://api.quotastack.io/v1/audit-log?action=canceled&entity_type=subscription" \
  -H "X-API-Key: qs_live_..."

Actions in use: adjusted, canceled, committed, created, deleted, downgraded, granted, imported, paused, released, renewed, reserved, resumed, revoked, updated, upgraded.

Entity types in use: api_key, billable_metric, credit_transaction, customer, plan, plan_credit_grant, plan_variant, plan_variant_entitlement, pricing_rule, reservation, subscription, subscription_entitlement_override, tenant, tenant_config, topup, topup_package.

Note pricing_rule — that is what a metering rule is called in the audit log.

What it is good for

Answering “who changed this?” — the most common use. Filter by entity_type and entity_id and read the trail.

Proving what a record used to be. before_state and after_state are full snapshots. You see the old and new values, not only that something changed.

Watching automated changes. Renewals, expiries, and grants come from the scheduler. Those rows carry actor_type: "system". Filter to those to see what the engine did on its own.

Separating environments. Each entry records its environment. A sandbox test never muddies your live trail.

The dashboard stats endpoint

Related, and much smaller: a single call that returns the counters behind the dashboard home page.

curl https://api.quotastack.io/v1/stats/dashboard \
  -H "X-API-Key: qs_live_..."
FieldMeaning
customer_countHow many customers you have.
total_balanceEvery customer’s balance added together, in millicredits.
active_subscriptionsHow many subscriptions are active.
credits_consumed_todayMillicredits consumed since midnight UTC.
credits_consumed_weekMillicredits consumed over a rolling 7 days.
credits_granted_weekMillicredits granted over a rolling 7 days.

Both week figures are rolling 7 days, not calendar weeks, and the field names have no this in them. Amounts are millicredits, like everywhere else in the API.

Common mistakes

Don't filter with action=subscription.created

Dotted names are webhook event types. In the audit log the verb and the noun are separate fields: action=created&entity_type=subscription.

Don't look for a metering rule under entity_type=metering_rule

It is recorded as pricing_rule.

Don't expect before_state on a create

It is null, because nothing existed before. Only updates and deletes carry a before snapshot.