Your geo-check requests and where they stand
Your last 50 requests, newest first, each with its countries: queued, running, in_review (checked; a person is confirming it on the screenshot), done (with check), or failed. Visible only to you.
Authorizations
Section titled “ Authorizations ”Responses
Section titled “ Responses ”Your requests.
object
object
object
object
Answered by a recent check (see its checked_at), not a new one.
What a domain served in one country on one date — an observation, never a licence status.
object
ISO 3166-1 alpha-2. CA is Ontario: probes in Toronto, a browser in Ontario.
reachable — the site was served in the country, and a browser IN that country (one of our proxies, verified to exit there) showed a working gambling site, confirmed on its screenshot. Without such a browser a served page is served_unverified (“Reachable, not verified”; reason: “HTML only, no in-country render”) — never reachable. refused — every probe in the country got HTTP 403, and so did a browser in the country when we had one (a browser that showed the site makes it reachable): what the server answered there, not a statement that it geo-blocks the country (a bot wall answers 403 too). Per country, the latest definite result is shown — refused counts as one, so a newer refused replaces an older reachable; served_unverified only when nothing definite was read, unknown only when nothing else was. geo_blocked — the site said it does not serve that country (HTTP 451, a block page, or its in-browser check’s country list). waf_blocked — a firewall refused the request; not about the country. parked — no gambling site at the domain. unknown — a Cloudflare captcha, an error, or a block we could see only from another country; reason says which. gateway / not_casino — set by the reviewer: a page that only sends visitors on to another domain, or not a gambling site.
Why, in a few words — or the reviewer’s note.
A person looked at the screenshot and set result.
Older than 30 days: request a new check.
A browser in the country itself rendered the page. reachable is only ever set with it.
Where we hold the market’s register (only CA: iGaming Ontario), whether it lists the domain on an active licence — beside the result, never instead of it.
object
Example
ONHeaders
Section titled “ Headers ”Your plan’s monthly request quota (not the per-second limit). Not sent on a plan with no monthly quota (Business, Enterprise).
What is left of the monthly quota, this request counted. Not sent on a plan with no monthly quota.
Unix epoch seconds of the start of the next UTC month. Not sent on a plan with no monthly quota.
tier=unlimited on a plan with no monthly quota; otherwise not sent.
Always https://igregulator.io/pricing.
The monthly request quota of your plan, or unlimited.
Requests counted this UTC month, this one included (a request that ends in 4xx / 5xx is not counted). Not sent when the limit is unlimited.
What is left of the monthly quota. Not sent when unlimited.
When the monthly counter starts again: the first of next month, 00:00 UTC, ISO-8601. Not sent when unlimited.
80% of monthly limit used — sent from 80% of the quota on, absent before.
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." }}Business and Enterprise only.
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": "This endpoint is available on the Business and Enterprise plans", "code": "payment_required", "details": { "reason": "geo_checks_require_business", "required_plan": "business", "available_on": [ "business", "enterprise" ], "plan_tier": "pro", "suggestion": "Geo-check endpoints come with Business (10 domains a month) and Enterprise (bulk). See https://igregulator.io/pricing or email founder@igregulator.io." }}A limit of the key was reached. quota_exceeded / monthly_request_limit_reached: the plan’s monthly request quota — wait for reset_at. rate_limited / per_second_limit_exceeded: more requests in one second than the plan allows — retry after Retry-After (1 s). A request refused here is not counted against the monthly quota.
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": "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 ”On the per-second limit (1). Not on the monthly quota — read details.reset_at.
On the per-second limit only: the requests per second your plan allows.
On the per-second limit only: 0.
On the per-second limit only: Unix epoch seconds of the next second.
On the monthly quota only: the quota of your plan.
On the monthly quota only: requests counted this month.
On the monthly quota only: 0.
On the monthly quota only: when the counter starts again (ISO-8601).
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." }}