# UK Gambling Commission Licensed Businesses Scraper (`scrapersdelight/ukgc-gambling-licensees-scraper`) Actor

From $8 per 1,000 rows. Export the UK Gambling Commission business licence register: all 2,642 licensed gambling operators with head-office address, every licence (activity, type, status, dates), every trading name and every domain including White Label brands. Change monitor included.

- **URL**: https://apify.com/scrapersdelight/ukgc-gambling-licensees-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Business, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 per business returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 🎰 UK Gambling Commission Licensed Businesses Scraper

**Every company licensed to run gambling in Great Britain — and, for the first time in one row, which brand and which website each of them actually operates.**

This Actor exports the UK Gambling Commission's **business licence register**: 2,642 licensed operators, joined to all 4,460 of their licences, all 2,408 registered trading names and all 2,231 registered domains, plus the structured head-office address. One denormalised row per company. The complete 2,642-row export runs on Apify in **5.9 seconds** at **256 MB**.

> Every number in this README was measured against the live register on **2026-09-07** (source files' `Last-Modified`: Mon, 07 Sep 2026 04:30:16–18 GMT). Nothing here is estimated.

***

### 📊 What one row contains

| Field | What it is | Measured fill |
|---|---|---|
| `account_number` | UKGC account number — the key in the Commission's own URLs | 2,642 / 100% |
| `licence_account_name` | Legal operator name as licensed | 2,642 / 100% |
| `detail_url` | The Commission's own register page for this business | 2,642 / 100% |
| `status` | **Derived**: `Active` (2,143) · `Pending` (31) · `Ceased` (468) | 100% |
| `address_line_1` | Head-office street | 2,112 / **79.9%** |
| `address_line_2` | Second address line | 1,571 / 59.5% |
| `city` | Head-office town | 2,171 / **82.2%** |
| `postcode` | Head-office postcode | 2,111 / 79.9% |
| `country` | Head-office country, free text as published | 2,169 / 82.1% |
| `is_offshore` | **Derived**: registered outside the UK | 265 true · 1,904 false · **473 null** (471 with no address at all, plus 2 whose address has no country) |
| `address_complete` | False whenever the address is blank *or* the read failed | — |
| `address_source` | `csv` · `zip` · `detail-page` · `none` · `unavailable` | 100% |
| `licences[]` | Licence number, status, type, activity, start date, end date | 4,460 rows |
| `licence_count` · `active_licence_count` | Totals per business | avg **1.69**, max 10 |
| `activities[]` | Distinct licensed activities | 25 in the register, max 7 per business |
| `licence_types[]` | `Remote` · `Non-Remote` · `Ancillary Remote` | — |
| `is_remote` · `is_non_remote` | **Derived** | 1,383 online · 2,011 premises · **752 both** |
| `first_licensed_date` | Earliest licence start — operator tenure | earliest in register: 2007-08-30 |
| `latest_licence_start_date` | Newest licence start — the new-permission trigger | 6 rows future-dated to 2026-10-01 |
| `latest_licence_end_date` | Newest end date — the surrender / revocation trigger | 747 licence rows carry one |
| `trading_names[]` · `active_trading_names[]` | Every brand, and the live ones | 2,408 rows; **1,204 businesses (45.6%)** have ≥1 live brand |
| `domain_names[]` · `active_domains[]` | Every registered domain, and the live ones | 2,231 rows; **480 businesses (18.2%)** have ≥1 live domain |
| `white_label_domains[]` · `has_white_label` | Domains running on **someone else's licence** | 370 domains across **34 businesses (1.3%)** |
| `trading_name_count` · `domain_count` | **Register** totals — they stay at the published count even when you switch the inactive entries out of the arrays | max 52 brands, max **231 domains** on one licence |
| `source_last_modified` | The Commission's own `Last-Modified` header — provenance | 100% |
| `scraped_at` | ISO timestamp of your run | 100% |

In **Monitor** mode each row also carries `changes[]` (`type`, `licence_number`, `activity`, `from`, `to`), `change_count` and `is_new_business`.

***

### 🎯 Why this beats reading the register yourself

**1. The brand → operator → domain map exists nowhere else.** 2,273 distinct trading names and 2,124 distinct domains resolve to 2,642 legal companies. Type `casino` into "Domain contains" and you get every licensed company running a casino site. Type `bingo` into "Trading name contains" and you get the legal entity behind every bingo brand. 89 domains are registered against more than one account — normally a white-label arrangement.

**2. `White Label` is a UKGC-only field and it is the most valuable one on the row.** A white-label domain is a brand trading on another operator's licence. 34 businesses carry one. No commercial company database exposes that relationship; it is a pure statutory artefact.

**3. The structured address is not on the website.** The register's own detail page prints the head office as one concatenated blob. This Actor reads the Commission's **structured** address file — separate street, city, postcode and country columns — which is not linked anywhere on gamblingcommission.gov.uk (see "How it works" below). Scraping the visible pages instead costs 2,642 page fetches (measured at 6.74 pages/second = ~6.5 minutes) for a *worse-shaped* result. This does five file GETs in 1.5 seconds.

**4. The offshore filter, derived honestly.** 265 of 2,642 operators are registered outside the UK: Malta 85, Gibraltar 37, USA 21 (+3 spelled "United States of America"), Isle of Man 18, Ireland 17, Sweden 7, Austria 7, Cyprus 6, Australia 6. 48 distinct country strings in all.

**5. The register moves daily.** All five source files were rebuilt at 04:30 UTC on the day this was measured, and the licence file already carried a 2026-09-04 surrender and six licences dated to start on 2026-10-01.

***

### 🔎 What you can filter on

Everything below is applied to the rows you are actually **delivered and billed for** — never after the fact. If you switch "Address source" to the detail-page crawl, the address filters are re-checked against the addresses that crawl republishes, and any row it re-addresses out of your filter is dropped **before** it is written or charged.

- **Identity** — account numbers · legal name contains · trading name contains · domain contains
- **Licence** — 25 activities · `Remote` / `Non-Remote` / `Ancillary Remote` · 6 licence statuses · derived business status · min/max licences held
- **Brand & web** — has an active trading name · has an active domain · **white-label operators only** · include or drop inactive trading names and domains
- **Geography** — UK / offshore / any · head-office countries (free text, case-insensitive) · city contains · postcode starts with · only businesses with a published address
- **Dates** — first licensed after/before · newest licence started after · a licence ended after
- **Shape** — sort by any of 12 fields · max businesses · drop the nested licence array for a flat CSV · plain dates or full ISO timestamps

#### Live counts you can filter against (2026-09-07)

| Licence status | Rows | | Licence type | Rows |
|---|---:|---|---|---:|
| Active | 3,650 | | Non-Remote | 2,381 |
| Surrendered | 660 | | Remote | 1,535 |
| Pending | 62 | | Ancillary Remote | 544 |
| Revoked - Non Payment of Fee | 52 | | | |
| Lapsed | 28 | | **Domain status** | |
| Revoked | 8 | | Active | 1,067 |
| | | | Inactive | 794 |
| **Top activities** | | | White Label | 370 |
| Society Lottery | 908 | | | |
| General Betting Limited | 535 | | **Trading-name status** | |
| Gaming Machine General AGC | 429 | | Active | 1,891 |
| Gaming Machine Technical Supplier | 398 | | Inactive | 517 |
| Gambling Software | 380 | | | |
| Bingo | 367 | | | |
| Casino | 205 | | | |

***

### 🚀 Example inputs

**The whole register (2,642 rows, 5.9 seconds, $21.14)**

```json
{ "mode": "full" }
```

**Every live online operator with a website — the iGaming operator list**

```json
{ "mode": "full", "remoteOnly": true, "hasActiveDomain": true, "businessStatus": ["Active"] }
```

**White-label brands and whose licence they run on**

```json
{ "mode": "full", "hasWhiteLabelOnly": true }
```

**Offshore operators licensed in Great Britain — the KYC list**

```json
{ "mode": "full", "jurisdiction": "offshore", "businessStatus": ["Active"], "sortBy": "country" }
```

**Who runs this website?**

```json
{ "mode": "full", "domainContains": "888" }
```

**Newly licensed entrants in the last year**

```json
{ "mode": "full", "firstLicensedAfter": "2025-09-01", "sortBy": "first_licensed_date", "sortOrder": "desc" }
```

**Surrenders and revocations — the churn signal**

```json
{ "mode": "full", "licenceStatuses": ["Revoked", "Revoked - Non Payment of Fee", "Surrendered"], "licenceEndedAfter": "2026-01-01" }
```

**Daily change monitor** (put it on a schedule; the first run saves a baseline and delivers 0 rows on purpose)

```json
{ "mode": "monitor" }
```

**A flat spreadsheet with no nested arrays**

```json
{ "mode": "full", "includeLicenceRows": false, "includeInactiveDomains": false, "includeInactiveTradingNames": false }
```

***

### 💵 Pricing

Plain **pay per event**. No actor-start charge, no platform-usage surcharge.

| Event | Price | When it fires |
|---|---:|---|
| `business-scraped` | **$0.008** | Once per business row written to your dataset. **Full export mode only.** |
| `monitor-run-completed` | $0.01 | Once per Monitor run. **Monitor mode only.** |
| `licence-change-detected` | $0.01 | Per licence that is new, newly ended or status-changed since the previous Monitor run — and only on rows you were actually delivered. **Monitor mode only.** |

- **The whole register = 2,642 × $0.008 = $21.14, once.** A filtered slice costs only what it returns.
- Rows your filters removed are **never** charged. `business-scraped` does not fire in Monitor mode, so no business is ever billed twice.
- The **first** Monitor run saves a baseline, delivers 0 rows and charges **no** change events. Billing 4,460 changes for changes that never happened would be the obvious way to get this wrong; it does not do that.
- **Honest volume note:** over the last 30 days the whole register saw **9** licences start and **14** end; over 90 days, 59 and 47; over a year, 289 and 251. Monitor is a *buying-trigger* feed, not a volume product. If you want volume, use Full export.
- Delivery is budget-aware: rows are written and charged atomically, so **delivered always equals billed**. If your `maxTotalChargeUsd` or free-tier balance truncates a run, the status message says so by name — it never blames the Commission for your cap. The run also asserts `delivered == charged` at the end and **fails** rather than finish green on a mismatch.

***

### ⚙️ How it works, and what it does not hide

Five static file GETs, ~945 KB total, largest file 492 KB. Pure HTTP — **no browser, no login, no API key, no CAPTCHA, no residential proxy**, 256 MB.

```
/downloads/business-licence-register-businesses.csv       91,854 B   2,642 rows
/downloads/business-licence-register-addresses.csv       189,468 B   2,642 rows   ← undocumented
/downloads/business-licence-register-licences.csv        492,390 B   4,492 rows
/downloads/business-licence-register-trading-names.csv    82,843 B   2,414 rows
/downloads/business-licence-register-domain-names.csv     88,323 B   2,231 rows
```

All five are joined on `Account Number`. **Join integrity, measured, not assumed:** 2,642 distinct accounts in the licence file with **0 orphans**; 1,498 in trading names, 0 orphans; 627 in domains, 0 orphans; 2,640 in addresses, 0 orphans. **0** businesses have no licence row. Cross-checked against the rendered site: account 39028's own page nav reads *1 Trading name / 90 Domain names* and the files give exactly 1 and 90.

**Verified through the Apify proxy, not from a home IP.** All five files and a detail page were re-fetched through `proxy.apify.com` and came back **byte-identical** (detail page 64,124 bytes both ways). One of six first-pass proxy requests hit a transient CONNECT failure and succeeded on retry — which is why every request here retries with backoff.

#### Six ways this register silently lies, and what this Actor does about each

**1. The address file is not linked anywhere.** The Commission's download page lists four CSVs and says the ZIP holds *"Contents: 4 files"*. The ZIP (`business-licence-data.zip`, 623,627 bytes) actually holds **six**, including `business-licence-register-addresses.csv` — which also serves standalone at a stable URL with a matching `Last-Modified`. An undocumented file can be renamed without notice, so there are three routes: **direct CSV → the copy inside the ZIP → the per-business detail pages**. If all three fail, the run still ships every other field and sets `address_complete=false` on every row. It never reports a gap it created as the source's fault.

**2. The address facet is not one row per business.** 2,642 address rows, but only **2,640 distinct accounts** — accounts 760 and 57464 each appear twice — and **two businesses have no address row at all** (101838 Hammertime Games Limited, 27216 Mr Rigby's Leisuretime Limited). A naive join swallows that silently. Duplicates are dropped and counted; the first distinct row wins.

**3. The bulk files carry exact duplicate rows.** 32 in `licences.csv`, 6 in `trading-names.csv`, 0 in domains, 2 in addresses. Left in, they inflate `licence_count` and `active_licence_count` **on a row you paid for**. They are dropped before billing, and the count is reported in the run log and in `RUN_SUMMARY`. This is why the Actor ships 4,460 licence rows where the Commission publishes 4,492.

**4. A Licence Number is not unique.** **667** licence numbers cover more than one Activity inside the same business (up to six rows share one number). Keying anything on the number alone collapses 1,027 of the 4,460 rows. `(account, licence number, activity)` **is** unique — 0 collisions — and that is what Monitor mode fingerprints, so a status change on a shared number is never missed.

**5. Country is free text.** The register spells home three ways — *United Kingdom* (1,891), *Great Britain* (11), *Northern Ireland* (2) — and carries 48 distinct values, twelve with a state appended (*USA - Nevada*, *Germany - Berlin*). `country !== 'United Kingdom'` would badge 13 domestic operators as offshore. All three domestic spellings are treated as UK. **Gibraltar and the Isle of Man are deliberately *not* domestic**: a British Overseas Territory and a Crown Dependency sit outside the UK, and that is the distinction a compliance buyer is filtering for.

**6. The detail page cannot reproduce the structured address.** Where a business has no address, its register page prints the literal sentinel **"Address not available"** — verified on eight such accounts. This Actor emits `null` and `address_complete=false`, never the sentinel string. And the rendered page joins address line 1 to line 2 with the same `", "` that appears *inside* those lines, so the split is irrecoverable from HTML. On the detail-page route the whole street block ships in `address_line_1` and `address_line_2` is always `null`. Measured against the bulk file over **300 live pages** on the platform: street block **100%**, postcode **100%**, town **99.7%** (one miss collapses a double space in the town name), country **93.0%**. Every country miss is the same shape — a business whose published address is *town + country only*, which the page renders as the bare town, and the parser will not guess which of the two a lone token is. That is **59 of the 2,171** addressed businesses register-wide. Because those rows can no longer satisfy a country or jurisdiction filter, they are dropped before delivery on this route rather than being sold to you as matches — the status message counts them.

#### Monitor mode

State lives in a **named** key-value store (`ukgc-gambling-licensees-monitor-state`), so the previous run's fingerprints survive between scheduled runs; an unnamed store is wiped each run and would make the whole register look new every time. State tracks the **whole** register regardless of your filters — scoping it to a filter would make every row look new the moment you changed one — and your filters then decide what is delivered.

Six change types are reported: `new-business`, `new-licence`, `status-changed`, `licence-ended`, `licence-removed`, `name-changed`, plus `business-removed` for an account that has left the register. If a cap (`maxBusinesses` or your charge limit) holds a changed business back, **its previous fingerprint is kept** so the next run reports it again instead of losing it — and the status message says how many.

***

### 🔒 Data and privacy

This Actor covers **businesses only**. The Commission's separate **personal licence** register (18,627 individual licence holders) is deliberately out of scope and is not fetched.

No director, manager or contact field exists in the source files, so no named natural person is emitted. **However:** some licensees are sole traders or partnerships licensed under a personal name, and their published "head office" may be a home address. The register is published by the Commission for public inspection, but if you are processing these rows under UK GDPR that is your controller obligation, not this Actor's.

Out of scope by design, each a different register surface: **premises licences** (8,866 records, its own file), **personal licences** (18,627), **regulatory actions** (135).

***

### ⚖️ Legal and fair use

`https://www.gamblingcommission.gov.uk/robots.txt`, fetched 2026-09-07, **verbatim**:

```
User-agent: *
Allow: /
Disallow: /about-us/transparency/html/corporate-strategy-2021-to-2024
Disallow: /about-us/guide/our-strategy-for-the-next-three-years
Sitemap: https://www.gamblingcommission.gov.uk/sitemap.xml
```

Neither `Disallow` line touches `/downloads` or `/public-register`. This Actor reads only those two paths.

**Re-use terms, stated plainly because we could not resolve them:** the download page and the site's terms of use do not mention *Open Government Licence*, *OGL*, *Crown copyright*, *re-use* or *commercial use* anywhere we could find. So unlike some UK government datasets, the UKGC publishes this register with **no re-use licence we were able to identify**. That is a copyright and terms question, separate from robots.txt, and **it is yours to judge before you resell or redistribute the data.** We flag it; we do not decide it.

Everything here is a statutory public register the Commission publishes for public inspection. No login is used, no access control is circumvented, and the request rate is five file downloads per run.

***

### 📈 Measured performance

Every figure below is from a run **on the Apify platform**, at 256 MB, through the Apify datacenter proxy.

| | |
|---|---|
| Full 2,642-row export, end to end | **5.9–10.8 s** across five runs · peak memory **73–91 MB** of 256 |
| The 50-row demo input | **3.2–7.8 s** · peak memory 60–69 MB · 50 items · 50 charged |
| Download, all five files | 1.1–1.9 s on the platform |
| Detail-page fallback throughput | **6.7–8.5 pages/s** at concurrency 12; 368 of 368 pages read, 0 failures |
| Platform usage for a full 2,642-row export | **$0.0136** total — dataset writes $0.0132, compute $0.00022, key-value store $0.0001, internal transfer $0.00003. **Residential proxy: $0.00**, because none is used |
| Transport failures | 1 transient proxy CONNECT in 6 first-pass requests; recovered on retry |
| Daily health test | PASS — **4.675 s**, 50 items (re-run on build 0.1.3) |

**Billing verified on the platform, not asserted.** A full run delivered 2,642 rows and charged exactly 2,642 `business-scraped`. A run capped at `maxTotalChargeUsd = $0.10` delivered exactly **12** rows (12 x $0.008 = $0.096), charged 12, and said so: *"Truncated by the charging limit you set (maxTotalChargeUsd / free-tier balance), not by the register."* A first Monitor run delivered 0 rows and charged 1 x `monitor-run-completed` and **zero** change events; the second found no changes and did the same — proving the named store survives between runs.

**Re-verified independently, 2026-09-08, by re-running the live Actor.** 24 filter inputs, each row count predicted from an offline rebuild of the five source files first and then matched **exactly** on the platform, with `delivered == charged` and **zero** secondary events on every one of them: white label 34, offshore 265, UK 1,904, remote+non-remote hybrids 752, Malta 85, Casino 204, Ancillary Remote 531, domain "888" 3, brand "bingo" 63, "entain" 1, postcode W1 37, city Gibraltar 33, revoked 44, min 5 licences 61, max 1 licence 1,392, has address 2,171, live brand 1,204, live domain 480, Pending 31, first licensed since 2025-09-01 141, first licensed to 2010-01-01 936, newest start since 2026-09-01 5, licence ended since 2026-06-01 34, and the three-way offshore+active+online combination 208. Monitor mode was driven against a deliberately doctored baseline: it found all **7** change types, delivered 3 of 8 changed businesses under a $0.10 cap and charged exactly the 9 changes on those 3 rows plus the flat fee (**$0.1000 of $0.10**, not a cent over), held the other 5 back, reported all 5 on the next uncapped run, and then went quiet. A `maxTotalChargeUsd` of $0.005 — below the price of one row — delivered 0 rows, charged nothing, and named the cap.

***

### ❓ FAQ

**Is this the same as the personal licence register?**
No. This is the **business** register — 2,642 licensed companies. Personal licences (18,627 individuals) are a separate register and are not scraped here.

**Does it cover premises — betting shops, arcades, casinos?**
No. Premises licences are a separate register of 8,866 records with its own address and local-authority fields. This Actor covers the licensed *company*, including whether it holds premises-side (`Non-Remote`) licences.

**How do I find out who runs a gambling website?**
Set `domainContains` to the domain. You get the legal operator, its licences, its other brands and whether the domain is flagged **White Label** — i.e. running on someone else's licence.

**What exactly is a "white label" domain?**
A brand operating under another company's UKGC licence. The Commission flags these explicitly: 370 domains across 34 businesses. It is the single hardest relationship in this market to find anywhere else.

**How fresh is the data?**
The Commission rebuilds all five files daily at about 04:30 UTC. Every row carries `source_last_modified` — the `Last-Modified` header of the Commission's own file — so you can prove the age of what you were sold.

**Why does the licence count differ from the Commission's own file?**
Because 32 rows in `licences.csv` are byte-identical duplicates. This Actor drops them, so it ships 4,460 where the Commission publishes 4,492. Leaving them in would inflate `licence_count` on a row you paid for. The count is reported in `RUN_SUMMARY`.

**Why do 471 businesses have no address?**
Because the Commission publishes none for them — their own register pages read "Address not available". Those rows carry `null` and `address_complete=false`, never a placeholder. Crawling the detail pages recovers nothing extra; that was tested.

**Can I get regulatory fines and enforcement actions?**
Not here. The regulatory-actions register is a separate 135-record surface, and finding the ~5% of businesses that have any would force all 2,642 detail-page fetches — destroying the bulk win for a handful of rows. It belongs in its own Actor.

**How much does the whole register cost?**
2,642 rows × $0.008 = **$21.14**, once. There is no start charge and no usage surcharge.

**What does Monitor mode actually deliver?**
Only businesses whose licences changed since the previous Monitor run, with a `changes[]` array saying exactly what moved. Realistically that is a handful per week — 9 licence starts and 14 ends across the whole register in the 30 days to 2026-09-07. It is a trigger feed for a sales or compliance workflow, not a volume product.

**Will the first Monitor run bill me for the whole register?**
No. It saves a baseline, delivers 0 rows and charges zero change events. Only the flat `monitor-run-completed` fee applies.

**What happens if a source file disappears?**
The address file falls back to the Commission's ZIP bundle, then to the detail pages, then degrades to `address_complete=false` with every other field intact. Any of the other four files failing on **both** routes fails the run outright with the file named — because shipping a business with an empty `licences[]` would look exactly like a real ceased operator, and that is a lie you would have paid for.

**Do I need a residential proxy?**
No. The default Apify datacenter proxy was verified to return byte-identical content. Residential would only add cost.

**Can I use my own proxy?**
Yes — the proxy field accepts a custom list.

***

*Not affiliated with, endorsed by, or connected to the Gambling Commission.*

# Actor input Schema

## `mode` (type: `string`):

FULL EXPORT returns every business that matches your filters — the whole 2,642-business register in about 20 seconds if you set no filters at all. MONITOR returns only the businesses whose licences changed since this Actor's previous monitor run, so you can put it on a daily schedule and get a short diff instead of the whole file. The very first monitor run saves a baseline, delivers 0 rows and charges no change events; the run after that starts reporting changes. Measured change volume over the register: 9 new + 14 ended licence rows in the last 30 days, 59 + 47 over 90 days, 289 + 251 over a year — so Monitor is a buying-trigger feed, not a high-volume one.

## `maxBusinesses` (type: `integer`):

Hard cap on how many business rows are returned and billed. 0 = no cap (the whole matching set — 2,642 rows if you set no filters). The cap is applied AFTER sorting, so 'Max businesses 100' + 'Sort by latest licence start, descending' gives you the 100 most recently licensed operators, not a random 100.

## `accountNumbers` (type: `array`):

Look up specific businesses by their UK Gambling Commission account number — the number in the register URL, e.g. 39028 for https://www.gamblingcommission.gov.uk/public-register/business/detail/39028. Leave empty to scan the whole register.

## `nameContains` (type: `string`):

Case- and accent-insensitive substring of the LEGAL operator name, e.g. 'entain', 'flutter', 'limited'. This is the registered company name, not the brand — use 'Trading name contains' below for brands.

## `tradingNameContains` (type: `string`):

Case-insensitive substring of any TRADING NAME the business is registered under — the brand a punter actually sees. This is the reverse lookup that makes this Actor useful: type 'bingo' and you get every legal operator running a brand with 'bingo' in it. 2,414 trading names map to 2,642 operators; 1,204 businesses (45.6%) have at least one Active trading name.

## `domainContains` (type: `string`):

Case-insensitive substring of any registered gambling domain, e.g. 'casino', '.co.uk', '888'. Answers 'which licensed company operates this website?'. 2,231 domains across 627 operators; 89 domains are registered against more than one account, which is normally a white-label arrangement.

## `activities` (type: `array`):

Return only businesses holding at least one licence for one of these activities. Licence-row counts measured 2026-09-07 after duplicate rows are dropped: Society Lottery 908, General Betting Limited 535, Gaming Machine General AGC 429, Gaming Machine Technical Supplier 398, Gambling Software 380, Bingo 367, Casino 205, General Betting Standard 187, GBS Real Event 152, Pool Betting 144.

## `licenceTypes` (type: `array`):

Non-Remote = premises / land-based (2,381 licence rows). Remote = online (1,535). Ancillary Remote = an online add-on to a land-based licence (544). A business matches if it holds any licence of a selected type.

## `licenceStatuses` (type: `array`):

Return businesses holding at least one licence in one of these states. Licence-row counts measured 2026-09-07: Active 3,650, Surrendered 660, Pending 62, Revoked - Non Payment of Fee 52, Lapsed 28, Revoked 8. Picking 'Revoked' plus 'Revoked - Non Payment of Fee' gives you the adverse-action list.

## `businessStatus` (type: `array`):

Company-level status this Actor derives from the licence rows: Active if any licence is Active (2,143 businesses), else Pending if any is Pending (31), else Ceased (468). Not a field the Commission publishes — it is computed here, and it is stated as derived on every row.

## `remoteOnly` (type: `boolean`):

Only businesses holding at least one Remote or Ancillary Remote licence — i.e. licensed to take bets online (1,383 of 2,642, measured 2026-09-07).

## `nonRemoteOnly` (type: `boolean`):

Only businesses holding at least one Non-Remote licence — betting shops, arcades, bingo halls, casinos (2,011 of 2,642). Switching this ON together with 'Online operators only' is allowed and returns the 752 hybrids that hold both.

## `minLicenceCount` (type: `integer`):

Only businesses holding at least this many licence rows. The register averages 1.69 licence rows per business and the largest holds 10 — so 'min 4' is a decent proxy for a large multi-activity group (61 businesses hold 5 or more).

## `maxLicenceCount` (type: `integer`):

Only businesses holding at most this many licence rows.

## `hasActiveTradingName` (type: `boolean`):

Only businesses with at least one Active trading name — 1,204 of 2,642 (45.6%). These are the operators with a live consumer-facing brand.

## `hasActiveDomain` (type: `boolean`):

Only businesses with at least one Active registered domain — 480 of 2,642 (18.2%). This is the live online-gambling operator list.

## `hasWhiteLabelOnly` (type: `boolean`):

Only businesses with at least one domain carrying the UKGC's 'White Label' status — 34 businesses (1.3%) and 370 domains, measured 2026-09-07. A white-label domain is a brand running on somebody ELSE'S licence, which is exactly the relationship an affiliate network, payment provider or compliance team needs to see and which no commercial database exposes.

## `includeInactiveTradingNames` (type: `boolean`):

Keep Inactive trading names in the trading\_names array (517 of 2,414 rows are Inactive). Turn OFF for a clean list of live brands only. active\_trading\_names is always Active-only regardless of this switch, and trading\_name\_count deliberately keeps the REGISTER total, so with this switch off it can be larger than the array you receive.

## `includeInactiveDomains` (type: `boolean`):

Keep Inactive domains in the domain\_names array (794 of 2,231 rows are Inactive). Turning this OFF keeps Active and White Label and drops Inactive. active\_domains and white\_label\_domains are unaffected, and domain\_count deliberately keeps the REGISTER total, so with this switch off it can be larger than the array you receive.

## `jurisdiction` (type: `string`):

UK-registered = a head office recorded as United Kingdom, Great Britain or Northern Ireland - all three spellings appear in the register and all three are domestic. Offshore = any other country, 265 of 2,642, led by Malta 85, Gibraltar 37, USA 21+3, Isle of Man 18, Ireland 17. Gibraltar and the Isle of Man count as offshore on purpose: a British Overseas Territory and a Crown Dependency are outside the UK, which is the distinction a compliance buyer is filtering for. The 473 businesses this Actor cannot place match neither and are excluded when you pick either option: 471 have no published address at all, and 2 have an address whose country field is blank.

## `countries` (type: `array`):

Exact head-office country match, case-insensitive, as spelled in the register. This is FREE TEXT in the source and the Commission is inconsistent about it, so type the string you want rather than picking from a list: 'USA' (21 businesses) and 'United States of America' (3) are the same place, and 12 values carry a state or province ('USA - Nevada', 'Germany - Berlin', 'Australia - Victoria'). 48 distinct values live on 2026-09-07 - United Kingdom 1,891, Malta 85, Gibraltar 37, USA 21, Isle of Man 18, Ireland 17, Great Britain 11, Sweden 7, Austria 7, Cyprus 6, Australia 6, South Africa 4, Germany 4, Bulgaria 4, Estonia 3, Israel 3, Netherlands 3, then a long tail of 1-2.

## `city` (type: `string`):

Case- and accent-insensitive substring of the head-office city, e.g. 'london', 'leeds', 'gibraltar'.

## `postcodeStartsWith` (type: `string`):

Outward-code prefix of the head-office postcode, spaces ignored: 'W1' matches W1D 3QU, 'LS' matches every Leeds postcode. Postcode fill rate is 79.9%.

## `hasAddressOnly` (type: `boolean`):

Drop the 471 businesses (17.8%) for which the Commission publishes no head-office address. Use this when the rows are going straight into a mail or enrichment pipeline.

## `firstLicensedAfter` (type: `string`):

YYYY-MM-DD. Filters on first\_licensed\_date — the earliest licence start date the business holds, i.e. operator tenure. The register's earliest is 2007-08-30. Use this to find newly-licensed entrants.

## `firstLicensedBefore` (type: `string`):

YYYY-MM-DD, inclusive. Combine with the field above for a tenure window — e.g. operators first licensed between 2007 and 2012 are the incumbent old guard.

## `latestLicenceStartAfter` (type: `string`):

YYYY-MM-DD. Filters on latest\_licence\_start\_date — a business that has just ADDED a licence, including an existing operator adding a new activity or moving online. Measured 2026-09-07: 6 licence rows in the register are future-dated to 2026-10-01, so this also surfaces licences that have been granted but have not started yet.

## `licenceEndedAfter` (type: `string`):

YYYY-MM-DD. Filters on latest\_licence\_end\_date — surrenders, revocations and lapses. 747 of the 4,460 licence rows this Actor ships carry an end date; the most recent measured was 2026-09-04. This is the churn/adverse-event trigger.

## `sortBy` (type: `string`):

Sorting runs BEFORE the 'Max businesses' cap, so the cap always gives you the top N of this order. Rows with an empty value sort last in both directions.

## `sortOrder` (type: `string`):

Ascending or descending.

## `includeLicenceRows` (type: `boolean`):

Keep the nested licences\[] array (licence number, status, type, activity, start and end date per licence). Turn it OFF for a flat, spreadsheet-friendly row — licence\_count, active\_licence\_count, activities, licence\_types and the three date roll-ups are all still there.

## `dateFormat` (type: `string`):

Plain date (2026-04-14) is what spreadsheets want. Full ISO timestamp (2026-04-14T00:00:00.000Z) is what the Commission's own file carries and what most databases prefer.

## `addressSource` (type: `string`):

AUTO (recommended) reads the register's structured bulk address file, falls back to the copy inside the Commission's ZIP bundle, and only if BOTH are gone crawls the per-business detail pages. CSV ONLY never crawls: if the bulk file is unavailable the run still ships every other field with address\_complete=false. DETAIL PAGES forces the per-business crawl — slower (about 6.7 pages/second measured) and it recovers nothing extra, because a business whose address row is blank also renders 'Address not available' on its own page. It is also LOSSIER: the page joins address line 1 and line 2 with the same separator that appears inside them, so on this route the whole street block ships in address\_line\_1 and address\_line\_2 is always null. Use it only to verify the bulk file against the live pages. One more consequence, measured: the rendered page prints town and country on one line, and for the 59 businesses whose published address is town + country only it prints the bare town, so this route loses their country (93.0% country fidelity over 300 live pages, against 100% street and postcode). If you combined it with a country, jurisdiction, city or postcode filter, any row the crawl re-addresses out of that filter is dropped before delivery and is never charged.

## `proxyConfiguration` (type: `object`):

Apify Proxy on the default (datacenter) group is enough and is what this Actor was measured on: all five files and the detail pages returned 200 and byte-identical content through it on 2026-09-07. Residential is not needed and would only add cost. You can point this at your own proxies instead.

## `requestTimeoutSecs` (type: `integer`):

Per-request timeout. The largest file (licences.csv, 492 KB) took 1.0-16.3 s through the Apify proxy in testing, so 90 s is generous.

## `maxRetries` (type: `integer`):

Retries with exponential backoff. One of six first-pass proxy requests hit a transient CONNECT failure during testing and succeeded on retry, so this is not decoration — leave it at 4 or higher.

## `detailConcurrency` (type: `integer`):

Parallel requests used ONLY by the detail-page address fallback. The host tops out around 6 pages/second, so anything above about 12 buys nothing.

## Actor input object example

```json
{
  "mode": "full",
  "maxBusinesses": 50,
  "remoteOnly": false,
  "nonRemoteOnly": false,
  "hasActiveTradingName": false,
  "hasActiveDomain": false,
  "hasWhiteLabelOnly": false,
  "includeInactiveTradingNames": true,
  "includeInactiveDomains": true,
  "jurisdiction": "any",
  "hasAddressOnly": false,
  "sortBy": "account_number",
  "sortOrder": "asc",
  "includeLicenceRows": true,
  "dateFormat": "date",
  "addressSource": "auto",
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "requestTimeoutSecs": 90,
  "maxRetries": 4,
  "detailConcurrency": 10
}
```

# Actor output Schema

## `businesses` (type: `string`):

The dataset: account number, legal operator name, derived Active/Pending/Ceased status, structured head-office address and offshore flag, licences\[], activities, licence types, first/latest licence dates, trading names, active and white-label domains, and the source file's Last-Modified header.

## `runSummary` (type: `string`):

Aggregates computed over the WHOLE register before any of your filters (2,642 businesses, 4,492 licence rows, address fill, offshore and white-label counts), next to how many matched your filters and how many were delivered — plus which route each source file came from, duplicate and orphan source rows dropped, and whether anything was truncated by your row cap or your charge limit.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "full",
    "maxBusinesses": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/ukgc-gambling-licensees-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "full",
    "maxBusinesses": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/ukgc-gambling-licensees-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "full",
  "maxBusinesses": 50
}' |
apify call scrapersdelight/ukgc-gambling-licensees-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapersdelight/ukgc-gambling-licensees-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/pgxQk1k3i8iKqCJig/builds/5iG3AsCU9hZf4rE6u/openapi.json
