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.
Domain check — curl
Section titled “Domain check — curl”curl -sG https://api.igregulator.io/v1/check \ --data-urlencode 'domain=paddypower.com' | jqDomain check — JavaScript (fetch)
Section titled “Domain check — JavaScript (fetch)”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}`);}Domain check — Python (requests)
Section titled “Domain check — Python (requests)”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']}")Walk all UKGC operators — JavaScript
Section titled “Walk all UKGC operators — JavaScript”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);}Walk all UKGC operators — Python
Section titled “Walk all UKGC operators — Python”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