# UK Trade Quota Balance & Status Change Signals (`starshaped_bullsnake/uk-trade-quota-balance-status-change-signals`) Actor

Monitor official UK quota-period status, balance, allocation and scope changes.

- **URL**: https://apify.com/starshaped\_bullsnake/uk-trade-quota-balance-status-change-signals.md
- **Developed by:** [Starshape Tools](https://apify.com/starshaped_bullsnake) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 uk trade quota 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

## UK Trade Quota Balance & Status Change Signals

Turn the official daily UK trade-quota dataset into compact, filterable change-intelligence signals. This Actor is for **monitoring, analytics, and change intelligence only**. It is not real-time quota availability, customs-declaration eligibility, guaranteed remaining quota, guaranteed duty treatment, or operational import-decision support. HMRC allocations can take several days to appear in the published balance; always use the official operational channels for customs decisions.

### Source and identity

The source is the Department for Business and Trade Data API report `uk-trade-quotas / quotas-including-current-volumes`, derived from UK Tariff and HM Revenue & Customs data and normally updated daily. Every live run resolves `latest` once, extracts the immutable `vX.Y.Z` identifier, and uses only that pinned version for metadata and CSV requests. `quota_definition__sid` is the identity of a quota definition/quota period. A quota order number can have many periods and is deliberately not the entity key. Order numbers stay strings; cosmetic leading-zero differences do not produce a signal.

The Actor stores only quota-level regulatory/trade fields needed for comparisons. It does not ingest personal data or metadata contacts. `#NA`, blank, and null values become `null`; a missing balance never becomes zero. Multi-value scopes are Unicode-normalized, trimmed, deduplicated, and sorted so source ordering alone cannot trigger a signal. Fill rate is the official source value and is not recalculated or reinterpreted.

### Signals

- `NEW_QUOTA_PERIOD` — a SID newly appears in the official full dataset; it does not claim a new legal scheme or operational availability.
- `QUOTA_STATUS_CHANGED` — the official status string changed. The Actor never infers Exhausted, Closed, or availability from balance.
- `BALANCE_DECREASED` / `BALANCE_INCREASED` — the official balance changed; no duplicate generic event is emitted.
- `FILL_RATE_CHANGED`, `LAST_ALLOCATION_DATE_CHANGED`, `VALIDITY_PERIOD_CHANGED`.
- `COMMODITY_SCOPE_CHANGED`, `GEOGRAPHICAL_SCOPE_CHANGED`, and `INITIAL_VOLUME_CHANGED`.

SID disappearance is not a business signal. Because the source includes historical quotas, excessive disappearance is treated as a source anomaly and blocks output and snapshot replacement.

### Safe state lifecycle

Live processing is: resolve latest → pin immutable version → fetch and validate OGL metadata → fetch CSV → schema and anomaly validation → normalization and stable-key validation → load previous snapshot → diff and filter → Dataset → `OUTPUT` summary → snapshot commit. Snapshot commit is last; Dataset or OUTPUT write failures retain the previous good snapshot.

On a fresh key-value store, the full validated snapshot is saved, Dataset stays empty, `signalsFound` and `signalsEmitted` are zero, and the summary says `BASELINE_INITIALIZED`. Re-running the same version/state emits nothing. `maxItems` limits Dataset items only; snapshots are always complete. The summary records the pinned version, release header, bytes, SHA-256, row/entity counts, SID profile, signal counts, and snapshot information.

Guards reject HTML/error payloads, malformed CSV, missing required columns, invalid finite numbers, null SIDs, conflicting duplicate SIDs, unexpectedly small files/row sets, a 30%+ row collapse, and implausible SID disappearance. Exact duplicate SID rows may collapse. Source-side staleness is reported through the pinned release timestamp rather than misrepresented as an Actor failure.

### Input and sample mode

Filters include signal types, quota order numbers, official statuses, commodity codes, geographical areas, minimum absolute balance change, and minimum fill-rate change. `baselineOnly` refreshes a validated baseline without signals.

`mode: "sample"` is the free demonstration path and the Console prefill. It performs no HTTP request, never opens or mutates the production named key-value store, uses deterministic fixtures through the production normalize/diff/filter path, covers every core signal, writes a non-empty Dataset, and returns `snapshotUpdated: false`.

### Licence, attribution, and privacy

The pinned version CSVW metadata identifies the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/), which permits copying, publication, distribution, adaptation, and commercial use subject to its terms and exemptions. **Contains public sector information licensed under the Open Government Licence v3.0. Source: Department for Business and Trade / HM Revenue & Customs UK trade quotas.**

The product processes quota-level public data, not personal data (`PRIVACY_MINIMISATION_PASS`). Known limitations are the source publication cadence, possible HMRC allocation lag, upstream corrections, and the fact that output describes published changes rather than legal or operational advice.

# Actor input Schema

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

Sample demonstrates every core signal without HTTP or live snapshot access.

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

Optional exact signal-type filter.

## `quotaOrderNumbers` (type: `array`):

Exact display values; kept as strings.

## `statuses` (type: `array`):

Optional exact official status filter.

## `commodityCodes` (type: `array`):

Optional exact canonical commodity-code filter.

## `geographicalAreas` (type: `array`):

Optional case-insensitive geographical-area substring filter.

## `minBalanceChangeAbsolute` (type: `number`):

Minimum absolute official balance delta for numeric changes.

## `minFillRateChange` (type: `number`):

Absolute change on the official 0–1 value.

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

Validate and store a live baseline without signals.

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

Caps Dataset output only; the live snapshot is always complete.

## Actor input object example

```json
{
  "mode": "sample",
  "minBalanceChangeAbsolute": 0,
  "minFillRateChange": 0,
  "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/uk-trade-quota-balance-status-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/uk-trade-quota-balance-status-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/uk-trade-quota-balance-status-change-signals --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,starshaped_bullsnake/uk-trade-quota-balance-status-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/frGcZ0h5ZvLehgzu2/builds/cvnidECJhTfDgIpvy/openapi.json
