Skip to content

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).

Headline counts.

object
licences
required

Licence records we hold from the regulators’ registers, in every status. by_status splits them by current status; only active means licensed now.

object
total
required
integer
by_status
required

Licence records per current status. Every status is present (0 when none); surrendered and not_in_register are not revocations.

object
active
integer
suspended
integer
revoked
integer
expired
integer
pending
integer
unknown
integer
surrendered
integer
not_in_register
integer
key
additional properties
integer
jurisdictions
required

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
count
required

Jurisdictions with at least one licence record.

integer
items
required

Every jurisdiction we cover, ordered by code. One with no licence records yet has licences: 0 and nulls for the read.

Array<object>
object
code
required

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.

string
name
required
string
licences
required

Licence records, any status.

integer
active
required

Of those, licence records whose status is active.

integer
last_read_at
required

When we last read this register: the newest last_verified_at among its licences (/v1/health/coverage’s last_successful_scrape).

string format: date-time
nullable
age_hours
required

Whole hours from last_read_at to generated_at.

integer
nullable
fresh
required

age_hours < sla_hours. A register we could not read keeps its last good read and turns false; null when never read.

boolean
nullable
sla_hours
required
integer
operators
required

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.

integer
domains
required
object
linked
required

Distinct domains with at least one active domain→operator link: a register or a regulator certificate lists the domain for that operator today.

integer
regulator_verified
required

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.

integer
brand_pages
required

Domains with a public page at app.igregulator.io/brands/ — the /brands directory total: an active link, a hostname (not a URL with a path), and not a subdomain of another live domain of the same operator.

integer
status_changes_30d
required

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.

integer
corrections
required

License_history events we later withdrew as wrong (corrected_at set). They stay on the record with a correction note; none is deleted.

integer
last_register_read_at
required

The most recent register read across all jurisdictions (max of jurisdictions.items[].last_read_at). Individual registers can be older — see each item.

string format: date-time
nullable
generated_at
required

When these numbers were counted. The payload is cached for up to 10 minutes.

string format: date-time
definitions
required

One sentence per field above, saying what it counts — the same text as this schema.

object
key
additional properties
string

Unexpected server error.

object
error
required

Human-readable error summary.

string
code
required

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.

string
details
required
object
reason
required

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.

string
field

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).

string
suggestion

Optional human-readable / agent-actionable hint describing how to resolve the error.

string
{
"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."
}
}