# London Gazette Notices Scraper (UK Official JSON) (`steadfetch/london-gazette-notices-monitor`) Actor

Returns official UK The Gazette notices for company subjects as JSON: insolvency, winding-up, liquidation and capital changes, with notice id, category, subject, case reference and publication date. Filter by notice code, keyword and publication date. Natural-person notices are discarded (GDPR).

- **URL**: https://apify.com/steadfetch/london-gazette-notices-monitor.md
- **Developed by:** [Steadfetch](https://apify.com/steadfetch) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 notice delivereds

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## London Gazette Notices Scraper (UK Insolvency Notices)

Monitor **official UK The Gazette notices** for **company and entity subjects**: insolvency, petitions to wind up, winding-up resolutions, liquidator appointments, creditors' meetings, capital reductions, limited partnerships, planning and environmental notices. Built by [Steadfetch](https://apify.com/steadfetch) on the official [The Gazette](https://www.thegazette.co.uk/) JSON feed.

Web data that doesn't break: keyless official feed, HTTP-only (no browser), schema-validated results and pay-per-event pricing.

### What it does

The Actor reads the official The Gazette notice feed:

```
https://www.thegazette.co.uk/all-notices/notice/data.json
```

It paginates the requested publication-date window, filters by notice code, category and keyword, and saves one validated item per **company/entity** notice:

- `notice_id`, `notice_code`, `category`, `subject_name`, `status`, `published_at`, `case_reference`, `summary`, `source_url`
- plus the common Steadfetch envelope (`url`, `title`, `scrapedAt`)

Default window: **last 7 days**. Default cap: **100 notices** (maximum 5,000).

#### GDPR and personal data

The Gazette licence (Open Government Licence v3.0) **does not cover the re-use of personal data** ([The Gazette data page](https://www.thegazette.co.uk/data), [terms](https://www.thegazette.co.uk/terms-and-conditions)). This Actor therefore:

- **discards every notice whose subject is a natural person** (deceased estates, probate, personal insolvency and other person-only categories) before building an item, so the address or contact details of the person never reach the dataset;
- only emits notices whose official feed title (or, for a few known generic categories, the opening of the notice text) identifies a **company, authority or other organisation**;
- **never outputs structured addresses, phone numbers or email addresses**, and scrubs email addresses and phone-shaped numbers from `summary`;
- never uses the per-notice `?view=linked-data` endpoint: it is disallowed by [robots.txt](https://www.thegazette.co.uk/robots.txt). Only the public search feed is read.

Notices that cannot be confidently classified as a company/entity are skipped, not guessed. They are never charged.

#### Monitor behaviour

- **Dedupe by `notice_id`** inside a run: a notice is charged once even if the feed repeats it.
- Schedule the Actor and set `publishedAfter` to the previous run date to receive only new notices. Only validated company/entity notices are charged; empty feeds, errors, person-subject notices, duplicates and malformed entries cost nothing beyond the run start event.
- Printed-supplement page entries that appear in the feed without a notice code are skipped as non-notices and never charged.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `noticeCodes` | array of strings | Optional official notice codes, for example `["2450"]` (Petitions to Wind Up (Companies)) or `["2441"]` (Resolutions for Winding-up). |
| `category` | string | Optional case-insensitive category filter, for example `"Petitions to Wind Up (Companies)"`. |
| `keyword` | string | Optional full-text search term passed to the official Gazette search. |
| `publishedAfter` | string | ISO date `YYYY-MM-DD`. Defaults to 7 days ago. |
| `maxResults` | integer | 1-5,000. Default 100. |
| `strictSchema` | boolean | Fail the run on an invalid item. Default `true`. |

Minimal test input:

```json
{
    "category": "Petitions to Wind Up (Companies)",
    "maxResults": 10
}
```

### Example output

A real item from the feed (20 October 2026):

```json
{
    "url": "https://www.thegazette.co.uk/notice/5234077",
    "title": "VALESCAPE CONSTRUCTION LTD",
    "scrapedAt": "2026-10-20T12:30:00.000Z",
    "notice_id": "5234077",
    "notice_code": "2450",
    "category": "Petitions to Wind Up (Companies)",
    "subject_name": "VALESCAPE CONSTRUCTION LTD",
    "status": "published",
    "published_at": "2026-10-20T12:10:21.000Z",
    "case_reference": "CR-2026-MAN-001175",
    "summary": "In the High Court of Justice CR-2026-MAN-001175 In the matter of VALESCAPE CONSTRUCTION LTD Trading As: Valescape Construction Ltd , and in the Matter of the Insolvency Act 1986 , A Petition to wind u...",
    "source_url": "https://www.thegazette.co.uk/notice/5234077"
}
```

Fields marked required in `.actor/dataset_schema.json` are always present. `case_reference` and `summary` are optional and appear only when the feed provides them.

### Pricing

Pay-per-event (PPE), the only per-result charge is the platform's synthetic dataset event. There is no custom event and no `Actor.charge()` call, so users are never billed twice.

| Event | Charged when | Price |
| --- | --- | --- |
| `apify-actor-start` | Once per run start (synthetic) | **$0.00005 per run** (Apify-recommended default; includes 5 s of free compute) |
| `apify-default-dataset-item` | Each validated company/entity notice saved to the dataset | **$0.0035 per notice = $3.50 per 1,000 notices** |

3.50 USD per 1,000 results is inside the Steadfetch band (1-10 USD per 1,000) and inside the Gazette competitor band (roughly 0.001-0.05 USD per notice). Person-subject notices, duplicates, empty feeds and errors are never charged.

#### Cost per 1,000 notices

Measured on the dev container against the live official feed (20 October 2026, 35-day window, 1,000 valid notices):

| Resource | Measured |
| --- | --- |
| Feed requests / pages | 28 |
| Candidate feed entries | 2,776 (including printed-supplement pages, skipped) |
| Feed transfer | about  5.6 MB |
| Wall clock | about  114 s |
| Memory | 256 MB (Actor minimum) |

Estimated platform cost at Apify's published rates (1 compute unit = 1 GB RAM/hour, $0.20/CU; external data transfer $0.20/GB; 1,000 dataset writes $0.005): **about  $0.01 per 1,000 notices**. This is a resource-based estimate, not an invoice: no platform run was made during the build to preserve the team's Apify credit. At a $3.50/1,000 price the gross margin is above 99% (the specification's conservative ceiling was $0.20/1,000).

A short, recent `publishedAfter` window is cheaper. Use `noticeCodes` or `category` to narrow the scan when you only need one notice type.

### Output schema

Everything is validated against `.actor/dataset_schema.json` (JSON Schema) before it reaches the dataset. With `strictSchema: true` the run fails rather than push a malformed item. The same schema is exercised by the offline test suite and by CI on Node 20 and 22.

### FAQ

**Does it need an API key, login or subscription?**
No. The Gazette search feed is public and keyless. The Actor never bypasses a login, paywall or CAPTCHA.

**Does it scrape the website HTML?**
No. It reads the official JSON feed. The per-notice linked-data view is disallowed by robots.txt and is not called. For a few official categories whose feed title is the category name (planning, environmental protection, electricity, general partner statements, other notices), the subject is recovered from the opening of the notice text; if that is ambiguous the notice is skipped.

**Why are some notices missing?**
Natural-person notices are deliberately discarded for GDPR reasons. Notices without a confidently identifiable company/entity subject are skipped. Printed-supplement page entries are not notices and are skipped.

**How do I monitor only new notices?**
Run on a schedule and set `publishedAfter` to the date of the previous run. `notice_id` dedupe prevents duplicates within a run. Only validated company/entity notices are charged.

**Is the output schema stable?**
Yes. New fields are additive and required fields do not change. `url` and `scrapedAt` are always present.

**Can I request a new source?**
Yes. Open an issue in the Steadfetch Actors repository describing the public feed you want tracked.

### Development

```bash
npm install
npm test                # lint + typecheck + offline fixture tests
npm run publish:check   # Steadfetch publish gate
npm run build           # production build
```

Tests run entirely offline against real feed snapshots in `test/fixtures/` (including personal-notice examples), so they spend zero Apify credit.

### Maintenance

This Actor is **tested daily**: automated runs keep the feed reachable, the extraction working and the output schema valid. Person-subject filtering is part of the test suite: a regression fails CI before anything is published.

### Source, licence and attribution

- Source: [The Gazette](https://www.thegazette.co.uk/) official notice feed, Crown Copyright.
- Licence: [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3), except personal data.
- Steadfetch does not claim endorsement by The Gazette, The National Archives or TSO.

# Actor input Schema

## `noticeCodes` (type: `array`):

Optional official notice codes to include (for example \["2450"] for Petitions to Wind Up (Companies), \["2441"] for Resolutions for Winding-up). Omit to read every notice type in the date window.

## `category` (type: `string`):

Optional category filter applied to the official notice category, case-insensitive substring (for example "Petitions to Wind Up (Companies)").

## `keyword` (type: `string`):

Optional full-text search term passed to the official Gazette search.

## `publishedAfter` (type: `string`):

ISO date (YYYY-MM-DD). Notices published on or after this date are read. Defaults to the last 7 days.

## `maxResults` (type: `integer`):

Maximum number of valid company/entity notices to save to the dataset.

## `strictSchema` (type: `boolean`):

Fail the run when an item does not match the output schema. Keep enabled: Steadfetch never publishes Actors without output-schema validation.

## Actor input object example

```json
{
  "noticeCodes": [
    "2450"
  ],
  "category": "Petitions to Wind Up (Companies)",
  "keyword": "construction",
  "publishedAfter": "2026-10-13",
  "maxResults": 100,
  "strictSchema": true
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items validated against the item schema in dataset_schema.json (fields).

# 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 = {
    "category": "Petitions to Wind Up (Companies)",
    "maxResults": 10,
    "strictSchema": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadfetch/london-gazette-notices-monitor").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 = {
    "category": "Petitions to Wind Up (Companies)",
    "maxResults": 10,
    "strictSchema": True,
}

# Run the Actor and wait for it to finish
run = client.actor("steadfetch/london-gazette-notices-monitor").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 '{
  "category": "Petitions to Wind Up (Companies)",
  "maxResults": 10,
  "strictSchema": true
}' |
apify call steadfetch/london-gazette-notices-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadfetch/london-gazette-notices-monitor"
        }
    }
}
```

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/prFEXkxsPXkUEIKhn/builds/NuCdEoJcG4YBDG1ke/openapi.json
