Developer docs
The age verification stats API
The numbers on your Stats page, from code. How many checks a wallet answered, why attempts were refused, where people dropped off and how the pass rate moved, for your whole organisation or one project. The same five reads answer an AI assistant through the MCP server.
Signup is open and a test project works as soon as you create one. Create an account to make a key.
Which key
Every read takes a key as a Bearer token, and the key decides whose checks it reads.
- A project key with Full access reads its own project's stats, as well as starting checks.
- A project key with Stats only reads its project's stats and nothing else. Give this one to a
dashboard or an agent: used to start a check, it gets
403 insufficient_scope. - An organisation stats key reads every project in the organisation, or one of them with
project_id. Make one on the Developer page, under Organization stats keys.
The five reads
Each is a GET under https://api.tessio.eu/v1/stats. A read your
plan does not include answers 403 with
plan_feature_unavailable and the feature that would admit it.
| Route | What it answers | Plan |
|---|---|---|
/v1/stats/summary | Checks, pass rate, fail rate, no answer rate and time to result for a period, beside the period of equal length before it. | Every plan |
/v1/stats/timeseries | One metric per bucket: checks, passed, under_age, failed, expired or pass_rate. Buckets are hours for two days or less, then days, weeks or months as the period grows. | Starter and up |
/v1/stats/failures | Refused presentations by reason category, such as the person declining, an issuer that is not trusted or an expired credential. Optionally split by method. | Growth and up |
/v1/stats/funnel | How far the checks got: created, a wallet answered, completed. For EU Digital Identity Wallet requests, also how many were fetched by a wallet. | Growth and up |
/v1/stats/breakdown | The checks grouped by one column, each group with its outcomes: project, api_key, method, transport, format or mode. | Growth and up |
Parameters
-
fromandto: UTC days asYYYY-MM-DD, both inclusive. Omit both for the last 30 days, or omittofor up to today. A period may reach back up to two years. -
mode:live,testorall. An organisation key reads live checks unless told otherwise; a project key reads its project's own mode. project_id: an organisation key only, to read one project.metric: the time series only, andchecksunless you name another.-
group_by: required on the breakdown, and optional on failures, where the only value ismethod.
An example
curl "https://api.tessio.eu/v1/stats/summary?from=2026-09-01&to=2026-09-30" \
-H "Authorization: Bearer tk_your_stats_key" Rates are fractions of the checks that ended, so a check still open counts in neither the pass rate nor the fail rate. The figures here are an example.
{
"mode": "live",
"current": {
"from": "2026-09-01",
"to": "2026-09-30",
"outcomes": { "total": 1240, "passed": 951, "underAge": 142, "failed": 0,
"expired": 147, "pending": 0, "noAnswer": 120 },
"passRate": 0.7669,
"failRate": 0.1145,
"noAnswerRate": 0.0968,
"p50Seconds": 22,
"p95Seconds": 40
},
"previous": { "from": "2026-08-02", "to": "2026-08-31", "...": "the same fields" },
"retention": { "recordsFrom": null, "eventsFrom": null }
} The time series takes the same period and answers one value per bucket:
curl "https://api.tessio.eu/v1/stats/timeseries?metric=pass_rate&from=2026-09-01" \
-H "Authorization: Bearer tk_your_stats_key" When a period reaches past what your plan keeps
Check records and check timelines are deleted when your plan's period passes, as the
privacy policy
sets out. Every answer carries retention: when
recordsFrom or eventsFrom is a date, the days before it
count only what is still held, so a drop there is the purge and not your traffic. Failures and the funnel read
the timelines, which are kept for less time than the checks.
Errors and limits
-
400with the parameter it is about:invalid_from,invalid_to,range_inverted,range_too_old,range_too_long,invalid_mode,invalid_metric,invalid_group_byorinvalid_project_id. A project outside your organisation answersinvalid_project_id, exactly as one that does not exist. 401the key is missing, invalid or revoked.403 plan_feature_unavailablethe read is not in your plan.-
429the key's budget is spent; wait for theRetry-Afterheader. Each key has a budget of 30 requests that refills at one every two seconds, shared by the API and the MCP server.
Rather ask than query?
Connect an AI assistant to the MCP server with the same key and ask it how your checks did last month.
The MCP server →