Reporting and logs
Counts, outcomes over time, usage, your team's activity, and what we sent your endpoints
Everything a back office renders around the queue. All of it is read-only, and all of it is scoped to the environments the acting seat holds.
Counts and outcomes
GET /v1/console/overview ?mode=&since=
GET /v1/console/analytics ?mode=&since=
GET /v1/console/usage ?mode=&since=overview is the status breakdown and how many are waiting on a reviewer. analytics buckets the
same by day and tells you how many outcomes reached a person at all. usage is what has been
metered, broken out per check and per environment.
Every response echoes the modes it covered. Render that next to the number: a figure that folded
sandbox rehearsals into production volume is the one number somebody is most likely to act on, and it
would be wrong in the flattering direction.
People
GET /v1/console/persons
GET /v1/console/persons/{id}The person behind the verifications, and their attempt history: how many times they have been through, how each ended, and when. It answers "have we seen this customer before".
It carries no identity. persons.read and verifications.reveal are different permissions and a
seat can hold the first alone, so names live on
/verifications/{id}/identity, which is gated and audited separately.
Your team's activity
GET /v1/console/activityWhat your own people have done: who decided what, who looked at whom, who changed a setting. Each row
carries surface, which is console or backoffice, so you can tell where somebody was working.
Applicant details are never in this list, whatever the underlying event touched.
Logs
GET /v1/console/logs/requests
GET /v1/console/logs/deliveries ?status=&event=
GET /v1/console/logs/deliveries/{id}
POST /v1/console/logs/deliveries/{id}/replayrequests is every API call your keys made, with the key's name, the status and the timing. The IP is
truncated when we store it and is never complete.
deliveries is every webhook we sent you, with the attempts, the response code and the error.
Delivery bodies are gated, and they are not where identity lives
The list is metadata. The body of a delivery is on the single-delivery endpoint and needs
verifications.reveal as well as logs.read. Without that permission the fields are simply absent
from the response rather than null, so you can tell "not shown to you" from "nothing to show". Every
body we return writes an audit row naming the person who asked.
It is gated because the reason codes are our judgement about a real person, and because the response
body is your own server replying and can contain anything you put in it. It is not gated because
the payload carries a name. No webhook we send carries applicant identity, and there is no setting,
on your side or ours, that adds identity to a payload. An outcome body is the session id, the verdict,
the status, the decline type and the reason codes, and nothing else. To read who the applicant is, ask
for it explicitly on the verification itself with
?include=applicant,documents.
Replaying re-arms the delivery and the worker sends it, with the normal retry ladder and backoff. It does not send from your request, so it will not block on your own endpoint's latency. A delivery whose endpoint has been deleted or disabled cannot be replayed.
Exports
POST /v1/console/exports/verifications
{ "since": "2026-08-01T00:00:00Z", "include_identity": false }
POST /v1/console/exports/usageBoth return CSV directly. They need verifications.export and usage.export, and the first of those
already requires verifications.reveal, so an owner cannot hand somebody exports without also handing
them the identity card.
Identity is off by default and must be asked for with include_identity. A volume report should
not put names into your warehouse, and from there into everything that reads your warehouse, because
nobody thought about it. The two forms are audited as different events.
Exports are capped at 5,000 rows. X-Rows and X-Truncated tell you what you got, so you can page
with since rather than quietly reporting on a slice.