# Getting started

URL: https://igregulator.io/docs/getting-started/
Markdown: https://igregulator.io/docs/getting-started.md

> Make your first iGregulator API call in under a minute: check a casino domain's gambling licence with curl, no API key needed, then read status and source.

The fastest path to a working integration. You won't need an API key for
this walk-through — the `/v1/check` endpoint is public at 10 requests per
IP per hour.

## 1. Send your first request

```bash
curl https://api.igregulator.io/v1/check?domain=bet365.com
```

Response:

```json
{
  "query": { "domain": "bet365.com" },
  "verdict": "licensed",
  "verdict_detail": "bet365.com is listed, as of our read on 2026-09-30, on an active UK Gambling Commission licence held by Hillside (UK Gaming) ENC (licence 055149-R-331499-004); see jurisdictions[] for this domain's 2 other operator links.",
  "match": {
    "confidence": "high",
    "match_type": "domain_exact",
    "operator": "Hillside (UK Gaming) ENC",
    "operator_slug": "hillside-uk-gaming-enc",
    "jurisdiction": "UKGC",
    "regulator_name": "UK Gambling Commission",
    "license_id": "ea65fd0a-7434-45db-9ac5-8ae5de967423",
    "license_number": "055149-R-331499-004",
    "license_reference_is_ours": false,
    "status": "active",
    "status_source_url": "https://www.gamblingcommission.gov.uk/downloads/business-licence-data.zip",
    "status_observed_at": "2026-09-30T03:00:24.581Z",
    "expires_at": null,
    "domain_association": "direct",
    "domain_status": "active",
    "matched_domain": "bet365.com",
    "domain_last_listed_at": "2026-09-30T03:00:24.582Z",
    "upstream_status": "Active",
    "status_qualifier": null,
    "verification_url": null,
    "verification_page_status": null,
    "verification_page_read_at": null
  },
  "alternatives": [],
  "jurisdictions": [
    {
      "operator": "Hillside (UK Gaming) ENC", "jurisdiction": "UKGC", "license_reference_is_ours": false,
      "status": "active", "status_qualifier": null, "domain_status": "active", "verification_url": null,
      "register": { "jurisdiction": "UKGC", "last_read_at": "2026-09-30T03:00:26.364Z", "fresh": true, "sla_hours": 24 }
    },
    {
      "operator": "Hillside (UK Sports) ENC", "jurisdiction": "UKGC", "license_reference_is_ours": false,
      "status": "active", "status_qualifier": null, "domain_status": "active", "verification_url": null,
      "register": { "jurisdiction": "UKGC", "last_read_at": "2026-09-30T03:00:26.364Z", "fresh": true, "sla_hours": 24 }
    },
    {
      "operator": "Hillside (New Media Malta) Plc", "jurisdiction": "MGA", "license_reference_is_ours": false,
      "status": "expired", "status_qualifier": null, "domain_status": "active", "verification_url": null,
      "register": { "jurisdiction": "MGA", "last_read_at": "2026-09-30T03:34:21.577Z", "fresh": true, "sla_hours": 48 }
    }
  ],
  "confidence": "high",
  "_meta": {
    "scraped_at": "2026-09-30T03:00:24.581Z",
    "source_modified_at": null,
    "source_url": "https://www.gamblingcommission.gov.uk/downloads/business-licence-data.zip",
    "confidence_hint": "authoritative",
    "checked_at": "2026-09-30T18:48:03.561Z",
    "register": { "jurisdiction": "UKGC", "last_read_at": "2026-09-30T03:00:26.364Z", "fresh": true, "sla_hours": 24 }
  }
}
```

That's it — no signup, no key. (`jurisdictions[]` rows are trimmed here; each
also carries `operator_slug`, `license_number`, `domain_association`,
`matched_domain` and `verification_page_status` / `verification_page_read_at`.)

