# UK Port Freight Flow Records — DfT PORT0499 (`nexgensignal/uk-port-freight-flow-records`) Actor

Keyless pay-per-record UK DfT port freight flows (PORT0499) — port, route, cargo, direction, year, tonnage, units. Figures verbatim; no persons. OGL v3.0. GOLD $0.05 ladder.

- **URL**: https://apify.com/nexgensignal/uk-port-freight-flow-records.md
- **Developed by:** [NexGen Signal](https://apify.com/nexgensignal) (community)
- **Categories:** Business, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $33.50 / 1,000 port freight records

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/actors/running/actors-in-store.md#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

## UK Port Freight Flow Records — DfT PORT0499

**Keyless. Pay per record. Every UK major-port freight flow — port, route, cargo, and year — as one clean table.**

This actor turns the **UK Department for Transport (DfT) port freight statistics** into clean, per-flow records — the official record-level dataset of freight moving through the UK's major ports. Each run reads the DfT's keyless PORT0499 "port level downloadable dataset" and delivers one row per port / route / cargo / year flow: the major port, the load-or-unload region and country, the direction, the cargo group, category, and description, and the tonnage and unit figures. Port / route / cargo / year grain, structured for engineering use, under the Open Government Licence v3.0, with no personal data of any kind.

### What this is, in one paragraph

Every year the DfT publishes how much freight moved through each UK major port, broken down by the port, the region and country at the other end of the route, the direction of travel, and the type of cargo. This actor reads the record-level PORT0499 table and flattens each of those flows into a single analysis-ready record: the year, the major port, the load/unload region and country, the direction (inwards or outwards), the cargo group / category / description, and the tonnage, loaded-unit, empty-unit, and total-unit figures. All figures are official statistics in thousands, carried **verbatim** as published — including the source's shorthand where "0" is absolute zero and "LOW" means less than half the smallest displayed unit. It is the freight-flow layer of the UK's port network. You are billed only for records actually delivered.

### Who buys this and for what job

- **Maritime-logistics, port-authority, and supply-chain teams** analysing freight volumes by port, route, and cargo type over a quarter-century of history.
- **Trade-flow, economics, and market-sizing products** mapping which cargoes move between the UK and which world regions.
- **Infrastructure, planning, and ESG teams** studying modal freight patterns and port throughput trends.
- **Data engineers** who want the PORT0499 record-level table as clean rows without opening a 9 MB spreadsheet and hand-parsing its two stacked tables.

### Open Government Licence v3.0 — free commercial reuse

One licence rider travels on every record. DfT port freight statistics are published under the **Open Government Licence v3.0 (OGL v3.0)** — free to reuse, including commercially, with attribution: "Contains public sector information licensed under the Open Government Licence v3.0." That attribution travels on every record. One honest caveat rides too: these are official statistics as published (figures in thousands, with "LOW"/"0" shorthand carried verbatim), not a forecast or a commercial valuation.

### Flow grain — no person data

The unit of every record is a freight flow — a port, a route, a cargo type, a year — never a person. The dataset carries no natural-person fields; ports, regions, countries, cargo categories, and directions are the entire dimensional payload, and the measures are tonnage and unit counts. A person-key guard runs on every record as a pure backstop.

### Pricing

| Event | Free plan | Bronze | Silver | Gold / Platinum / Diamond |
|-------|-----------|--------|--------|---------------------------|
| `port_freight_record` | $0.05 | $0.045 | $0.04 | $0.0335 |

Delivered before charged. Blocked runs and empty results cost nothing.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `portContains` | string | — | Optional. Keep only rows whose major port contains this text (e.g. Dover, Felixstowe, Grimsby). |
| `cargoContains` | string | — | Optional. Keep only rows whose cargo group or description contains this text (e.g. containers, liquid bulk). |
| `direction` | string | — | Optional direction filter: Inwards or Outwards. |
| `year` | integer | — | Optional year to filter (e.g. 2024). |
| `maxRecords` | integer | 500 | Ceiling on records delivered and billed. |

### Output

One JSON object per flow. Real example (values as published):

```json
{
  "record_id": "2024:Dover:France:Inwards:51",
  "year": "2024",
  "major_port": "Dover",
  "load_unload_region": "Europe (excl. UK)",
  "load_unload_country": "France",
  "direction": "Inwards",
  "cargo_group": "Roll-on/Roll-off",
  "cargo_category": "51",
  "cargo_description": "Road goods vehicles",
  "tonnage_thousands": "12,345",
  "tonnage_thousands_num": 12345.0,
  "loaded_units_thousands": "678",
  "empty_units_thousands": "90",
  "total_units_thousands": "768",
  "source": "UK DfT port freight statistics (PORT0499)",
  "licence": "UK Department for Transport ... Open Government Licence v3.0 ... carried VERBATIM ...",
  "disclaimer": "UK major-port freight traffic records at port / route / cargo / year grain ...",
  "observed_at": "2026-08-22T00:00:00Z"
}
```

An unbilled `RUN_RECEIPT` records the robots check, the resolved file, the filters, rows matched and delivered, and whether charged equals delivered.

### Field reference

Each record is one freight flow. Dimensions: `year`, `major_port`, `load_unload_region`, `load_unload_country`, `direction`, `cargo_group`, `cargo_category`, and `cargo_description`. Measures: `tonnage_thousands` (verbatim string, so the "LOW"/"0" shorthand is preserved) alongside `tonnage_thousands_num` (a numeric parse, null where the value is shorthand), plus `loaded_units_thousands`, `empty_units_thousands`, and `total_units_thousands`. Identity: `record_id` (year + port + country + direction + cargo category). Provenance: `source`, `source_url`, `licence`, `attribution`, `disclaimer`, and `observed_at`.

### How a run works

A run first re-reads the source host's robots posture from your runtime — the GOV.UK assets host that serves the data file — and stops at the door if a Disallow ever covers it. It resolves the current PORT0499 spreadsheet URL from the DfT statistical-data-set page (the file's asset URL is content-hashed and changes each publication, so it is discovered fresh each run), downloads the spreadsheet once, and streams the record-level data table — skipping the notes, header, and summary rows and the sheet's empty row-padding, keeping only the year-led data rows — carrying every figure **verbatim**, delivered **before** it is charged, so a blocked or empty run costs you nothing. The actor stops at your `maxRecords` ceiling and records `charge_equals_delivered` in the receipt.

