# UN Comtrade Trade Flow Change Report (`taroyamada/un-comtrade-trade-flow-change-report`) Actor

Monitor bounded official UN Comtrade preview queries for new, changed, or removed trade-flow records and generate source-linked trend reports and exports. Each watch uses one HS product and one period per request; preview results are limited to 500 records and are not comprehensive trade data.

- **URL**: https://apify.com/taroyamada/un-comtrade-trade-flow-change-report.md
- **Developed by:** [naoki anzai](https://apify.com/taroyamada) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 trade flow rows

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/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

## UN Comtrade Trade Flow Change Report

Trade analysts, procurement teams, and supply-chain researchers enter one or more bounded UN Comtrade watches.
Each watch specifies one reporter, partner, HS product, flow, frequency, and period for the official keyless preview API.
The Actor returns a report-first change alert, source-linked trend report, optional normalized rows, and export; unchanged checks are free.

### Store Quickstart

Run a free baseline for Japan exports to World for HS chapter 84 in annual 2023 data:

```json
{
  "watches": [
    {
      "id": "japan-world-hs84-2023",
      "reporterCode": "392",
      "partnerCode": "0",
      "hsCode": "84",
      "flowCode": "X",
      "frequency": "A",
      "period": "2023"
    }
  ],
  "monitorKey": "japan-world-hs84",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": false,
  "emitUnchanged": false,
  "maxChargeUsd": 35,
  "dryRun": false
}
```

Repeat the same input on a schedule. New, changed, or removed records in the bounded response create alerts and the requested report. A source-confirmed unchanged response emits zero rows and zero charges.

The anonymous preview API is intentionally limited: one HS product and one period per request, at most 500 records, and no claim of complete country-period coverage. Use multiple narrow watches rather than assuming a preview is a full trade matrix.

### Run the next report

Use `emit_backfill` and `emitExport` when you explicitly want the current bounded snapshot packaged as a report and export:

```json
{
  "watches": [
    {
      "id": "japan-world-hs84-2023-report",
      "reporterCode": "392",
      "partnerCode": "0",
      "hsCode": "84",
      "flowCode": "X",
      "frequency": "A",
      "period": "2023"
    }
  ],
  "monitorKey": "japan-world-hs84-report",
  "initialRunMode": "emit_backfill",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": true,
  "maxChargeUsd": 35,
  "dryRun": false
}
```

### Input examples

#### Monthly imports

```json
{
  "watches": [
    {
      "id": "us-imports-hs30-202501",
      "reporterCode": "840",
      "partnerCode": "0",
      "hsCode": "30",
      "flowCode": "M",
      "frequency": "M",
      "period": "202501"
    }
  ],
  "monitorKey": "us-imports-hs30-monthly",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "maxChargeUsd": 35,
  "dryRun": false
}
```

#### Several narrow products and periods

```json
{
  "watches": [
    {
      "id": "japan-hs84-2022",
      "reporterCode": "392",
      "partnerCode": "0",
      "hsCode": "84",
      "flowCode": "X",
      "frequency": "A",
      "period": "2022"
    },
    {
      "id": "japan-hs84-2023",
      "reporterCode": "392",
      "partnerCode": "0",
      "hsCode": "84",
      "flowCode": "X",
      "frequency": "A",
      "period": "2023"
    }
  ],
  "monitorKey": "japan-hs84-period-comparison",
  "initialRunMode": "emit_backfill",
  "generateReport": true,
  "emitExport": true,
  "maxChargeUsd": 35,
  "dryRun": false
}
```

#### Dry run

```json
{
  "watches": [],
  "monitorKey": "preview-dry-run",
  "generateReport": true,
  "emitRawRows": true,
  "emitExport": true,
  "dryRun": true
}
```

Dry run output is deterministic and illustrative. It does not call UN Comtrade, write monitor state, or charge PPE.

### Sample output

The first row is the aggregate report when report generation is enabled:

```json
{
  "rowType": "trade_trend_report",
  "billingEventName": "trade-trend-report",
  "report": {
    "reportType": "bounded_trade_flow_change_report",
    "queryCount": 1,
    "changedRecordCount": 2,
    "newRecordCount": 1,
    "updatedRecordCount": 1,
    "removedRecordCount": 0,
    "byFlow": [{"key": "X", "count": 2}],
    "coverageNote": "Official preview response only; one product and one period per request, max 500 records, not comprehensive trade data."
  }
}
```

See [`docs/sample-output.json`](docs/sample-output.json) for representative report, alert, normalized row, and export records.

### Output fields

- `report`: changed-record counts and bounded query dimensions, emitted before detail rows.
- `record`: reporter, partner, HS code, flow, period, trade value, quantity, and source-linked public fields when supplied by the API.
- `previousRecord`: prior snapshot for value changes and removals.
- `matchedWatchIds`: duplicate watches are fetched once and associated with all matching IDs.
- `limitations` and `prohibitedInterpretations`: safeguards travel with every row.

The Actor does not claim complete trade data, market share, forecast accuracy, causality, supplier identity, sanctions status, legal compliance, or investment value. Values are reported as published by the source for the selected bounded query.

### Pricing

| Event | Price | Delivered when |
|---|---:|---|
| `trade-flow-row` | $0.006 | Optional normalized current record for a changed snapshot |
| `trade-flow-change-alert` | $0.20 | A new, changed, or removed record is observed |
| `trade-trend-report` | $12.00 | Changed records are grouped into a report-first summary |
| `trade-export-generated` | $8.00 | Selected changed records are packaged as a compact export |

There is no start charge. The complete planned PPE amount is estimated before the first push and the run fails closed if it exceeds `maxChargeUsd`.

### Baseline and no-change billing

- `baseline_only` stores the first complete source snapshot with zero rows and zero charges.
- A later unchanged response emits zero rows and zero charges.
- `emitUnchanged` cannot override this safeguard.
- State is committed only after every billable row receives a positive PPE receipt.
- Any API error, response validation error, partial/truncated preview, or state-save failure fails closed.

### Compliance and source limits

- Only the official anonymous UN Comtrade preview endpoint is used; no login, browser session, subscription key, or user API key is accepted.
- Requests are sequential at no more than one request per second and use `maxRecords=500`.
- A watch contains one period and one HS product. Multiple periods/products require separate watches and are fetched separately.
- Preview responses may be incomplete for broad queries. A response that indicates truncation, partial data, more than 500 records, or exactly 500 returned records is rejected rather than presented as complete.
- The output is descriptive public data and is not legal, customs, sanctions, tax, investment, procurement, or trade advice.
- No UN endorsement or affiliation is implied.

### See also

- [Government Tender & Grants Alert Report](https://apify.com/taroyamada/government-tender-grants-monitor) for public tender and grant opportunity watches.
- [GovCon Recompete Watch](https://apify.com/taroyamada/govcon-recompete-incumbent-watch-scraper) for public award and recompete signals.
- [Procurement Intelligence](https://apify.com/taroyamada/procurement-intel-actor) for adjacent public procurement records.

### Development

```text
npm test
npm start
```

# Actor input Schema

## `watches` (type: `array`):

Each watch creates at most one official preview API request. Duplicate query dimensions are fetched once and matched to all watch IDs.

## `monitorKey` (type: `string`):

Stable isolated state namespace for this recurring watch portfolio.

## `initialRunMode` (type: `string`):

baseline\_only stores the first bounded snapshot with zero rows. emit\_backfill emits the current changes for an explicit paid run.

## `generateReport` (type: `boolean`):

Emit one report-first aggregate row when changes are observed.

## `emitRawRows` (type: `boolean`):

Emit one low-priced normalized row per changed current record. Report and alerts remain the primary output.

## `emitExport` (type: `boolean`):

Emit a compact source-linked JSON export when changes are observed.

## `emitUnchanged` (type: `boolean`):

Accepted for compatibility only. Unchanged runs always emit zero rows and zero charges.

## `maxChargeUsd` (type: `number`):

The complete planned PPE charge is estimated before the first dataset push. The run fails closed if this cap would be exceeded.

## `requestTimeoutSeconds` (type: `integer`):

Timeout for each official preview request.

## `maxRetries` (type: `integer`):

Bounded retries for 429 and transient 5xx responses only.

## `dryRun` (type: `boolean`):

Return deterministic representative report, alert, row, and export records without API calls, state writes, or charges.

## Actor input object example

```json
{
  "watches": [
    {
      "id": "japan-world-hs84-2023",
      "reporterCode": "392",
      "partnerCode": "0",
      "hsCode": "84",
      "flowCode": "X",
      "frequency": "A",
      "period": "2023"
    }
  ],
  "monitorKey": "un-comtrade-trade-flow-watch",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": false,
  "emitUnchanged": false,
  "maxChargeUsd": 35,
  "requestTimeoutSeconds": 30,
  "maxRetries": 3,
  "dryRun": false
}
```

# 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 = {
    "watches": [
        {
            "id": "japan-world-hs84-2023",
            "reporterCode": "392",
            "partnerCode": "0",
            "hsCode": "84",
            "flowCode": "X",
            "frequency": "A",
            "period": "2023"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("taroyamada/un-comtrade-trade-flow-change-report").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 = { "watches": [{
            "id": "japan-world-hs84-2023",
            "reporterCode": "392",
            "partnerCode": "0",
            "hsCode": "84",
            "flowCode": "X",
            "frequency": "A",
            "period": "2023",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("taroyamada/un-comtrade-trade-flow-change-report").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "watches": [
    {
      "id": "japan-world-hs84-2023",
      "reporterCode": "392",
      "partnerCode": "0",
      "hsCode": "84",
      "flowCode": "X",
      "frequency": "A",
      "period": "2023"
    }
  ]
}' |
apify call taroyamada/un-comtrade-trade-flow-change-report --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=taroyamada/un-comtrade-trade-flow-change-report",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/5YONCkmVzurhmKBbW/builds/1NUxuKWLow3fOvQtM/openapi.json
