All licences for an operator
GET /v1/operators/{slug}/licenses
Every licence record we hold for the operator, in every status, sorted by jurisdiction_code, license_number — the whole list in one response (not paginated). Append ?include_history=true to embed the status-change timeline under each licence; omit for the slimmer detail view. Agents that want a cross-jurisdiction compliance view should call this instead of the single-licence endpoint.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”The operator’s slug, from /v1/operators/search or a /v1/check match’s operator_slug. Case-insensitive.
Query Parameters
Section titled “Query Parameters ”When true, each licence includes its status-change history[].
Responses
Section titled “ Responses ”All of the operator’s licences.
object
object
The licence number as the regulator’s register prints it — except for KH (Kahnawake), TGC (Tobique) and IOM (Isle of Man), whose registers publish none. For those three it is an iGregulator reference we assign: KH/IG/<slug> or KH/CSPA/<slug>, TGC/B2C/<slug> or TGC/B2B/<slug>, IOM/OGRA/<company key>. The reference is stable and /v1/check?license_number= accepts it, but no regulator issued it: do not present it to a user as the licence number.
true when license_number is an iGregulator reference, not a number the regulator published — every KH, TGC and IOM licence (their registers publish none). Never present such a reference to a user as the licence number. Same field as on a /v1/check match.
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.
Canonical licence status. Only active means “licensed right now”. Every other value is “not a pass” — but three of them are not enforcement decisions, and a rule that lumps them in with revoked publishes a claim about a real business that no regulator made.
not_in_register — the regulator’s public register no longer lists this licence, since not_listed_since. An observation about the register, not a decision by the regulator: licences drop off because they expired, were surrendered, were renumbered, or the page had a bad day. Nobody published a reason and we do not invent one. It is not a revocation. (Until 2026-09-17 we reported this as revoked; that was wrong, every affected record has been corrected, and its history says so.)
surrendered — the operator gave the licence up (UKGC publishes “Surrendered”; Kahnawake “voluntary termination … in good standing”; the Isle of Man GSC, on its Former Licence Holders list, “Surrendered”). Also not an enforcement decision: nobody took it away. 627 UKGC licences carried revoked for this until 2026-09-17.
unknown — the register lists this licence and published a status we could not classify: a new phrase, a reworded sentence, a typo. We do not guess: two of our scrapers used to default an unreadable status to active, and that is precisely the bug this value exists to make impossible. Read upstream_status for the regulator’s own words.
None of these is a synonym for any other:
- None of them means “not licensed” in the enforcement sense. Do not present them as such.
- None of them means “probably fine”. Do not treat them as a pass.
A rule like if (status === "revoked") block() will silently let surrendered, not_in_register and unknown through. If your flow makes an automated allow/deny decision, approve only on active and escalate everything else to a human.
revoked and suspended are only ever set from a regulator publication we actually read — an enforcement register, a revoked-licences page, an explicit status column — never from a licence disappearing. (The Isle of Man’s Former Licence Holders list says Cancelled for a licence the Commission cancelled under s.13 of the Online Gambling Regulation Act 2001; we store that as revoked.)
When status is right but not the whole truth; same field as on a /v1/check match. provisional_under_assessment: a Curaçao licence the CGA register reads as “Assessment in progress” past its stated term — active, because the CGA keeps such a licence in force until it decides, but a decision is outstanding and expiry_date may already be past. Derived from the regulator’s wording on every read. null otherwise.
Multi-valued type vocabulary, sourced verbatim from the regulator. Stable values per jurisdiction (audited 2026-04-21):
- UKGC —
Remote,Non-Remote,Ancillary Remote - MGA —
Type 1,Type 2,Type 3,Type 4,B2B,B2C - CW (Curaçao) —
B2C,B2B - KH (Kahnawake) —
Interactive Gaming Permit,CSPA - AN (Anjouan) —
B2C,B2B,White Labeling - TGC (Tobique) —
B2C,B2B - IOM (Isle of Man) —
Full,Network Services,Software Supply(the Online Gambling Regulation Act 2001 licence types, as the register writes them)
Add a new value to your client mapping when a regulator publishes one — we don’t reject unknown strings. Multi-jurisdiction operators carry one license row per jurisdiction, so this array is per-licence.
When the regulator’s public register stopped listing this licence (first pull that missed it) — the date behind status: not_in_register. null = listed in the most recent pull. An observation about the register, not a regulator decision: it does not mean revoked. A licence can briefly carry this while still active (one missed pull, inside our grace window).
Cross-jurisdiction harmonised category — derived by @igregulator/normalizer so a multi-regulator query can group by it. UKGC Remote, MGA Type 1/2, CW B2C, IOM Full map to remote; UKGC Non-Remote to non-remote; IOM Network Services and Software Supply to ancillary; etc.
As the register gives it: a calendar date, YYYY-MM-DD (no time, no zone).
As the register gives it: a calendar date, YYYY-MM-DD. A past date next to status: active is normal for a provisional_under_assessment licence (see status_qualifier).
When our scraper last reconciled this record against its register.
The register this licence is listed in. Not necessarily where its current status came from — cite status_source_url for that.
The page that published THIS status — provenance is per status, not per licence. Often not the register in source_url: a Curaçao or Anjouan revocation comes from the regulator’s enforcement / revoked-licences page, a Kahnawake termination from its advisory notice, an MGA status from the licensee’s verification page. Cite this, not source_url, when you explain a non-active status. null for a status set before we tracked provenance.
The latest read of status_source_url that still said this status. When the status CHANGED is in the licence history (/v1/licenses/{license_id}/history), not here. null when status_source_url is.
The last time we saw this licence listed in its register. With not_listed_since it reads “no longer listed since X; last seen listed on Y”. null when we have no such read on record.
Scraper-specific fields captured verbatim from the upstream register (e.g. UKGC activity categories, CGA company-type flags). Not a stable integration surface. Keys here are added, renamed, or removed without a deprecation window when a scraper is updated — they do not carry the 90-day Sunset guarantee that top-level fields do. Use license_types, license_category, status, issued_date, expiry_date for stable compliance logic; read raw_data only for diagnostic / investigative purposes.
object
Point-in-time status, present only when ?as_of= was supplied. Answers ONLY within the observation window: we never extrapolate a status before tracking_since (the first time we recorded the licence).
object
The resolved instant (UTC). A bare YYYY-MM-DD resolves to the end of that day; today’s date resolves to now.
observed: the date is within our window, status is known. corrected: the event in effect on that date is one we later WITHDREW (see correction) — status is null. We do not report the withdrawn status, and we do not fall back to the one before it either: neither is something we observed for that date. before_tracking: the date predates when we started watching — status is null, NOT a guess. no_such_license: we have no history for this licence. no_license_resolved: a fuzzy /v1/check match with no specific licence to time-travel.
Licence status as of the date, or null when not observed.
The history transition in effect at the date — when this status was last confirmed relative to the query.
object
Present only when knowledge is corrected. The event that was in effect at the date and that we later withdrew. withdrawn_status is what we USED to say — never quote it as the status.
object
Lower bound of our knowledge — when we first observed this licence.
Only with ?include_history=true: every event for this licence, most recent first.
object
Canonical licence status. Only active means “licensed right now”. Every other value is “not a pass” — but three of them are not enforcement decisions, and a rule that lumps them in with revoked publishes a claim about a real business that no regulator made.
not_in_register — the regulator’s public register no longer lists this licence, since not_listed_since. An observation about the register, not a decision by the regulator: licences drop off because they expired, were surrendered, were renumbered, or the page had a bad day. Nobody published a reason and we do not invent one. It is not a revocation. (Until 2026-09-17 we reported this as revoked; that was wrong, every affected record has been corrected, and its history says so.)
surrendered — the operator gave the licence up (UKGC publishes “Surrendered”; Kahnawake “voluntary termination … in good standing”; the Isle of Man GSC, on its Former Licence Holders list, “Surrendered”). Also not an enforcement decision: nobody took it away. 627 UKGC licences carried revoked for this until 2026-09-17.
unknown — the register lists this licence and published a status we could not classify: a new phrase, a reworded sentence, a typo. We do not guess: two of our scrapers used to default an unreadable status to active, and that is precisely the bug this value exists to make impossible. Read upstream_status for the regulator’s own words.
None of these is a synonym for any other:
- None of them means “not licensed” in the enforcement sense. Do not present them as such.
- None of them means “probably fine”. Do not treat them as a pass.
A rule like if (status === "revoked") block() will silently let surrendered, not_in_register and unknown through. If your flow makes an automated allow/deny decision, approve only on active and escalate everything else to a human.
revoked and suspended are only ever set from a regulator publication we actually read — an enforcement register, a revoked-licences page, an explicit status column — never from a licence disappearing. (The Isle of Man’s Former Licence Holders list says Cancelled for a licence the Commission cancelled under s.13 of the Online Gambling Regulation Act 2001; we store that as revoked.)
Canonical licence status. Only active means “licensed right now”. Every other value is “not a pass” — but three of them are not enforcement decisions, and a rule that lumps them in with revoked publishes a claim about a real business that no regulator made.
not_in_register — the regulator’s public register no longer lists this licence, since not_listed_since. An observation about the register, not a decision by the regulator: licences drop off because they expired, were surrendered, were renumbered, or the page had a bad day. Nobody published a reason and we do not invent one. It is not a revocation. (Until 2026-09-17 we reported this as revoked; that was wrong, every affected record has been corrected, and its history says so.)
surrendered — the operator gave the licence up (UKGC publishes “Surrendered”; Kahnawake “voluntary termination … in good standing”; the Isle of Man GSC, on its Former Licence Holders list, “Surrendered”). Also not an enforcement decision: nobody took it away. 627 UKGC licences carried revoked for this until 2026-09-17.
unknown — the register lists this licence and published a status we could not classify: a new phrase, a reworded sentence, a typo. We do not guess: two of our scrapers used to default an unreadable status to active, and that is precisely the bug this value exists to make impossible. Read upstream_status for the regulator’s own words.
None of these is a synonym for any other:
- None of them means “not licensed” in the enforcement sense. Do not present them as such.
- None of them means “probably fine”. Do not treat them as a pass.
A rule like if (status === "revoked") block() will silently let surrendered, not_in_register and unknown through. If your flow makes an automated allow/deny decision, approve only on active and escalate everything else to a human.
revoked and suspended are only ever set from a regulator publication we actually read — an enforcement register, a revoked-licences page, an explicit status column — never from a licence disappearing. (The Isle of Man’s Former Licence Holders list says Cancelled for a licence the Commission cancelled under s.13 of the Online Gambling Regulation Act 2001; we store that as revoked.)
What we observed, in words — e.g. “No longer listed in the public register since 2026-08-04.”
SHA-256 of the exact payload this change was read from, stored on our side. null for events recorded before 2026-09-17 and for runs whose snapshot could not be filed. Ask support for that payload by hash if you need to audit a claim — a hash you can check against your own copy of the regulator’s page is the point.
When that payload was fetched from the regulator.
Set when a later review found this event asserted something we had not read from the regulator. The event is kept for the audit trail; treat it as withdrawn and read correction_note.
Invalid query / parameters.
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." }}Missing / malformed / revoked API key.
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." }}The key’s plan does not cover this request — canceled or no plan (plan_inactive), or a legacy trial key calling anything but /v1/check and the other endpoints that work without a key (endpoint_requires_paid_plan), or a plan below Pro asking for an export (export_requires_pro). Paid plans are not on sale yet: email founder@igregulator.io and we will sort it out.
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." }}No row matched.
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." }}Rate limit reached. Public endpoints: 10 req / IP / hour — a free API key (no card, 10,000 requests / month) from https://app.igregulator.io/signup lifts it. Authenticated: per plan tier; paid tiers are not open yet, so email founder@igregulator.io for a higher limit. Retry after the window surfaced in X-RateLimit-Reset.
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." }}Headers
Section titled “Headers ”Unix epoch seconds.
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." }}