**Read `verdict` first**: it puts `status`, `domain_status`, `status_qualifier`
and `confidence` together into one answer — `licensed`, `licensed_provisional`,
`licence_not_active`, `domain_not_listed`, `related_host_listed`,
`name_match_only`, `not_found` or `generic_term` — and `verdict_detail` says it
in one sentence you can quote as it stands (it names the regulator, never calls
anything "unlicensed", and scopes a miss to the registers we cover). Only
`licensed` and `licensed_provisional` mean licensed now; treat every other value
as "not confirmed as licensed" and show the sentence:

```js
const { verdict, verdict_detail } = await (
  await fetch('https://api.igregulator.io/v1/check?domain=bet365.com')
).json();
const ok = verdict === 'licensed' || verdict === 'licensed_provisional';
// licensed_provisional: in force, provisionally — say so, and check again later.
console.log(ok ? 'licensed' : `not confirmed (${verdict})`, '—', verdict_detail);
```

The `match` object is the detail behind the verdict;
`alternatives[]` populates when we're not 100% sure, and the optional
`jurisdictions[]` array appears when more than one (operator,
jurisdiction) pair licenses the domain — bet365.com is held by several
Hillside entities at once, each row with its own licence status and the
freshness of its own register (`register`). Where the regulator publishes a
per-domain verification page (Curaçao certificate, Tobique seal),
`match.verification_url` links straight to it. See
[confidence scoring](https://igregulator.io/docs/confidence/) for the semantics.

`www.bet365.com` gets the same answer: a host and its `www.` counterpart are the
same site, and `match.matched_domain` names the one the register lists. Any other
subdomain (`sports.bet365.com`) is not the listed host — it answers
`related_host_listed`, with the hosts that are listed in `related_hosts[]`
([which host answers](https://igregulator.io/docs/confidence/#which-host-answers--exact-www-then-the-rest-of-the-domain)).

**`confidence` is about the match, not the licence.** `confidence: high` means we
are sure *which* licence this domain belongs to — read `status` for whether that
licence is any good, and `domain_status` for whether it still covers this site
(`delisted` = the regulator no longer lists the domain on it). Only `active`
means licensed now: the third row above is a high-confidence match to an
`expired` MGA licence. `verdict` does this reading for you, for `match`.

To cite the answer: `match.regulator_name` names the regulator,
`match.status_source_url` is the page that published the status and
`match.status_observed_at` the latest read of it that still said so;
`match.domain_last_listed_at` is when a regulator source last listed the domain
on that licence (`null` once it is de-listed — we keep no "de-listed since"
time). `_meta.register` says when we last read that register and whether the
read is inside its freshness window (24 h or 48 h, as on
`/v1/health/coverage`); on a miss, `_meta.stale_jurisdictions` lists the
registers past theirs. For since when a licence has been unlisted
(`not_listed_since`, `last_listed_at`) and its history, pass `match.license_id`
to `GET /v1/licenses/{id}`. `_meta.checked_at` is when the answer was computed.

## 2. Verify by licence number

Compliance teams often receive a licence number from a regulator and
need the reverse lookup — who holds it and what's its status? Same
endpoint, different query param:

```bash
curl "https://api.igregulator.io/v1/check?license_number=055148-R-331498-002"
```

Returns the same `{ query, verdict, verdict_detail, match, alternatives,
confidence }` shape, with `match.match_type: "license_number"`; `confidence: high`
when the licence number is in a register we cover, and `verdict` is about the
licence alone (`licensed`, `licensed_provisional` or `licence_not_active` — there
is no domain to be listed). On a miss `confidence` is absent (treat it as
`none`): `verdict` is `not_found`, `match` is `null`, with
`match_absence_reason: "no_record_found"` and the `checked_jurisdictions` we
searched. Pass `?domain=` **or** `?license_number=`, not both.

The number is matched on its letters and digits alone — case, spaces and
separators don't matter, so `mga/b2c/775/2019` and `MGA B2C 775 2019` both find
`MGA/B2C/775/2019`.

The UK Gambling Commission steps the last part of a number when it varies a
licence (`055148-R-331498-001` became `…-002`), and its register prints only the
latest. An **earlier** number of a licence we hold still finds it: `match` is the
licence as the register lists it now, `superseded_number` says so —
`{ "requested": "055148-R-331498-001", "current": "055148-R-331498-002", "note": "…" }`
— and `verdict_detail` opens with that note. A number *later* than the one we hold
is not resolved: the register has not shown it to us.

Kahnawake, Tobique and the Isle of Man publish no licence number. For their
licences, `license_number` is an iGregulator reference (`KH/IG/…`,
`TGC/B2C/…`, `IOM/OGRA/…`) and `match.license_reference_is_ours` is `true` — it
round-trips through this endpoint, but it is not a number the regulator issued;
look those operators up by domain or name.

## 3. Try a name match

```bash
curl https://api.igregulator.io/v1/check?domain=coral.com
```

No register we cover lists `coral.com` or any other host on it, but its name is a
trading name in the UKGC register, so the trading-name fallback finds an operator
— and says that is all it is:

```json
{
  "query": { "domain": "coral.com" },
  "verdict": "name_match_only",
  "verdict_detail": "We hold no licence that lists coral.com; its name closely resembles a trading name of Ladbrokes Betting & Gaming Limited, whose UK Gambling Commission licence is active — a name match, not evidence that this domain is theirs.",
  "match": {
    "confidence": "medium",
    "match_type": "trading_name_fuzzy",
    "operator": "Ladbrokes Betting & Gaming Limited",
    "license_number": "001611-R-319348-018",
    "status": "active",
    "domain_status": null
  },
  "alternatives": [
    { "operator": "LC International Limited", "matched_name": "coral", "similarity": 1 }
  ],
  "confidence": "medium"
}
```

(Trimmed.) `status: active` here is Ladbrokes Betting & Gaming Limited's licence,
not a finding about `coral.com` — which is why the verdict is `name_match_only`,
not `licensed`. Both entities carry the trading name "Coral" at similarity `1.0`,
so the primary pick falls through a documented tiebreaker cascade — see
[confidence scoring → Tiebreaking](https://igregulator.io/docs/confidence/#tiebreaking-for-equal-similarity).

## 4. Graduate to authenticated requests

When you hit the 10-per-hour ceiling, or you need:

- Higher volume (10k / 100k / unlimited depending on tier)
- The authenticated endpoints: `/v1/operators/:slug`, `/v1/licenses/*`
- Full search results (unauthenticated search caps at 3 rows)

[Create a free account](https://app.igregulator.io/signup) — founding
members get the full Starter plan free, no card. Generate a key at
[app.igregulator.io/api-keys](https://app.igregulator.io/api-keys) and
attach it with a Bearer header:

```bash
curl -H "Authorization: Bearer YOUR_KEY" \
  https://api.igregulator.io/v1/operators/search?q=paddy
```

## 5. Explore interactively

Paste any endpoint into the **[API playground](https://igregulator.io/docs/playground/)** on this
site — it's a Scalar-powered try-it-out that runs against the live
production API. For authenticated endpoints, paste your key into the
Authorize dialog and execute without leaving the page.

## Stability guarantees

All `/v1/*` endpoints are **maintained indefinitely**. When `/v2/*` lands,
both versions will run in parallel for a minimum of 12 months. Individual
fields inside v1 get at least **90 days notice** before removal, surfaced
via the `Deprecation` ([RFC 9745](https://www.rfc-editor.org/rfc/rfc9745))
and `Sunset` ([RFC 8594](https://www.rfc-editor.org/rfc/rfc8594)) response
headers. No field is deprecated today, so neither header is sent. Full
policy in the [changelog](https://igregulator.io/docs/changelog/).

## Next

- [Authentication](https://igregulator.io/docs/authentication/) — how to create + rotate keys.
- [Rate limits](https://igregulator.io/docs/rate-limits/) — quotas, headers, 429 handling.
- [Code examples](https://igregulator.io/docs/code-examples/) — JS/Python snippets.
