List all covered jurisdictions
The regulators whose registers we read — fourteen today: UKGC, MGA, CW, KH, AN, TGC, IOM, ON, SE, ES, BE, DE, CO, UA — ordered by code, each with its name, country code, website, currency and a reference list of licence categories (license_types — read its note before validating anything against it). Use it for a jurisdiction picker or to turn a code into a name. For when each register was last read, see GET /v1/health/coverage. No key needed: without one 10 requests / IP / hour; a valid key sent with it is honoured.
Responses
Section titled “ Responses ”Every covered jurisdiction, ordered by code.
object
object
Jurisdiction code — UKGC, MGA, CW (Curaçao), KH (Kahnawake), AN (Anjouan), TGC (Tobique), IOM (Isle of Man), ON (Ontario — the iGaming Ontario operator directory), SE (Sweden — online gaming and betting licences from the Spelinspektionen register, nothing else), ES (Spain — the DGOJ’s state-level online licences; not the state lotteries (SELAE, ONCE) or regional land-based gambling), BE (Belgium — the Gaming Commission’s online licence classes A+, B+ and F1+ only; not land-based licences or the Loterie Nationale), DE (Germany — the GGL whitelist’s four internet game types (virtual slots, online poker, sports betting, online horse betting); not a Land’s online casino permits, lotteries or land casinos), CO (Colombia — Coljuegos’ online gaming concessions only; not land-based gaming (juegos localizados) or the lotteries), UA (Ukraine — PlayCity’s online casino, online poker and bookmaking licences only; not land casinos or slot halls or the state lotteries). GET /v1/jurisdictions lists them with their names.
The name of the body whose register we read — the same string /v1/check returns as match.regulator_name. That is the regulator everywhere but ON: there it is iGaming Ontario, which publishes the operator directory; the regulator that registers Ontario operators is the Alcohol and Gaming Commission of Ontario (AGCO). Do not write “licensed by iGaming Ontario”.
ISO 3166-1 alpha-2 (KM for Anjouan, CA for Kahnawake, Tobique and Ontario).
The regulator’s site — for AN, TGC, IOM, ON, SE, ES, DE and CO the register page itself, for BE the Gaming Commission’s licences page (which links the register’s three lists), for UA PlayCity’s home page (which links the register PDF), for the others the home page. Not necessarily the page a licence’s source_url cites.
ISO 4217 code of the jurisdiction’s currency (ANG for Curaçao).
A reference list of the regulator’s licence categories, set by hand when we added the jurisdiction. Do not validate a licence’s license_types against it: for UKGC, CW, AN, TGC, IOM and SE the two use the same words, but for MGA (licences carry Type 1–Type 4 or the class) and KH (licences carry Interactive Gaming Permit / CSPA) they do not; for ON the list is empty, as is every Ontario licence’s (the directory prints no licence type); for ES the list is the three general licences (Apuestas, Concursos, Otros juegos) — the words of a licence’s license_type_raw — while its license_types are the singular licences under it (Ruleta, Póquer, …); for BE (A+, B+, F1+) and DE (Virtuelle Automatenspiele, Online-Poker, Sportwetten, Pferdewetten im Internet) the list is the classes and game types we load, the same words as a licence’s; for CO it is the one concession type we load, Juegos operados por internet; for UA the three licence types we load, in English (Online casino, Online poker, Bookmaking), the same words as a licence’s. The values licence records really carry are listed on License.license_types.
Example
{ "code": "UKGC", "name": "UK Gambling Commission", "country_code": "GB", "website": "https://www.gamblingcommission.gov.uk", "currency": "GBP", "license_types": [ "Remote", "Non-Remote", "Ancillary Remote" ]}Headers
Section titled “ Headers ”Without a key: 10 — requests per IP per clock hour on THIS endpoint (each keyless endpoint has its own counter). With a valid key these three X-RateLimit-* headers describe your monthly quota instead, and the X-Monthly-Quota-* headers are sent too — see any keyed endpoint.
Requests left this hour, this one counted. A refused request (400) counts.
Unix epoch seconds of the top of the next UTC hour, when the counter starts again.
tier=public;limit=10;window=hour without a key; tier=authenticated with one.
The same limit in the IETF draft form, "default";q=10;w=3600. Not sent on a keyed call.
Always https://igregulator.io/pricing.
The API key is missing, malformed, unknown or revoked. On an endpoint that works without a key this is only ever sent when a key WAS sent and is not valid — drop the header, or fix the key.
The body of every non-2xx response.
object
Human-readable summary. The wording can change; do not branch on it.
The error class. Mostly one per HTTP status, with two exceptions to know: quota_exceeded is a 429 for the monthly request quota and a 403 for a plan cap (watchlist size, webhook endpoints). A 409 carries conflict (it carried invalid_query before 1.24.0). Branch on the HTTP status and details.reason. forbidden is only ever sent to a signed-in MCP connection, never to an API key.
Always present. reason is always set; field and suggestion when they apply; limit errors add the numbers below.
object
Machine-readable refinement of the top-level code — branch on this. Values: invalid_input, missing_required_parameter, conflicting_parameters, not_a_valid_hostname, hostname_too_long, invalid_pagination, invalid_cursor, since_exceeds_retention_window, invalid_event_type, invalid_jurisdiction, as_of_not_supported, api_key_missing, malformed_header, api_key_invalid, api_key_revoked, plan_inactive, plan_ended, export_requires_pro, geo_checks_require_business, watchlist_quota_exceeded, webhook_quota_exceeded, operator_not_found, license_not_found, jurisdiction_not_found, webhook_not_found, dataset_not_found, route_not_found, method_not_allowed, watchlist_duplicate, no_active_secret, quota_exceeded, monthly_request_limit_reached, per_second_limit_exceeded, watchlist_events_poll_limit, export_daily_limit_reached, geo_check_quota_exceeded, internal_error. A rejected webhook URL carries the SSRF check’s reason (invalid_url, invalid_scheme, empty_host, blocked_hostname, unresolvable_host, private_ip_blocked). New values can be added.
Present only when the error maps to a specific request input (query param, path param, body key). Omitted for errors that aren’t field-scoped (e.g. rate_limited, auth_revoked).
A hint a person or an agent can act on. Present on every error today.
On a limit error (429, and the 403 plan caps): the ceiling that was reached.
On a keyed limit error: how much of limit is used. Not on the keyless per-IP 429 or the watchlist-poll 429.
When the counter starts again — on the keyless per-IP 429, the monthly quota, the watchlist-poll limit and the export daily limit. Not on the per-second limit (retry after one second).
The key’s plan, on plan-scoped limit errors and on export_requires_pro.
On export_requires_pro: the lowest plan that includes the feature.
On watchlist_events_poll_limit: always hour.
Examples
{ "error": "Authorization header required", "code": "auth_required", "details": { "reason": "api_key_missing", "suggestion": "Attach an API key: `Authorization: Bearer <key>`. No key yet? Start a 14-day free trial of Starter (card required) at https://app.igregulator.io/signup; an existing account creates keys at https://app.igregulator.io/api-keys." }}{ "error": "Authorization header must be \"Bearer <key>\"", "code": "auth_invalid", "details": { "reason": "malformed_header", "suggestion": "Header format: `Authorization: Bearer <your-api-key>`." }}{ "error": "API key not recognized", "code": "auth_invalid", "details": { "reason": "api_key_invalid", "suggestion": "Double-check the key. Create a new one at https://app.igregulator.io/api-keys if the previous one was deleted." }}{ "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." }}Only when a key was sent and its account has no plan or a canceled one (plan_inactive), or its plan’s end date has passed (plan_ended). The same request without the Authorization header is answered (within the per-IP limit).
The body of every non-2xx response.
object
Human-readable summary. The wording can change; do not branch on it.
The error class. Mostly one per HTTP status, with two exceptions to know: quota_exceeded is a 429 for the monthly request quota and a 403 for a plan cap (watchlist size, webhook endpoints). A 409 carries conflict (it carried invalid_query before 1.24.0). Branch on the HTTP status and details.reason. forbidden is only ever sent to a signed-in MCP connection, never to an API key.
Always present. reason is always set; field and suggestion when they apply; limit errors add the numbers below.
object
Machine-readable refinement of the top-level code — branch on this. Values: invalid_input, missing_required_parameter, conflicting_parameters, not_a_valid_hostname, hostname_too_long, invalid_pagination, invalid_cursor, since_exceeds_retention_window, invalid_event_type, invalid_jurisdiction, as_of_not_supported, api_key_missing, malformed_header, api_key_invalid, api_key_revoked, plan_inactive, plan_ended, export_requires_pro, geo_checks_require_business, watchlist_quota_exceeded, webhook_quota_exceeded, operator_not_found, license_not_found, jurisdiction_not_found, webhook_not_found, dataset_not_found, route_not_found, method_not_allowed, watchlist_duplicate, no_active_secret, quota_exceeded, monthly_request_limit_reached, per_second_limit_exceeded, watchlist_events_poll_limit, export_daily_limit_reached, geo_check_quota_exceeded, internal_error. A rejected webhook URL carries the SSRF check’s reason (invalid_url, invalid_scheme, empty_host, blocked_hostname, unresolvable_host, private_ip_blocked). New values can be added.
Present only when the error maps to a specific request input (query param, path param, body key). Omitted for errors that aren’t field-scoped (e.g. rate_limited, auth_revoked).
A hint a person or an agent can act on. Present on every error today.
On a limit error (429, and the 403 plan caps): the ceiling that was reached.
On a keyed limit error: how much of limit is used. Not on the keyless per-IP 429 or the watchlist-poll 429.
When the counter starts again — on the keyless per-IP 429, the monthly quota, the watchlist-poll limit and the export daily limit. Not on the per-second limit (retry after one second).
The key’s plan, on plan-scoped limit errors and on export_requires_pro.
On export_requires_pro: the lowest plan that includes the feature.
On watchlist_events_poll_limit: always hour.
Examples
{ "error": "Active subscription required", "code": "payment_required", "details": { "reason": "plan_inactive", "suggestion": "Current plan_tier: canceled — this account has no active plan. Renew or choose a plan at https://app.igregulator.io/billing (by card, or by invoice for three months or more; Starter starts with a 14-day free trial, card required), or email founder@igregulator.io." }}{ "error": "Plan ended", "code": "payment_required", "details": { "reason": "plan_ended", "suggestion": "This account's business plan ended on 2027-01-22 (UTC). Keys and settings are kept; email founder@igregulator.io to renew." }}Without a key: the per-IP limit of this endpoint, 10 requests per hour (rate_limited / quota_exceeded) — every keyless endpoint has its own counter, a refused request (400) counts, and an API key lifts it — Starter (10,000 requests / month) starts with a 14-day free trial, card required, at https://app.igregulator.io/signup. With a key: the limits of the key — see the key_* examples.
The body of every non-2xx response.
object
Human-readable summary. The wording can change; do not branch on it.
The error class. Mostly one per HTTP status, with two exceptions to know: quota_exceeded is a 429 for the monthly request quota and a 403 for a plan cap (watchlist size, webhook endpoints). A 409 carries conflict (it carried invalid_query before 1.24.0). Branch on the HTTP status and details.reason. forbidden is only ever sent to a signed-in MCP connection, never to an API key.
Always present. reason is always set; field and suggestion when they apply; limit errors add the numbers below.
object
Machine-readable refinement of the top-level code — branch on this. Values: invalid_input, missing_required_parameter, conflicting_parameters, not_a_valid_hostname, hostname_too_long, invalid_pagination, invalid_cursor, since_exceeds_retention_window, invalid_event_type, invalid_jurisdiction, as_of_not_supported, api_key_missing, malformed_header, api_key_invalid, api_key_revoked, plan_inactive, plan_ended, export_requires_pro, geo_checks_require_business, watchlist_quota_exceeded, webhook_quota_exceeded, operator_not_found, license_not_found, jurisdiction_not_found, webhook_not_found, dataset_not_found, route_not_found, method_not_allowed, watchlist_duplicate, no_active_secret, quota_exceeded, monthly_request_limit_reached, per_second_limit_exceeded, watchlist_events_poll_limit, export_daily_limit_reached, geo_check_quota_exceeded, internal_error. A rejected webhook URL carries the SSRF check’s reason (invalid_url, invalid_scheme, empty_host, blocked_hostname, unresolvable_host, private_ip_blocked). New values can be added.
Present only when the error maps to a specific request input (query param, path param, body key). Omitted for errors that aren’t field-scoped (e.g. rate_limited, auth_revoked).
A hint a person or an agent can act on. Present on every error today.
On a limit error (429, and the 403 plan caps): the ceiling that was reached.
On a keyed limit error: how much of limit is used. Not on the keyless per-IP 429 or the watchlist-poll 429.
When the counter starts again — on the keyless per-IP 429, the monthly quota, the watchlist-poll limit and the export daily limit. Not on the per-second limit (retry after one second).
The key’s plan, on plan-scoped limit errors and on export_requires_pro.
On export_requires_pro: the lowest plan that includes the feature.
On watchlist_events_poll_limit: always hour.
Examples
{ "error": "Public rate limit reached (10/hour/IP).", "code": "rate_limited", "details": { "reason": "quota_exceeded", "suggestion": "Start a 14-day free trial of Starter (card required) at https://app.igregulator.io/signup for an API key — 10,000 requests/month, no per-IP cap — and send it as \"Authorization: Bearer <key>\". Or wait until reset_at, the top of the next hour (UTC; also the X-RateLimit-Reset header).", "limit": 10, "reset_at": "2026-10-08T01:00:00.000Z" }}{ "error": "Monthly quota exceeded", "code": "quota_exceeded", "details": { "reason": "monthly_request_limit_reached", "current_usage": 10000, "limit": 10000, "reset_at": "2026-11-01T00:00:00.000Z", "plan_tier": "starter", "suggestion": "Wait until the monthly reset (reset_at). Higher limits: Pro and Business, by card or by invoice (three months or more) — https://app.igregulator.io/billing, or email founder@igregulator.io." }}{ "error": "Per-second rate limit reached", "code": "rate_limited", "details": { "reason": "per_second_limit_exceeded", "current_usage": 6, "limit": 5, "plan_tier": "starter", "suggestion": "Your plan allows 5 req/s. Back off for a second and retry. Higher limits: Pro and Business, by card or by invoice (three months or more) — https://app.igregulator.io/billing, or email founder@igregulator.io." }}Headers
Section titled “ Headers ”Without a key: 10 — requests per IP per clock hour on THIS endpoint (each keyless endpoint has its own counter). With a valid key these three X-RateLimit-* headers describe your monthly quota instead, and the X-Monthly-Quota-* headers are sent too — see any keyed endpoint.
Requests left this hour, this one counted. A refused request (400) counts.
Unix epoch seconds of the top of the next UTC hour, when the counter starts again.
tier=public;limit=10;window=hour without a key; tier=authenticated with one.
The same limit in the IETF draft form, "default";q=10;w=3600. Not sent on a keyed call.
Always https://igregulator.io/pricing.
Unexpected server error. Safe to retry.
The body of every non-2xx response.
object
Human-readable summary. The wording can change; do not branch on it.
The error class. Mostly one per HTTP status, with two exceptions to know: quota_exceeded is a 429 for the monthly request quota and a 403 for a plan cap (watchlist size, webhook endpoints). A 409 carries conflict (it carried invalid_query before 1.24.0). Branch on the HTTP status and details.reason. forbidden is only ever sent to a signed-in MCP connection, never to an API key.
Always present. reason is always set; field and suggestion when they apply; limit errors add the numbers below.
object
Machine-readable refinement of the top-level code — branch on this. Values: invalid_input, missing_required_parameter, conflicting_parameters, not_a_valid_hostname, hostname_too_long, invalid_pagination, invalid_cursor, since_exceeds_retention_window, invalid_event_type, invalid_jurisdiction, as_of_not_supported, api_key_missing, malformed_header, api_key_invalid, api_key_revoked, plan_inactive, plan_ended, export_requires_pro, geo_checks_require_business, watchlist_quota_exceeded, webhook_quota_exceeded, operator_not_found, license_not_found, jurisdiction_not_found, webhook_not_found, dataset_not_found, route_not_found, method_not_allowed, watchlist_duplicate, no_active_secret, quota_exceeded, monthly_request_limit_reached, per_second_limit_exceeded, watchlist_events_poll_limit, export_daily_limit_reached, geo_check_quota_exceeded, internal_error. A rejected webhook URL carries the SSRF check’s reason (invalid_url, invalid_scheme, empty_host, blocked_hostname, unresolvable_host, private_ip_blocked). New values can be added.
Present only when the error maps to a specific request input (query param, path param, body key). Omitted for errors that aren’t field-scoped (e.g. rate_limited, auth_revoked).
A hint a person or an agent can act on. Present on every error today.
On a limit error (429, and the 403 plan caps): the ceiling that was reached.
On a keyed limit error: how much of limit is used. Not on the keyless per-IP 429 or the watchlist-poll 429.
When the counter starts again — on the keyless per-IP 429, the monthly quota, the watchlist-poll limit and the export daily limit. Not on the per-second limit (retry after one second).
The key’s plan, on plan-scoped limit errors and on export_requires_pro.
On export_requires_pro: the lowest plan that includes the feature.
On watchlist_events_poll_limit: always hour.
Example
{ "error": "Internal server error", "code": "server_error", "details": { "reason": "internal_error", "suggestion": "Retry with exponential backoff (1s / 2s / 4s). If the error persists past 4 seconds, surface failure state to the user instead of looping." }}