# England Higher Education Regulatory Register Change Signals (`starshaped_bullsnake/england-higher-education-regulatory-register-change-signals`) Actor

Track official OfS provider registration, condition and regulatory attribute changes.

- **URL**: https://apify.com/starshaped\_bullsnake/england-higher-education-regulatory-register-change-signals.md
- **Developed by:** [Starshape Tools](https://apify.com/starshaped_bullsnake) (community)
- **Categories:** Education
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 ofs regulatory change signals

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

## England Higher Education Regulatory Register Change Signals

**This is a regulatory change-intelligence Actor, not an OfS provider directory or provider lookup scraper.** It monitors official changes to provider registration, specific conditions, and selected regulatory attributes. It does not infer provider risk, severity, educational quality, endorsement, or compliance beyond the Office for Students source text.

### Official source and identity

Every live run downloads the official XLSX linked by the [Guide to the OfS Register](https://www.officeforstudents.org.uk/for-providers/registering-with-the-ofs/guide-to-the-ofs-register/). UKPRN is the stable identity and is canonicalised with `String(value).trim()` without recreating it numerically. The full content SHA-256 is the source version. Response Last-Modified and ETag are recorded when supplied; fetch time is labelled only as fetch time and is never presented as an official extract date.

The current workbook supports these signals: `NEW_PROVIDER_REGISTERED`, `PROVIDER_DEREGISTERED`, `PROVIDER_NAME_CHANGED`, `REGISTRATION_CATEGORY_CHANGED`, `SPECIFIC_CONDITION_ADDED`, `SPECIFIC_CONDITION_REMOVED`, `DEGREE_AWARDING_POWER_CHANGED`, `UNIVERSITY_TITLE_STATUS_CHANGED`, `FEE_LIMIT_CHANGED`, `TEF_OUTCOME_CHANGED`, and `TRADING_NAME_CHANGED`.

The primary Register sheet contains currently registered providers but no explicit registration-date/status column. A provider is treated as newly registered only when its UKPRN was absent from the previous validated Register and appears in the current one. A provider is treated as deregistered only when it disappears from the Register and is explicitly present in the workbook's section 22 or section 18 deregistration sheet. Any unexplained disappearance is a source anomaly, not a deregistration signal. Fresh baselines never emit every provider as new.

Specific ongoing conditions and trading names are Unicode-normalised, whitespace-normalised, deduplicated and deterministically sorted. Reordering or line-break-only changes produce no signal. Degree-awarding powers and university-title fields are compared as official composite values. The current fee field contains the official fee-limit category (for example `Higher`), not a numeric price, so the Actor preserves the official string. TEF is also preserved as supplied and is not converted into a quality score.

### Privacy and safe state

The source workbook includes provider contact addresses and email addresses. These fields, websites, contact-person details, and raw rows are excluded from the canonical snapshot and Dataset. Signals retain only UKPRN, provider name, regulatory attributes, compact before/after values and source provenance (`PRIVACY_MINIMISATION_PASS`).

Live processing is fetch XLSX → validate ZIP/workbook/sheets/columns → privacy projection → normalize → stable-key and anomaly guards → load previous snapshot → diff/filter → Dataset → `OUTPUT` → snapshot commit. Snapshot commit is last, so fetch, parse, Dataset, or OUTPUT failures retain the previous good state. Guards cover minimum bytes/provider count, XLSX magic, required sheets/columns, null or conflicting UKPRNs, row collapse, empty workbook, malformed workbook, and unexplained disappearance.

A fresh run writes no Dataset items, reports `BASELINE_INITIALIZED`, and stores the complete snapshot. An unchanged source emits no signals. `maxItems` limits Dataset output only. `mode: "sample"` is the free Console prefill: it performs no HTTP, never opens the production named KVS, uses deterministic fixtures through the production normalize/diff/filter path, emits every implemented signal type, and returns `snapshotUpdated: false`.

### Licence and limitations

**Contains information from the Office for Students licensed under the Open Government Licence v3.0.** The [OfS copyright page](https://www.officeforstudents.org.uk/copyright/) states that OfS-owned data and content are reusable under OGL with acknowledgement; separately identified third-party content requires separate permission. This Actor uses no OfS logo and does not imply official status or endorsement.

Limitations include upstream corrections, workbook schema changes, the lack of an explicit registration date in the current Register sheet, categorical rather than numeric fee-limit data, and source publication timing. Output is monitoring evidence, not a regulatory or quality judgement.

# Actor input Schema

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

Sample demonstrates signals without HTTP or live snapshot access.

## `signalTypes` (type: `array`):

Optional exact signal-type filter.

## `ukprns` (type: `array`):

Optional exact UKPRN filter, preserved as strings.

## `registrationCategories` (type: `array`):

Optional exact official registration-category filter.

## `providerNames` (type: `array`):

Optional case-insensitive provider-name substring filter.

## `conditionText` (type: `array`):

Optional case-insensitive added or removed condition text filter.

## `baselineOnly` (type: `boolean`):

Store a validated live baseline without signals.

## `maxItems` (type: `integer`):

Caps Dataset output only; the snapshot stays complete.

## Actor input object example

```json
{
  "mode": "sample",
  "baselineOnly": false,
  "maxItems": 30
}
```

# Actor output Schema

## `OUTPUT` (type: `string`):

No description

# 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": "sample",
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("starshaped_bullsnake/england-higher-education-regulatory-register-change-signals").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": "sample",
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("starshaped_bullsnake/england-higher-education-regulatory-register-change-signals").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": "sample",
  "maxItems": 30
}' |
apify call starshaped_bullsnake/england-higher-education-regulatory-register-change-signals --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,starshaped_bullsnake/england-higher-education-regulatory-register-change-signals"
        }
    }
}
```

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/2YqNK02zAfAuJhyMh/builds/1CDIeLFvCVQuw6i2a/openapi.json
