Skip to content

Code examples

Copy-paste snippets for the two things every integration does first — check a domain, then walk an authenticated list. No SDKs yet; the API is small enough that 15 lines of fetch / requests does the job.

Terminal window
curl -sG https://api.igregulator.io/v1/check \
--data-urlencode 'domain=paddypower.com' | jq
const res = await fetch(
'https://api.igregulator.io/v1/check?domain=paddypower.com'
);
const { verdict, verdict_detail, match } = await res.json();
// Branch on `verdict`, quote `verdict_detail`. Only two values mean licensed now.
switch (verdict) {
case 'licensed':
console.log(`Licensed: ${verdict_detail}`);
break;
case 'licensed_provisional':
// In force, provisionally (a Curaçao licence under the CGA's final assessment):
// accept it if your policy does, say so, and check again later.
console.log(`Licensed, provisionally — recheck: ${verdict_detail}`);
break;
default:
// licence_not_active, domain_not_listed, related_host_listed, name_match_only,
// not_found, generic_term — and any value added later. Not confirmed as
// licensed by the registers we cover. That is NOT "unlicensed": send it to a
// person, with the sentence.
console.log(`Not confirmed (${verdict}): ${verdict_detail}`);
}
// The fields behind the verdict, for a citation: the regulator and the page that
// published the licence status. (KH, TGC and IOM publish no licence number: when
// match.license_reference_is_ours is true, license_number is our reference.)
if (match?.status_source_url) {
console.log(`Source: ${match.regulator_name} — ${match.status_source_url}`);
}
import requests
r = requests.get(
'https://api.igregulator.io/v1/check',
params={'domain': 'paddypower.com'},
timeout=5,
)
r.raise_for_status()
data = r.json()
verdict, detail = data['verdict'], data['verdict_detail']
if verdict == 'licensed':
print(f'Licensed: {detail}')
elif verdict == 'licensed_provisional':
# In force, provisionally: accept per your policy, say so, and recheck later.
print(f'Licensed, provisionally — recheck: {detail}')
else:
# Every other value (and any added later): not confirmed as licensed by the
# registers we cover. Not "unlicensed" — review it, quoting the sentence.
print(f'Not confirmed ({verdict}): {detail}')
match = data.get('match')
if match and match.get('status_source_url'):
print(f"Source: {match['regulator_name']} — {match['status_source_url']}")
const KEY = process.env.IGREGULATOR_KEY;
const BASE = 'https://api.igregulator.io';
async function* paginate(jurisdiction) {
let offset = 0;
const limit = 200;
while (true) {
const r = await fetch(
`${BASE}/v1/jurisdictions/${jurisdiction}/operators?limit=${limit}&offset=${offset}`,
{ headers: { Authorization: `Bearer ${KEY}` } },
);
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const body = await r.json();
if (body.operators.length === 0) return;
for (const op of body.operators) yield op;
offset += body.operators.length;
}
}
for await (const op of paginate('UKGC')) {
console.log(op.slug, op.display_name);
}
import os, requests
KEY = os.environ['IGREGULATOR_KEY']
BASE = 'https://api.igregulator.io'
session = requests.Session()
session.headers['Authorization'] = f'Bearer {KEY}'
def paginate(jurisdiction):
offset, limit = 0, 200
while True:
r = session.get(
f'{BASE}/v1/jurisdictions/{jurisdiction}/operators',
params={'limit': limit, 'offset': offset},
timeout=10,
)
r.raise_for_status()
rows = r.json()['operators']
if not rows:
return
for op in rows:
yield op
offset += len(rows)
for op in paginate('UKGC'):
print(op['slug'], op['display_name'])

Bulk domain verification — rate-limit aware

Section titled “Bulk domain verification — rate-limit aware”

If you’re verifying a list of 500 domains as part of a nightly sweep, POST /v1/check/batch does it in 5 requests (100 domains each). One GET /v1/check per domain works too: authenticate and sleep between requests to stay under your plan’s per-second limit (Starter 5 req/s). Simpler than retry-on-429.

import os, time, requests
KEY = os.environ['IGREGULATOR_KEY']
DOMAINS = open('domains.txt').read().splitlines()
S = requests.Session()
S.headers['Authorization'] = f'Bearer {KEY}'
for d in DOMAINS:
r = S.get(
'https://api.igregulator.io/v1/check',
params={'domain': d}, timeout=5,
)
if r.status_code == 429:
reset = int(r.headers.get('X-RateLimit-Reset', 0))
wait = max(1, reset - int(time.time()))
time.sleep(wait + 1)
r = S.get(
'https://api.igregulator.io/v1/check',
params={'domain': d}, timeout=5,
)
r.raise_for_status()
body = r.json()
# Only 'licensed' and 'licensed_provisional' (in force, provisionally —
# recheck) mean licensed now; everything else goes to review, with the
# sentence. Never record a miss as "unlicensed".
ok = body['verdict'] in ('licensed', 'licensed_provisional')
print(d, 'OK' if ok else 'REVIEW', body['verdict'], '—', body['verdict_detail'])
time.sleep(0.25) # < 4 req/s: headroom under Starter's 5 req/s