Two jobs: resolve vs search
A licence is a regulator-issued authorisation held by a company. The License API mirrors the Company API split (ADR-0027):
- Resolve (
GET /licenses/resolve) — "I know a licence number (orlicense_ref); give me the authoritative licence." Returns the full record: status, type, authorized domains, and the issuing company'scompany_refso you can pivot straight intocompanies/resolve. - Search (
GET /licenses/search) — "I have criteria; give me ranked candidate licences." Returns thin discovery rows. Preview the size and cost first withGET /licenses/search/preview.
$ help --topic=license-refEvery licence carries an opaquelicense_ref(e.g.igfl_8KQn2RrVez4pMb0xWcT3). It is the stable follow-up handle: store it and pass it back toresolve. Treat it as a black box — do not parse it, sort by it, or construct refs from it. It is not an internal database id. A re-issued/superseded licence redirects its ref to the successor (ref_status: "redirected"); a withdrawn licence retires it.
Resolve a licence
Provide a natural key, or an opaque license_ref:
license_ref— authoritative and exclusive. Any natural identifiers sent alongside it are treated as assertions; a disagreement returns409 conflicting_lookup_input(charge 0).license_number(+ optionaljurisdiction) — licence uniqueness is(jurisdiction, license_number), so a bare number matching multiple jurisdictions returns409 ambiguous_license_numberwithmatches[](charge 0); resend withjurisdiction.
GET /v1/licenses/resolve
COST 3 credits / profile returned
Resolve a licence by its natural key or license_ref to the authoritative licence profile. Charged per profile successfully returned.
/v1/licenses/resolve
Authorization
Query
Opaque public handle (igfl_…). Authoritative and exclusive.
Licence number; pair with jurisdiction when a bare number is ambiguous.
mga, ukgc, curacao, anjouan
Hard cost ceiling. Rejected (402) before any payload if exceeded.
Example response200
{
"success": true,
"data": {
"resolved_by": "license_number",
"query": { "license_number": "039698", "jurisdiction": "ukgc" },
"input_license_ref": null,
"resolved_license_ref": "igfl_8KQn2RrVez4pMb0xWcT3",
"ref_status": "active",
"matches": [],
"licenses": [
{
"license_ref": "igfl_8KQn2RrVez4pMb0xWcT3",
"jurisdiction": "ukgc",
"license_number": "039698",
"status": "active",
"license_type": "Remote Casino",
"authorized_domains": [
{ "domain_ref": "igfd_4kL8…", "domain": "888casino.com", "inferred_geo": null },
{ "domain_ref": "igfd_7pQ2…", "domain": "888.com", "inferred_geo": null }
],
"issuing_company": {
"company_ref": "igfc_3uSBTwEXnRo1rfvmRs6fgdMr",
"company_name": "888 UK Limited",
"role": ["operator"]
},
"first_seen_at": "2024-02-11T00:00:00Z",
"last_confirmed_at": "2026-06-20T00:00:00Z"
}
],
"billing": { "returned_count": 1, "credits_per_profile": 3, "credits_charged": 3 }
}
}
Search licences
Ranked discovery over the licence universe. Filter by jurisdiction, license_status, license_type, or the issuing Company's public role; full-text q matches licence number, issuing company name, jurisdiction, and type. An exact domain q uses the current published PostgreSQL links and may add domain_match_basis: exactly regulator_published, site_corroborated, or both. The key is omitted for non-domain hits. Rows are thin — they carry the license_ref, the issuing company_ref, facets, and an authorized_domain_count, but never the full authorized_domains[] list, observed hostname, proof, evidence, receipt, manifest, artifact, or candidate data.
GET /v1/licenses/search
COST 1 credit / result returned
Ranked licence discovery rows. Charged per row returned. Preview size and cost first with /licenses/search/preview.
/v1/licenses/search
Authorization
Query
Full-text query (licence number, company name, jurisdiction, type).
Facet filter: mga, ukgc, curacao, anjouan
Facet filter: active, suspended, revoked, expired, unknown
Facet filter on licence type
Public role of the issuing Company
Rows per page (capped at 100).
Example response200
{
"success": true,
"data": {
"total": 42,
"page": 1,
"page_size": 20,
"hits": [
{
"license_ref": "igfl_8KQn2RrVez4pMb0xWcT3",
"license_number": "039698",
"jurisdiction": "ukgc",
"license_status": "active",
"license_type": "Remote Casino",
"company_ref": "igfc_3uSBTwEXnRo1rfvmRs6fgdMr",
"company_name": "888 UK Limited",
"role": ["operator"],
"authorized_domain_count": 2,
"domain_match_basis": "regulator_published",
"rank": 1
}
],
"billing": { "returned_count": 1, "credits_per_result": 1, "credits_charged": 1 }
}
}
Preview search (free)
GET /licenses/search/preview returns total_count, low-cardinality facet counts, per-page cost estimates, and a tiny redacted sample — charge 0 (free of credits, but still requires your API key like every License endpoint). For exact-domain queries the sample may include the same bounded domain_match_basis enum; it is omitted otherwise. Preview never returns license_ref/company_ref, authorized domains, or private evidence. Preview first, then choose a paid page_size.
Pivot: licence → company
Every resolved licence and every search row carries the issuing company_ref. Pass it to GET /companies/resolve?company_ref=… to get the full operator profile. Conversely, a Company profile's nested licenses[] carry their license_ref.
Billing
licenses/search is charged per row returned (licenses_search_result); licenses/resolve per licence profile returned (licenses_resolve_profile, ≥ 3× the search row). Preview is free. Charging is on success — empty/ambiguous/not_found responses charge 0. Retries carrying the same Idempotency-Key replay the original charge.