### Coverage and scope

The PORT0499 record-level table holds on the order of **146,000 port / route / cargo / year flows** spanning **2000 to 2025**. Because each record carries the `year`, `major_port`, `direction`, and cargo fields, segmenting by port, cargo type, trade route, or year — and building a time series for any of them — is straightforward. Pull one port, one cargo type, or the whole table to seed a freight-flow warehouse.

### Working with the flows

The table is built to be pivoted, and the fields carry the structure to do it. Because every record carries the `year`, a single filtered pull sorted by year reconstructs a port's throughput trajectory for a given route or cargo without any cross-table work. The `direction` splits inbound from outbound so a trade-balance view falls out of one filter, and the `load_unload_region` / `load_unload_country` pair locates the other end of each route so flows can be rolled up to a continent or drilled to a single country. The cargo hierarchy — `cargo_group`, `cargo_category`, and `cargo_description` — lets an analyst move between a coarse modal view (roll-on/roll-off, liquid bulk, containers) and a fine commodity view in the same dataset. Because the tonnage and unit figures travel both verbatim and as a parsed number, a consumer can preserve the official "LOW"/"0" shorthand for fidelity and still compute on the numeric column, and two annual pulls can be diffed to see how a port's freight mix shifted year over year.

### Cost guidance

One `port_freight_record` per delivered flow: cost = rows delivered × your plan's per-record price. Scope with `portContains`, `cargoContains`, `direction`, or `year` to keep runs bounded. The whole table is ~146,000 rows; 1,000 rows is **$50** (Free) / **$33.50** (Gold).

### Honest limitations

- **Official statistics, as published.** Figures are in thousands and carry the source's "LOW"/"0" shorthand verbatim; this actor reformats, it does not recompute.
- **Major ports.** PORT0499 covers UK major-port freight traffic at the published grain; it is not a vessel-movement or berth-level feed.
- **Attribute the DfT.** The OGL v3.0 attribution travels on every record.
- **No person data** of any kind.

### Differentiation

This is a **net-new** category for the NexGenData fleet — no existing fleet actor covers UK port freight flows. It is a **different jurisdiction and a different source** from the fleet's US Bureau of Transportation Statistics freight cells (BTS international / carrier / air freight, which cover US carriers and airports), and distinct from any air-freight or road-freight cell — this is UK **sea** port freight, by port, route, cargo, and year. Its specific job is the **DfT PORT0499 record-level freight-flow table**.

### The NexGen Signal family

Part of the NexGen Signal family of pay-per-record data products:

- [GB NaPTAN Transit Node Records — DfT](https://apify.com/nexgensignal/gb-naptan-transit-node-records)
- [UK Road Collision Records — DfT STATS19](https://apify.com/nexgensignal/uk-road-collision-records)
- [EU Maritime Environmental Measure Records — WISE](https://apify.com/nexgensignal/eu-maritime-environmental-measure-records)
- [UK Company Status Records — Companies House](https://apify.com/nexgensignal/uk-company-status-records)
- [EU Vehicle CO2 Records — EEA](https://apify.com/nexgensignal/eu-vehicle-co2-records)

*Source: UK Department for Transport, port and domestic waterborne freight statistics, table PORT0499 (assets.publishing.service.gov.uk, resolved via gov.uk). Contains public sector information licensed under the Open Government Licence v3.0 — free to reuse, including commercially, with attribution to the Department for Transport. Port / route / cargo / year grain; figures in thousands carried verbatim including the "LOW"/"0" shorthand; no person data of any kind. Official statistics as published, not a forecast.*

# Actor input Schema

## `portContains` (type: `string`):

Optional. Keep only rows whose major port contains this text (e.g. Dover, Felixstowe, Grimsby).

## `cargoContains` (type: `string`):

Optional. Keep only rows whose cargo group or description contains this text (e.g. containers, liquid bulk).

## `direction` (type: `string`):

Optional direction filter: Inwards or Outwards.

## `year` (type: `integer`):

Optional year to filter (e.g. 2024).

## `maxRecords` (type: `integer`):

Maximum records delivered and billed.

## Actor input object example

```json
{
  "maxRecords": 500
}
```

# Actor output Schema

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

Delivered records.

# 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 = {
    "maxRecords": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgensignal/uk-port-freight-flow-records").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 = { "maxRecords": 500 }

# Run the Actor and wait for it to finish
run = client.actor("nexgensignal/uk-port-freight-flow-records").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 '{
  "maxRecords": 500
}' |
apify call nexgensignal/uk-port-freight-flow-records --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexgensignal/uk-port-freight-flow-records"
        }
    }
}

```

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/z6J2IO2mcx9b8d2B2/builds/WckPHOwigcZSRQUUk/openapi.json
