Headline counts, each with its definition
GET /v1/stats
The numbers the igregulator.io homepage prints: licence records by status,
jurisdictions with their last register read and freshness, operators,
linked domains, brand pages, status changes read in the last 30 days, and
withdrawn events. Every value is a count of what the database holds at
generated_at; the body carries a definitions object saying exactly what
each one counts. Only active in licences.by_status means licensed now.
No key, no per-IP limit. Every caller gets the same payload, recounted
at most every 10 minutes, so it is not metered: the homepage calls it on
every view and a visit must not spend the visitor’s 10 lookups. A key sent
with it is ignored and not charged. Cache-Control: public, max-age=300;
Access-Control-Allow-Origin: *.
Per-jurisdiction last_read_at, age_hours, fresh and sla_hours follow
the same rule as /v1/health/coverage (24 h for UKGC, AN, TGC, IOM; 48 h for
MGA, CW, KH).
Responses
Section titled “ Responses ”Headline counts.
object
Licence records we hold from the regulators’ registers, in every status. by_status splits them by current status; only active means licensed now.
object
Licence records per current status. Every status is present (0 when none); surrendered and not_in_register are not revocations.
object
Count: regulators we hold at least one licence record for. items: every regulator we cover, with its licence records, how many are active, when we last read its register (the newest last_verified_at among its licences, as /v1/health/coverage reports it), and whether that read is inside its 24 h / 48 h freshness window.
object
Jurisdictions with at least one licence record.
Every jurisdiction we cover, ordered by code. One with no licence records yet has licences: 0 and nulls for the read.
object
Jurisdiction code — UKGC, MGA, CW (Curaçao), KH (Kahnawake), AN (Anjouan), TGC (Tobique) or IOM (Isle of Man). GET /v1/jurisdictions lists them with names and licence types.
Licence records, any status.
Of those, licence records whose status is active.
When we last read this register: the newest last_verified_at among its licences (/v1/health/coverage’s last_successful_scrape).
Whole hours from last_read_at to generated_at.
age_hours < sla_hours. A register we could not read keeps its last good read and turns false; null when never read.
Operators holding at least one licence record, in any status, as each register names them — a company licensed by two regulators can be two operators.
object
Distinct domains with at least one active domain→operator link: a register or a regulator certificate lists the domain for that operator today.
Of those, domains with an active link that carries the regulator’s own per-domain certificate or seal page (Curaçao cert.cga.cw / cert.gcb.cw, Tobique validate.thetgc.ca) — the page /v1/check returns as verification_url.
Domains with a public page at app.igregulator.io/brands/
Licence status changes read from a regulator in the last 30 days: license_history events written by a scraper or the seal re-verifier, not since withdrawn, whose new status differs both from the previous one and from what the last event still standing had set — so a read that only puts a status back after a withdrawn event (the undo of the 2026-09-22 UKGC register flap) is not a change. First sightings, data-only updates and our correction/backfill migrations are excluded.
License_history events we later withdrew as wrong (corrected_at set). They stay on the record with a correction note; none is deleted.
The most recent register read across all jurisdictions (max of jurisdictions.items[].last_read_at). Individual registers can be older — see each item.
When these numbers were counted. The payload is cached for up to 10 minutes.
One sentence per field above, saying what it counts — the same text as this schema.
object
Unexpected server error.
object
Human-readable error summary.
HTTP-status-level class. Stable enum; branch on details.reason for finer control. Current values: invalid_query, invalid_slug, invalid_license_id, invalid_jurisdiction_code, invalid_pagination, not_found, auth_required, auth_invalid, auth_revoked, payment_required, quota_exceeded, rate_limited, server_error.
object
Machine-readable refinement of the top-level code. Stable vocabulary; branch on this in clients. Examples: invalid_input, missing_required_parameter, conflicting_parameters, operator_not_found, license_not_found, jurisdiction_not_found, route_not_found, api_key_missing, malformed_header, api_key_invalid, api_key_revoked, quota_exceeded, export_requires_pro, export_daily_limit_reached, as_of_not_supported, dataset_not_found, internal_error.
Present only when the error maps to a specific request input field (query param, path param, body key). Omitted for errors that aren’t field-scoped (e.g. rate_limited, auth_revoked).
Optional human-readable / agent-actionable hint describing how to resolve the error.
{ "reason": "api_key_revoked", "suggestion": "Generate a new API key at https://app.igregulator.io/api-keys. Revoked keys cannot be restored."}{ "error": "API key has been revoked", "code": "auth_revoked", "details": { "reason": "api_key_revoked", "suggestion": "Generate a new API key at https://app.igregulator.io/api-keys. Revoked keys cannot be restored." }}