UK HSE Enforcement Monitor - Prosecutions & Notices Scraper avatar

UK HSE Enforcement Monitor - Prosecutions & Notices Scraper

Pricing

from $3.00 / 1,000 record (full detail)s

Go to Apify Store
UK HSE Enforcement Monitor - Prosecutions & Notices Scraper

UK HSE Enforcement Monitor - Prosecutions & Notices Scraper

Scrape and monitor the UK Health and Safety Executive registers of convictions (prosecutions, fines, breaches, courts) and enforcement notices (Improvement, Prohibition). Filter by company name, region, industry, fine, notice type, dates. Delta mode with new and updated events. Pay per record.

Pricing

from $3.00 / 1,000 record (full detail)s

Rating

0.0

(0)

Developer

Stefano Seggio

Stefano Seggio

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 hours ago

Last modified

Share

UK HSE Enforcement Monitor — Prosecutions & Notices Scraper

Store URL: https://apify.com/stefano_seggio/uk-hse-enforcement-monitor Actor ID: jV35qppM82fjyjsle Version: 2.0 (latest changelog entry: 2.0.1, 2026-09-08)


Executive Summary & Business Use Case

UK HSE Enforcement Monitor extracts structured records from the two public enforcement registers published by the UK Health and Safety Executive at resources.hse.gov.uk: the register of convictions (every successful HSE prosecution — defendant, offence, fine, costs, breaches, court, hearing date — which HSE keeps for five years, roughly 210 live records) and the register of enforcement notices (Improvement and Prohibition notices — recipient, notice type, served and compliance dates, result, legislation breached — which HSE keeps for ten years, 30,000+ records). Neither register has an official API; the HSE site is a 2013-era classic-ASP search wizard with ten rows per page, no CSV export for notices, no "last updated" field, and a default sort that hides late-published cases. This actor is a maintained, pay-per-record API layer over both registers, with a delta engine that can put either register — or a filtered slice of it — under continuous monitoring.

The data supports several concrete commercial use cases, all grounded in fields that actually exist in the output. Contractor pre-qualification and supply-chain risk teams (CHAS/SSIP/Constructionline-style buyers, principal contractors, procurement teams) use nameContains, event_type, noticeCategory, isImmediate and partyHseReference to check whether a subcontractor has picked up a notice or conviction since they were approved, and isRepeatOffender plus partyConvictionCount/partyNoticeCount to flag repeat offenders at onboarding or renewal. Employers'-liability and public-liability insurance underwriters, MGAs and brokers use totalFineGbp, resultingFromFatality, hasCustodialSentence and the party-level conviction/notice counts to price, load, survey or decline a risk, and to catch anything new before a renewal date. KYB, adverse-media and ESG data vendors, and H&S consultancies doing business development, pull the whole register keyed on partyStatus/partyAddress/partyPostcode plus the daily delta (via contentHash and firstSeenAt) to attach a "UK H&S enforcement" attribute to company profiles or to prospect companies freshly served an Improvement Notice with a near-term effectiveComplianceDateIso.

Because every filter in the input schema is applied server-side by the HSE register itself, narrow runs (a single company name, a single region/industry combination, a fine floor) touch only a handful of pages and cost accordingly — the actor is priced and designed for exactly this kind of targeted, recurring lookup rather than only bulk extraction.

Technical Features & V2 Architecture Highlights

Delta engine with named, cross-run key-value-store persistence. When onlyNew is enabled, the actor writes its memory of every previously delivered record — one content hash per record, keyed by register — into a private, named key-value store called uk-hse-enforcement-monitor-state-<deltaStateName> (the name defaults to a fingerprint of the active filter set, so unrelated schedules never collide unless deltaStateName is set to the same value on purpose). Later runs read that store back, walk the register in entry order (case/notice number descending) rather than the site's own offence/issue-date order — which the README documents as necessary because HSE enters convictions months after the hearing and notices weeks after service, so date-sorted listings hide late-published records — and deliver only records that are new or whose page's content hash changed. Convictions (~210 records) are walked in full every run; the notices walk stops once it hits two consecutive already-known pages, so a routine scheduled run only touches a few pages.

