# BIS Export Control List Change Report (`taroyamada/bis-export-control-list-change-report`) Actor

Monitor official BIS Entity List, Denied Persons List, and Unverified List downloads for source-linked descriptive matches and list changes. Baseline and unchanged checks are free.

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

## Pricing

from $8.00 / 1,000 bis restricted party 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

## BIS Export Control List Change Report

Export-control teams, procurement reviewers, and audit analysts provide BIS list types plus optional country/name watch conditions and receive source-linked descriptive alerts, delta reports, and JSON exports from official BIS downloads.

You input a recurring watch and a stable `monitorKey`; the Actor reads the official Entity List, Denied Persons List, and Unverified List files and compares them with the prior complete snapshot.

You receive potential source-linked matches and list deltas, never an identity, authorization, legal, or transaction decision.

### Store Quickstart

Use the first run as a free baseline. It stores the complete official source bundle and emits zero rows and zero charges.

```json
{
  "watchlists": [{
    "id": "dpl-name-watch",
    "listTypes": ["denied_persons"],
    "names": ["SEMICONDUCTOR SYSTEMS INTL"],
    "countries": []
  }],
  "monitorKey": "dpl-name-watch",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": false,
  "emitUnchanged": false,
  "maxChargeUsd": 50,
  "dryRun": false
}
```

#### Example 1: Country watch across all three BIS lists

```json
{
  "watchlists": [{
    "id": "asia-country-watch",
    "listTypes": ["entity", "denied_persons", "unverified"],
    "names": [],
    "countries": ["CN", "TW", "HK"]
  }],
  "monitorKey": "asia-country-watch",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitExport": true,
  "maxChargeUsd": 50,
  "dryRun": false
}
```

#### Example 2: Name watch with a report and export

```json
{
  "watchlists": [{
    "id": "supplier-name-watch",
    "listTypes": ["entity", "unverified"],
    "names": ["Example Robotics", "Example Components"],
    "countries": []
  }],
  "monitorKey": "supplier-name-watch",
  "initialRunMode": "emit_backfill",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": true,
  "maxChargeUsd": 50,
  "dryRun": false
}
```

#### Example 3: Deterministic local preview

```json
{
  "watchlists": [],
  "monitorKey": "preview",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": true,
  "emitExport": true,
  "dryRun": true
}
```

### What the output contains

- `bis_restricted_party_row`: optional normalized source row for an added, removed, or changed record.
- `bis_list_change_alert`: one source-linked alert per selected delta.
- `bis_export_control_delta_report`: an aggregate report with counts by list type and source pages.
- `bis_change_export`: a compact JSON-ready delta export.
- `record.sourceUrl` and `record.sourcePageUrl`: the official source references used for the observation.
- `potentialMatch: true` and `matchReason`: descriptive watch matching only.

The Actor does not enrich people or organizations, use private data, use a Trade.gov key, or make a legal, licensing, authorization, compliance, identity, or transaction conclusion.

### Pricing

| Event | Price |
| --- | ---: |
| `bis-restricted-party-row` | `$0.008` |
| `bis-list-change-alert` | `$0.50` |
| `bis-export-control-delta-report` | `$18` |
| `bis-change-export` | `$10` |

There is no start event. `baseline_only` and unchanged runs emit `0 rows / 0 charge`. Before delivery, the Actor estimates all event charges and stops if `maxChargeUsd` would be exceeded. It also requires a positive Apify `chargedCount` receipt for each delivered row and saves state only after delivery succeeds.

### Compliance guardrails

This is a descriptive public-data monitor, not a legal or export-control decision system. A potential match is not an identity resolution and not a conclusion about a party or transaction. Review the current official BIS source and obtain qualified advice before acting.

Only official BIS landing pages and BIS-hosted CSV/TXT downloads are accepted. HTML, empty files, header drift, inconsistent rows, and truncated quoted fields fail closed. See [source compliance](docs/source-compliance.md) for the full boundary.

### Run the next report

