# UKRI Project Status Change Watch (`nexgenwatch/uk-ukri-project-status-watch`) Actor

Status transitions on UKRI research projects — active, closed and back again. Sourced from the public UKRI Gateway to Research API, logged-out, no key.

- **URL**: https://apify.com/nexgenwatch/uk-ukri-project-status-watch.md
- **Developed by:** [NexGen Watch](https://apify.com/nexgenwatch) (community)
- **Categories:** Business, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $134.00 / 1,000 ukri project deltas

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

## UKRI Project Status Change Watch

Status transitions on UKRI research projects — active, closed and back again.

### Source

UKRI Gateway to Research **GtR-2 REST API** (public, logged-out)

- `https://gtr.ukri.org/gtr/api/projects`

Public, logged-out only — no API key, login, cookie or CAPTCHA.

### Why this Actor reads a different API from the rest of the UKRI family

The other UKRI watches read the search API, which carries the date sort they need. It returns
`status: null` on **339 of 339** live records — measured 2026-07-27. A status watch built on it
would compare nothing to nothing and report a clean zero forever, which from the outside is
indistinguishable from a quiet regulator.

The Project Status facet on that same API advertises Closed 146,235 / Active 28,155. The index
holds the field; the record does not. Facet counts are advertisements, not evidence.

GtR-2 **does** carry status — 85 Closed / 15 Active in a 100-record sample. It has no date sort,
which a status watch does not need: it fetches the projects you name and diffs them.

### You name the projects — this Actor does not sweep the corpus

`project_references` is **required**, capped at 200, and one lookup is issued per project you
name. That count is visible to you before you run. Without a list there is nothing to watch, so
the run fails loudly rather than reporting a healthy-looking nothing.

A reference that returns no exact match is **reported as NOT FOUND**, never silently dropped — a
typo must not read as a quiet source.

Parameters proven under the filter-proof law, control-vs-test, 2026-07-27:

| parameter | result |
|---|---|
| `q=<grant reference>` | **REAL** — totalSize 174,404 → 1 |
| `ref=<grant reference>` | **IGNORED** — HTTP 200, totalSize unchanged at 174,404 |
| page size 5 | rejected, HTTP 400; 25 is the documented floor |

`ref` is exactly the parameter you would reach for first, and it does nothing. `q` is a SEARCH
rather than a lookup, so this Actor keeps only the project whose reference matches exactly.

### One delta type per Actor

This Actor watches **`project-status`** and nothing else. A project's FIRST sighting is absorbed into
the baseline silently — selling you your own seed run as a status change would be dishonest.

### Unit nouns (Pay-Per-Event)

- `apify-actor-start` — reserved platform event, charged per GB of run memory. This Actor is
  pinned to 1024 MB, so it is one event per run.
- `source-check` — once per run after the source enumeration terminates, seed runs and
  evidenced-zero runs included. Not charged when the source refused the read.
- `ukri-project-delta` — the value event, charged per status change emitted. Billed deltas are
  capped at 500 per run; any overflow is reported as a withholding and is not charged.

### Pricing

| Event | FREE | BRONZE | SILVER | GOLD+ |
|---|---|---|---|---|
| Actor Start (`apify-actor-start`) | $0.02 | $0.02 | $0.02 | $0.02 |
| Source check (`source-check`) | $0.10 | $0.09 | $0.08 | $0.067 |
| UKRI Project Delta (`ukri-project-delta`) | $0.20 | $0.18 | $0.16 | $0.134 |

Prices are the filed pay-per-event amounts per plan tier (PLATINUM/DIAMOND match GOLD). Blocked and refused runs do not intentionally charge value events.

### Run it WEEKLY, not daily

Schedule this Actor **once a week**. A project moving from Active to Closed is not an
hour-sensitive event, and Gateway to Research is republished in bursts rather than continuously
— its own index reported a last refresh of **14 Apr 2026** when measured on 2026-07-27, 104 days
later. A daily schedule pays seven `source-check` events a week to see the same thing. Override
it if you have a reason.

### Honest limits

Status is the publisher's own field and this Actor reports it verbatim; a project whose status
is null is **surfaced as such**, not watched, because a null cannot produce a delta. Gateway to
Research publishes awarded projects, not funding opportunities. Absence is never read as a
withdrawal. Public logged-out data only. Not investment, legal or research-funding advice.

# Actor input Schema

## `project_references` (type: `array`):

GtR grant references to watch, e.g. MR/X011811/1. REQUIRED — this Actor watches the projects you name. Max 200; one lookup is issued per reference.

## `max_items` (type: `integer`):

Maximum records or deltas to emit this run.

## `watch_mode` (type: `boolean`):

Seed a private baseline and emit only confirmed later changes. The first run emits zero deltas by design.

## `baseline_id` (type: `string`):

Named watch baseline. Changing the watched set derives a new one.

## Actor input object example

```json
{
  "project_references": [
    "MR/X011811/1"
  ],
  "max_items": 500,
  "watch_mode": true
}
```

# Actor output Schema

## `results` (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 = {
    "project_references": [
        "MR/X011811/1"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgenwatch/uk-ukri-project-status-watch").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 = { "project_references": ["MR/X011811/1"] }

# Run the Actor and wait for it to finish
run = client.actor("nexgenwatch/uk-ukri-project-status-watch").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 '{
  "project_references": [
    "MR/X011811/1"
  ]
}' |
apify call nexgenwatch/uk-ukri-project-status-watch --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexgenwatch/uk-ukri-project-status-watch"
        }
    }
}

```

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/5EXjBVW7w5Mev3UOR/builds/Zl7AGw5TaYrytol8a/openapi.json