Real event types: SANCTION, NEW_LISTING, UPDATED — no CLOSED. Per dataset_schema.json and input_schema.json, this actor's event_type enum is domain-specific and asymmetric by design, not the generic new/updated/closed set some other actors in this developer's fleet use: SANCTION marks a conviction never delivered before, NEW_LISTING marks a notice never delivered before, and UPDATED marks a previously delivered record whose case/notice page has since changed (a notice complied with, a revised compliance date, a breach or hearing added). There is deliberately no CLOSED event — the HSE registers have no concept of a record being withdrawn or closed in a way the site exposes cleanly (a withdrawn record just starts returning an HTTP 500 "unknown id" page, handled separately — see below), so the engine does not manufacture a closure event for it.

onlyNew behaviour, verbatim from the actor's own schema. input_schema.json documents onlyNew as: "Remembers every record it has delivered (per filter set, in a named key-value store) and returns only records that are new or whose page changed since. Convictions (~210 records) are always walked in full; notices stop at the first two pages of already-known records, so a scheduled run costs a few pages." In plain terms: with onlyNew: true, a record the register hasn't changed since the last run is never emitted into the dataset at all — it is not delivered, not counted, and (per the pricing model below) not billed. Turning onlyNew off after having used it does not fork the delta memory — filter values, not the flag itself, determine which named state a run reads and writes.

No evidence of a generic 18-field "UMS" in this actor's own schema. What the actor's own files do confirm is a smaller, explicitly-named 6-field integration enveloperecord_id, event_type, scraped_at, is_new, source_url, data_source — which the README states in as many words is "identical across all of this developer's public-register Actors, so one webhook parser serves them all." Everything past those six fields is domain-specific to the HSE registers (conviction fields, notice fields, breach arrays, location fields, party fields, provenance fields), documented field-by-field in dataset_schema.json.

Content-hash change detection with a baseline floor and a walk watermark (added/fixed in 2.0.0/2.0.1). Because the HSE registers have no "last updated" timestamp, the delta engine hashes each fetched page (contentHash) as its sole change-detection key. CHANGELOG.md documents two architectural safeguards added specifically to keep a capped, scheduled run honest over time: (1) a baseline floor — on a cold delta memory's first run, if maxItemsPerDataset cuts the walk short, the oldest record actually delivered is persisted as that register's baseline before anything is delivered, and every later delta run treats unseen records below that floor as history — never delivered, never charged, never a reason to keep walking; and (2) a walk watermark for every later capped run — the record number a capped walk stopped at is persisted so the next run resumes the backlog from that point instead of prematurely treating "two known pages" as the end of new material. The 2.0.1 patch specifically fixed a case where a small cap (below ~20, i.e. under two full listing pages) broke the baseline promise and caused older records to be silently re-delivered and re-charged run after run.

Recheck window for UPDATED detection. recheckDays (default 180, 0–3650) controls how long known open records — Improvement Notices with result = "Ongoing", and every conviction — keep being re-read after first delivery (or after their register date, whichever is later) to catch an UPDATED event; up to 2,000 records are re-checked per run. Prohibition notices carry no result value on the register at all and are never re-checked.

Three independent detail-fetch toggles gate both data completeness and price tier. fetchDetail opens the case/notice page itself (description, dates, fine, costs, result, address, industry, HSE admin fields, plus the per-case breach list for convictions); fetchBreachDetail opens each breach's own page (court, Act section/Regulation paragraph, per-breach fine, hearing date) for convictions, or the breach list for notices; fetchPartyDetail opens the defendant/recipient's own page and cross-register history (three extra requests, no extra charge). Turning fetchDetail or fetchBreachDetail off drops a record to the cheaper result-summary price tier (see Pricing below) and also disables UPDATED detection for that record, since there is no case/notice page to hash.

Five ready-made dataset views ship in dataset_schema.json: Overview (both registers side by side), Convictions & fines, Enforcement notices, Compliance tracker (ongoing/overdue/complied notices with daysUntilCompliance), and Defendants & recipients (party-level roll-up with repeat-offender counts) — usable directly from the Output tab or via the dataset API's view parameter.

Input Schema & JSON Configuration Example

All descriptions below are copied verbatim from .actor/input_schema.json.

