Audit Log
Every mutation, who did it, and what the record looked like before and after — plus the dashboard stats endpoint.
Quick take
- Every mutation is recorded, including ones the scheduler makes
actionis a bare verb andentity_typeis a noun — not a dottedsubscription.createdbefore_stateandafter_stateare full snapshots; before is null for createsactor_typeisapi,admin, orsystem- 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:
| Parameter | Values |
|---|---|
action | A verb — created, updated, granted, and so on. See the list below. |
entity_type | A noun — subscription, customer, plan. See the list below. |
actor_type | api, admin, or system. |
from / to | Timestamps bounding the search. |
limit | How many entries to return. |
cursor | The pagination.next_cursor from the previous page. |
What an entry holds
| Field | Meaning |
|---|---|
actor_id | Who did it. An API key ID, an admin user ID, or the name of a system job. |
actor_type | api for an API key, admin for the dashboard, system for a scheduler job. |
action | The verb. |
entity_type | The kind of thing that changed. |
entity_id | Which one. |
before_state | The record before the change. Null for creates — there was nothing before. |
after_state | The record after the change. |
environment | live or sandbox. |
created_at | When. |
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_..."
| Field | Meaning |
|---|---|
customer_count | How many customers you have. |
total_balance | Every customer’s balance added together, in millicredits. |
active_subscriptions | How many subscriptions are active. |
credits_consumed_today | Millicredits consumed since midnight UTC. |
credits_consumed_week | Millicredits consumed over a rolling 7 days. |
credits_granted_week | Millicredits 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.
Loading…