- [NIH grant publication output report](https://apify.com/taroyamada/nih-grant-publication-output-report) for source-linked research-funding output reporting.
- [Regulatory obligation change impact report](https://apify.com/taroyamada/regulatory-obligation-change-impact-report) for public regulatory-text change reporting.
- [Government tender and grants monitor](https://apify.com/taroyamada/government-tender-grants-monitor) for public opportunity watch reporting.

# Actor input Schema

## `watchlists` (type: `array`):

Each watch is a descriptive filter. Leave names and countries empty to observe all records in the selected list types.

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

Stable isolated state namespace for this recurring watch.

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

baseline\_only stores the first observation with zero rows. emit\_backfill delivers current matching records.

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

Generate one source-linked aggregate report when selected list changes exist.

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

Add one low-priced descriptive row for each selected list delta.

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

Generate one compact JSON export for the selected deltas.

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

Accepted for compatibility. Unchanged runs always remain zero rows and zero charge.

## `maxRowsPerList` (type: `integer`):

Fail closed instead of silently truncating an official source download.

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

Fail closed before the first push when the planned PPE charge exceeds this cap.

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

Return deterministic representative rows without requesting BIS, saving state, or charging events.

## Actor input object example

```json
{
  "watchlists": [
    {
      "id": "dpl-example-name",
      "listTypes": [
        "denied_persons"
      ],
      "names": [
        "SEMICONDUCTOR SYSTEMS INTL"
      ],
      "countries": []
    },
    {
      "id": "entity-country-watch",
      "listTypes": [
        "entity"
      ],
      "names": [],
      "countries": [
        "CN",
        "TW"
      ]
    },
    {
      "id": "all-list-delta-watch",
      "listTypes": [
        "entity",
        "denied_persons",
        "unverified"
      ],
      "names": [],
      "countries": []
    }
  ],
  "monitorKey": "bis-export-control-watch",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": false,
  "emitExport": false,
  "emitUnchanged": false,
  "maxRowsPerList": 10000,
  "maxChargeUsd": 50,
  "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 = {
    "watchlists": [
        {
            "id": "dpl-example-name",
            "listTypes": [
                "denied_persons"
            ],
            "names": [
                "SEMICONDUCTOR SYSTEMS INTL"
            ],
            "countries": []
        },
        {
            "id": "entity-country-watch",
            "listTypes": [
                "entity"
            ],
            "names": [],
            "countries": [
                "CN",
                "TW"
            ]
        },
        {
            "id": "all-list-delta-watch",
            "listTypes": [
                "entity",
                "denied_persons",
                "unverified"
            ],
            "names": [],
            "countries": []
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("taroyamada/bis-export-control-list-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 = { "watchlists": [
        {
            "id": "dpl-example-name",
            "listTypes": ["denied_persons"],
            "names": ["SEMICONDUCTOR SYSTEMS INTL"],
            "countries": [],
        },
        {
            "id": "entity-country-watch",
            "listTypes": ["entity"],
            "names": [],
            "countries": [
                "CN",
                "TW",
            ],
        },
        {
            "id": "all-list-delta-watch",
            "listTypes": [
                "entity",
                "denied_persons",
                "unverified",
            ],
            "names": [],
            "countries": [],
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("taroyamada/bis-export-control-list-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 '{
  "watchlists": [
    {
      "id": "dpl-example-name",
      "listTypes": [
        "denied_persons"
      ],
      "names": [
        "SEMICONDUCTOR SYSTEMS INTL"
      ],
      "countries": []
    },
    {
      "id": "entity-country-watch",
      "listTypes": [
        "entity"
      ],
      "names": [],
      "countries": [
        "CN",
        "TW"
      ]
    },
    {
      "id": "all-list-delta-watch",
      "listTypes": [
        "entity",
        "denied_persons",
        "unverified"
      ],
      "names": [],
      "countries": []
    }
  ]
}' |
apify call taroyamada/bis-export-control-list-change-report --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/yLh8afpnuRRUtYVQF/builds/M6oOff6W6XTgc4Fq2/openapi.json