FieldTypeDefaultDescription
datasetsarray (enum: convictions, notices)["convictions", "notices"]Convictions = successful prosecutions (defendant, fine, costs, breaches, court, hearing date; HSE keeps 5 years). Notices = Improvement and Prohibition enforcement notices (recipient, type, served/compliance dates, result; HSE keeps 10 years).
nameContainsstringSubstring match on the defendant's (convictions) or recipient's (notices) name, e.g. 'Skanska' or 'Balfour Beatty'. The contractor-vetting filter. Quotes are treated as single-character wildcards.
descriptionContainsstringFull-text substring over the case description (convictions) or notice summary (notices), e.g. 'asbestos', 'scaffold', 'silica'.
localAuthorityContainsstringLocal authority where the offence occurred, e.g. 'Bradford', 'Cardiff UA'.
mainActivityContainsstringA numeric value matches the SIC 2007 code of the offence location; any other text matches the activity description ('ROOFING', 'MACHINING'). The site keeps the two in different columns, so a code never matches as text and vice versa. The code match is a CONTAINS match on the register: use a full 5-digit code for one class ('43910' = roofing) or a 4-digit group ('4391'); 2-3 digit values also match every code that merely contains those digits ('43' returns 14310, 24310, 46430 ...) - use the industry filter for broad selections.
regionstring (select, enum "",17)""HSE's seven UK regions. (1 Wales & South West, 2 East & South East, 3 North West, 4 Yorks & North East, 5 Midlands, 6 London, 7 Scotland)
countrystring (select, enum "",811)""Country of the offence location. (8 England, 9 Scotland, 10 Wales, 11 Jersey)
industrystring (select, enum "",1216)""HSE's five industry groups. (12 Agriculture/hunting/forestry/fishing, 13 Construction, 14 Extractive & utility supply, 15 Manufacturing, 16 Total service industries)
hseDivisionstring (select, enum "",1727)""HSE's operational division (finer than region).
dateFromstring (datepicker, absolute or relative)Offence date (convictions) / date the notice was served (notices). Absolute (2026-01-01) or relative ('30 days', '6 months', '1 year' back from today, UK calendar). Note: both dates lag publication on the register by weeks to years - for 'what is new on the register' use delta mode instead.
dateTostring (datepicker, absolute or relative)Absolute or relative upper bound of the same date. Leave empty for 'today'.
hseReferencestring (pattern ^\s*\d+\s*$)Everything about one party: the numeric HSE Reference shown on a defendant or recipient page (the same id is used on both registers), e.g. 4392330.
recordNumberstring (pattern ^\s*\d+\s*$)Look up one record by its case number (convictions) or notice number (notices), e.g. 4883993 or 316005113.
defendantStatusstring (select, enum "",1980,1972,1981,1974,1976,1978,1977,1973,1975,1979)""Legal form of the defendant. Convictions only.
resultingFromFatalitystring (enum any,yes,no)"any"Only cases that resulted from the investigation of a (RIDDOR-reportable) fatality. Convictions only.
minTotalFineGbpinteger (min 0)Only cases with a total fine of at least this amount. Tip: 100000 leaves about 50 of the 210 cases.
maxTotalFineGbpinteger (min 0)Only cases with a total fine of at most this amount.
noticeTypesarray (enum 0109)[]HSE's nine notice-type codes (labels verified against the register, 2026-09-07). '03' is the ordinary Improvement Notice (22,000+); '01' and '02' are the rare Crown / FEPA variants. Select several to get their union. Notices only.
actstring (select, 43-code enum)""Primary legislation of the breach. Notices only (labels are the register's own, some truncated by the site).
eventTypesarray (enum SANCTION,NEW_LISTING,UPDATED)["SANCTION","NEW_LISTING","UPDATED"]SANCTION = a conviction not delivered before; NEW_LISTING = a notice not delivered before; UPDATED = a record you already received whose case/notice page changed (a notice complied with, a revised compliance date, a breach or hearing added) - delta mode only. Applied by the delta engine, not by the site: changing it later does not fork the delta memory.
onlyNewbooleanfalseRemembers every record it has delivered (per filter set, in a named key-value store) and returns only records that are new or whose page changed since. Convictions (~210 records) are always walked in full; notices stop at the first two pages of already-known records, so a scheduled run costs a few pages.
recheckDaysinteger (0–3650)180In delta mode, known records that are still open (Improvement Notices with Result 'Ongoing', and every conviction) are re-read for this many days after they were first delivered (or after their register date, whichever is later) to detect UPDATED events - the register has no 'last updated' field, so this is the only way to see a notice being complied with or a hearing being added. 0 disables re-checks. Up to 2,000 records are re-checked per run.
deltaStateNamestring (pattern ^[A-Za-z0-9-]{1,30}$)fingerprint of filtersOptional label for the memory of a monitoring task. Defaults to a fingerprint of your filters, so different schedules never interfere. Set the same name on two tasks to make them share one memory.
resetStatebooleanfalseForget every previously delivered record for this delta state and re-baseline (the run then returns up to 'Max records per register' most recently entered records).
maxItemsPerDatasetinteger (1–100000)100Hard cap on delivered records per selected register (and therefore on cost: you pay per record). On the very first delta run the cap defines the baseline: the oldest record that run delivers is remembered per register, and records entered before it are history - later delta runs never deliver or charge for them, whatever the cap (run once with onlyNew=false, or set a high cap on the first run, if you want the history). On every later delta run the overflow is a backlog: the walk remembers where it stopped (a per-register watermark in the delta memory) and the next run walks down to that point instead of stopping at the records already delivered.
fetchDetailbooleantrueOpens each record's own page for the description, dates, fine and costs, result, address, industry and HSE admin fields (plus, for convictions, the per-case breach list). Off = listing-row-only records (name, date, local authority, main activity, notice type) at the cheaper 'result-summary' price; no UPDATED detection is possible without it.
fetchBreachDetailbooleantrueConvictions: opens each breach's page for the court, Act section / Regulation paragraph, hearing date, result and per-breach fine. Notices: fetches the breach list (Act / regulation / paragraph per breach). Off = the cheaper 'result-summary' price.
fetchPartyDetailbooleantrueOpens the party's page (registered address, Status such as 'Private Company' or 'Individual', HSE Reference) and its case and notice lists on both registers - the repeat-offender signal (3 extra requests per record, no extra charge).
maxConcurrencyinteger (1–10)5Run-wide cap on simultaneous HTTP requests (listing, detail, breach and party pages together - never more than this in flight). The register is a classic-ASP site that answered 17 concurrent requests without throttling; 5 keeps a 100-record run around a minute.
dateRangestring (hidden, pattern ^(24h|7d|30d)$)Kept for tasks created with version 1: '24h', '7d' or '30d' are interpreted as 'Date from'.

Valid input example

{
"datasets": ["notices"],
"nameContains": "Skanska",
"noticeTypes": ["08"],
"industry": "13",
"region": "3",
"dateFrom": "90 days",
"eventTypes": ["NEW_LISTING", "UPDATED"],
"onlyNew": true,
"recheckDays": 180,
"deltaStateName": "skanska-nw-construction",
"maxItemsPerDataset": 500,
"fetchDetail": true,
"fetchBreachDetail": true,
"fetchPartyDetail": true,
"maxConcurrency": 5
}

This asks for Immediate Prohibition Notices (noticeTypes: ["08"]) served on or after 90 days ago, in Construction (industry: "13"), North West England (region: "3"), where the recipient name contains "Skanska", delivering new and updated records only (onlyNew: true, eventTypes excludes SANCTION since no convictions dataset was requested), remembered under the delta state skanska-nw-construction, capped at 500 records, with full case, breach and party detail fetched.

Output Dataset Sample & Data Dictionary

Fields, types and descriptions below come from .actor/dataset_schema.json. additionalProperties: true in that schema means individual records may occasionally carry a couple of extra provenance-style fields not enumerated here, but every field named below is declared explicitly in the schema.

Integration envelope (shared shape across this developer's public-register actors):

FieldTypeDescription
record_idstringcaseNumber or noticeNumber - stable across runs.
event_typestring (SANCTION|NEW_LISTING|UPDATED)SANCTION (conviction not delivered before), NEW_LISTING (notice not delivered before) or UPDATED (a previously delivered record whose case/notice page changed).
scraped_atstringISO-8601 UTC timestamp of this extraction.
is_newbooleantrue when this record was never delivered by a previous run of this delta state.
source_urlstringThe official HSE register page.
data_sourcestringOpen Government Licence v3.0 attribution string.

Record identity and classification:

FieldTypeDescription
recordTypestring (conviction|notice)Which register the record came from.
caseNumberstring | nullConvictions only.
noticeNumberstring | nullNotices only.
defendantNamestring | nullConvictions only.
defendantIdstring | nullDefendant ID (HSE reference).
recipientNamestring | nullNotices only.
recipientIdstring | nullRecipient ID (HSE reference).
descriptionstring | nullCase or notice description.

Conviction fields:

FieldTypeDescription
offenceDatestring | nullOffence date, raw site string (example 27/07/2021).
offenceDateIsostring | nullOffence date, YYYY-MM-DD.
hearingDatestring | nullLatest hearing date, raw site string.
hearingDateIsostring | nullNewest Date of Hearing across the case's breaches - the closest thing to a publication date.
totalFinestring | nullTotal fine, raw site string (example £400,000.00).
totalFineGbpnumber | nullTotal fine, GBP.
totalCostsstring | nullCosts awarded to HSE, raw site string.
totalCostsGbpnumber | nullCosts awarded to HSE, GBP.
totalPenaltyGbpnumber | nullFine + costs, GBP.
resultingFromFatalityboolean | nulltrue when the case page states it resulted from the investigation of a fatality.
hasCustodialSentenceboolean | nulltrue when any breach result is a prison sentence (including suspended).
breachCountinteger | nullNumber of breaches.
legislationBreachedarray<string> | nullLegislation breached.
courtLevelstring | nullCourt level (example Magistrates Court).
breachesarray<object>Convictions: breachId, court, courtLevel, act, regulation, dateOfHearing(Iso), result, resultListing, resultCategory, isCustodial, fine, fineGbp, actName/actSection/actSubSection, regulationName/regulationNumber/regulationParagraph, legislation/provision/paragraph, source_url. Notices: breachId, actOrRegulation, legislation, provision, paragraph.

Notice fields:

FieldTypeDescription
noticeTypestring | nullExample Immediate Prohibition Notice.
noticeTypeListingstring | nullNotice type, listing wording.
noticeCategorystring | null (Improvement|Prohibition|null)Notice category.
isProhibitionboolean | nullIs prohibition notice.
isImprovementboolean | nullIs improvement notice.
isImmediateboolean | nullIs immediate prohibition.
isDeferredboolean | nullIs deferred prohibition.
isCrownboolean | nullCrown notice.
isComahboolean | nullCOMAH notice.
isFepaboolean | nullFEPA notice.
servedDatestring | nullServed on, raw site string.
servedDateIsostring | nullServed on, ISO date.
complianceDatestring | nullFrom the notice page, or from the listing when an Improvement notice type is selected (8-column listing).
complianceDateIsostring | nullCompliance date, ISO.
revisedComplianceDatestring | nullRevised compliance date, raw site string.
revisedComplianceDateIsostring | nullRevised compliance date, ISO.
effectiveComplianceDateIsostring | nullRevised date when one exists, else the original.
daysToComplyinteger | nullDays given to comply.
daysUntilComplianceinteger | nullNegative once the effective compliance date has passed.
hasRevisedComplianceDateboolean | nullHas revised compliance date.
resultstring | nullExample Ongoing. Ongoing / Complied with (Improvement Notices only). From the notice page, or from the listing when an Improvement notice type is selected.
isOngoingboolean | nullIs ongoing.
isCompliedWithboolean | nullComplied with.
isOverdueboolean | nullOngoing and past its effective compliance date.
descriptionItemIdsarray<string> | nullPer-item notice numbers embedded in multi-item descriptions.

Location of offence:

FieldTypeDescription
addressstring | nullOffence address.
postcodestring | nullPostcode.
countrystring | nullCountry.
regionstring | nullUK region.
localAuthoritystring | nullLocal authority.
industrystring | nullIndustry.
mainActivitystring | nullRaw site string (example 43910 - ROOFING ACTIVITIES).
sicCodestring | nullSIC code.
sicDescriptionstring | nullSIC description.
typeOfLocationstring | nullType of location.
hseGroupstring | nullHSE group.
hseDirectoratestring | nullHSE directorate.
hseAreastring | nullAlways empty on the live register; kept for compatibility.
hseDivisionstring | nullHSE division.

Party (fetchPartyDetail):

FieldTypeDescription
partyStatusstring | nullExample Private Company.
partyEntityTypestring | null (company|individual|partnership|public_body|other|null)Party entity type.
partyAddressstring | nullParty registered address.
partyPostcodestring | nullParty postcode.
partyHseReferencestring | nullParty HSE reference.
partyUrlstring | nullParty page.
partyConvictionCountinteger | nullParty convictions (all time on register).
partyNoticeCountinteger | nullParty notices (all time on register).
partyOtherCaseNumbersarray<string> | nullParty's other case numbers.
partyOtherNoticeNumbersarray<string> | nullParty's other notice numbers.
isRepeatOffenderboolean | nulltrue when the party has more than one conviction or notice on the registers.

Provenance:

FieldTypeDescription
detailFetchedbooleanDetail fetched.
detailErrorstring | nullNOT_FOUND when the page was withdrawn between listing and detail.
breachDetailFetchedbooleanBreach detail fetched.
partyDetailFetchedbooleanParty detail fetched.
partyDetailErrorstring | nullParty detail error.
contentHashstring | nullThe delta engine's change key for this record.
firstSeenAtstring | nullYYYY-MM-DD, from the delta memory.

Sample dataset record

This is a real notice record produced by the actor (per the actor's own README):

{
"record_id": "314719061",
"event_type": "NEW_LISTING",
"scraped_at": "2026-09-07T21:10:39.804Z",
"is_new": true,
"source_url": "https://resources.hse.gov.uk/notices/notices/notice_details.asp?SF=CN&SV=314719061",
"data_source": "Contains public sector information published by the Health and Safety Executive and licensed under the Open Government Licence v3.0 (HSE public registers of convictions and enforcement notices, resources.hse.gov.uk)",
"recordType": "notice",
"noticeNumber": "314719061",
"recipientName": "Llanelec Precision Engineering Company Limited",
"recipientId": "1108773",
"noticeType": "Improvement Notice",
"noticeCategory": "Improvement",
"isProhibition": false,
"isImmediate": false,
"servedDate": "05/12/2024",
"servedDateIso": "2024-12-05",
"complianceDateIso": "2025-03-03",
"revisedComplianceDateIso": "2025-03-31",
"effectiveComplianceDateIso": "2025-03-31",
"daysToComply": 88,
"daysUntilCompliance": -525,
"hasRevisedComplianceDate": true,
"result": "Complied with",
"isOngoing": false,
"isCompliedWith": true,
"isOverdue": false,
"breachCount": 2,
"legislationBreached": [
"Health and Safety At Work Act 1974",
"Management of Health & Safety at Work Regulations 1999"
],
"breaches": [
{
"breachId": "001",
"actOrRegulation": "Health and Safety At Work Act 1974 / 2 / 1",
"legislation": "Health and Safety At Work Act 1974",
"provision": "2",
"paragraph": "1"
},
{
"breachId": "002",
"actOrRegulation": "Management of Health & Safety at Work Regulations 1999 / 3 / 1",
"legislation": "Management of Health & Safety at Work Regulations 1999",
"provision": "3",
"paragraph": "1"
}
],
"address": "Llanelec Prec. Eng. Co. Ltd./L, Llanelec Precision Engineering, Nidum House, Neath Abbey Business Park, NEATH, West Glamorgan, SA10 7DR, Wales",
"postcode": "SA10 7DR",
"country": "Wales",
"region": "Wales & South West",
"localAuthority": "Neath & Port Talbot UA",
"industry": "Manufacturing",
"mainActivity": "25620 - MACHINING",
"sicCode": "25620",
"sicDescription": "MACHINING",
"hseDivision": "Wales",
"partyStatus": "Private Company",
"partyEntityType": "company",
"partyAddress": "Nidum House, Neath Abbey Business Park, NEATH, West Glamorgan, SA10 7DR",
"partyPostcode": "SA10 7DR",
"partyHseReference": "1108773",
"partyConvictionCount": 0,
"partyNoticeCount": 22,
"isRepeatOffender": true,
"detailFetched": true,
"breachDetailFetched": true,
"partyDetailFetched": true,
"contentHash": "e20670777ba0369e",
"firstSeenAt": "2026-09-07"
}

A conviction record has the same envelope plus "recordType": "conviction", "event_type": "SANCTION", caseNumber, defendantName, offenceDateIso, hearingDateIso, totalFineGbp, totalCostsGbp, totalPenaltyGbp, resultingFromFatality, hasCustodialSentence, courtLevel, and a breaches[] array carrying court, courtLevel, dateOfHearingIso, result, resultCategory, isCustodial, fineGbp, actName/actSection/actSubSection, regulationName/regulationNumber/regulationParagraph per breach.

Multi-language Integration Snippets

cURL

curl -X POST "https://api.apify.com/v2/acts/stefano_seggio~uk-hse-enforcement-monitor/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"datasets": ["notices"],
"noticeTypes": ["08"],
"industry": "13",
"region": "3",
"onlyNew": true,
"maxItemsPerDataset": 500
}'

Python (apify-client)

from apify_client import ApifyClient
client = ApifyClient(token="YOUR_TOKEN")
run = client.actor("stefano_seggio/uk-hse-enforcement-monitor").call(
run_input={
"datasets": ["notices"],
"noticeTypes": ["08"],
"industry": "13",
"region": "3",
"onlyNew": True,
"maxItemsPerDataset": 500,
}
)
for record in client.dataset(run["defaultDatasetId"]).iterate_items():
print(
record["event_type"],
record["recordType"],
record.get("recipientName") or record.get("defendantName"),
record.get("noticeType"),
record["source_url"],
)

Node.js (apify-client)

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('stefano_seggio/uk-hse-enforcement-monitor').call({
datasets: ['notices'],
noticeTypes: ['08'],
industry: '13',
region: '3',
onlyNew: true,
maxItemsPerDataset: 500,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems({ desc: true });
for (const record of items) {
console.log(
record.event_type,
record.recordType,
record.recipientName ?? record.defendantName,
record.noticeType,
record.source_url,
);
}

Pricing Model Explanation

The actor is billed per pay-per-event pricing with three named events (confirmed live via the Apify API):

EventPriceWhen it applies to this actor
result$0.003 per recordA record delivered with the case/notice page fetched and breach detail fetched — i.e. fetchDetail: true and fetchBreachDetail: true for that record, giving court, Act section, and regulation paragraph alongside the full case/notice fields.
result-summary$0.001 per recordAny lighter record: fetchDetail: false (listing-row-only — name, date, local authority, main activity, notice type), fetchBreachDetail: false (case/notice page fetched but no breach page), or a record whose detail page could not be fetched at all (delivered as a listing-only stub, e.g. detailError: "NOT_FOUND").
Actor start (apify-actor-start)$0.00005Once per run, regardless of how many records — including a delta run that finds nothing new.

The two-tier result/result-summary split in this actor is specifically about how much of the record was fetched, not about "new vs. old" or any other generic distinction: it is driven directly by the fetchDetail and fetchBreachDetail input flags. A run with both flags on pays full price per record for the case/notice page plus the per-breach legislation detail; turning either off (or hitting a page that can't be read) drops that record to the summary price. fetchPartyDetail, by contrast, adds three extra HTTP requests per record (the party's own page and its case/notice history) at no extra charge — it does not change which pricing tier a record falls into.

Because this actor supports delta monitoring (onlyNew: true), enabling it changes what gets billed, not the price of what gets billed: a record the HSE register hasn't added or changed since the last run is never delivered into the dataset at all, so it is never a result or result-summary event — it simply doesn't exist as a chargeable event that run, rather than being billed at $0. Per the README's own worked example, a quiet daily monitoring run that finds nothing new costs only the $0.00005 actor-start fee. A daily monitor of both registers that turns up 20 new notices and one conviction (all with full detail) costs about $0.06 for that run; a one-off full pull of the ~210-case convictions register costs about $0.63; the entire 30,000-record notices register with full detail is about $91, or about $30 if pulled as listing rows only (fetchDetail: false).