Skip to main content

Usage metering

What a tenant did, per day, counted from the rows that record it.

There is no pricing here. These are counts and measured model costs. What they are worth is a commercial question and deliberately lives nowhere near the code that answers what happened.

What is metered​

MeterSource tableMeaning
alertsalertsAlerts created in the window
triages_modelalertsAlerts carrying model-generated triage output
triages_deterministicalertsAlerts resolved without model output
investigationsinvestigation_runsAgent investigation runs started
llm_tokensaisoc_run_costsPrompt plus completion tokens
llm_cost_usdaisoc_run_costsMeasured model spend
actionsaisoc_action_recordsResponse actions recorded
actions_executedaisoc_action_recordsOf those, the ones that reached a vendor
active_connectorsconnectorsEnabled data sources, right now
seatsusersActive user accounts, right now

triages_model and triages_deterministic partition alerts exactly: their sum equals the total, so there is no triage unaccounted for and none counted twice.

The last two are point-in-time rather than windowed. Counting them per day would report today's value against every historical day, which looks like data and is not.

What is not measured​

events_ingested lives in the ClickHouse event lake, which runs in the full profile. On a deployment without it, that meter is reported as not measured, named with the reason, in both the API response and the CSV header.

It is never reported as 0. Zero is a measurement, and a reader who sees it concludes no events arrived rather than that nothing looked.

Reading it​

curl "https://<your-aisoc-host>/api/v1/usage?start=2026-03-01&end=2026-03-31" \
-H "Authorization: Bearer $AISOC_SESSION_TOKEN"

Defaults to the last 30 days. The maximum window in one request is 186 days; export a month at a time beyond that.

The response carries the daily series, the totals, the point-in-time figures, the meters' own definitions and source tables, whatever was not measured, and the entitlement headroom those counts run against. The last of those is deliberate: a usage screen and a quota screen that compute their numbers separately are two surfaces that will eventually disagree in front of a customer.

The tenant comes from your credential. There is no tenant parameter on any of these routes, because usage is the input to a commercial conversation and a surface that let one customer name another's tenant would publish their volume.

Monthly CSV​

curl "https://<your-aisoc-host>/api/v1/usage/export.csv?month=2026-03" \
-H "Authorization: Bearer $AISOC_SESSION_TOKEN" -o march.csv

Requires reports:read. The file carries a header block naming the tenant, the operator organisation and the generation time, because a bare grid of numbers in a downloads folder cannot answer what it is about.

Checking the numbers​

Metering is computed from the source tables when you ask, rather than kept in a counter table that is incremented as things happen. A counter drifts from the table it summarises and nothing notices; a query cannot, because the number is the rows.

You can verify that directly:

curl "https://<your-aisoc-host>/api/v1/usage/reconciliation?start=2026-03-01&end=2026-03-31" \
-H "Authorization: Bearer $AISOC_SESSION_TOKEN"

This runs each meter twice, once per day and summed, and once as a single query over the whole window, and reports both figures with whether they agree. Day boundaries are where a row gets dropped or counted twice, and neither shows up in a single-day check.

The same comparison runs in CI against a seeded corpus, including an alert placed at exactly midnight.