# US CBP Cargo Systems Messaging Service Change Signals (`starshaped_bullsnake/us-cbp-cargo-systems-messaging-service-change-signals`) Actor

Monitor official CBP CSMS bulletins and emit filter-isolated, stateful operational change signals.

- **URL**: https://apify.com/starshaped\_bullsnake/us-cbp-cargo-systems-messaging-service-change-signals.md
- **Developed by:** [Starshape Tools](https://apify.com/starshaped_bullsnake) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.00 / 1,000 cbp csms change 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

## US CBP Cargo Systems Messaging Service Change Signals

Monitor official U.S. Customs and Border Protection (CBP) Cargo Systems Messaging Service (CSMS) bulletins and emit one machine-readable change signal for each newly observed CSMS message that matches your monitor filters.

This Actor is designed for customs brokers, import/export operations, trade-compliance teams, logistics software, filing operations, and agents that need a persistent feed of operational CBP notices. It is **not** a customs ruling database, tariff calculator, legal-advice service, or substitute for controlling authorities.

### What CSMS is

CBP uses CSMS to communicate operational and trade-processing information to users of automated cargo systems, including Automated Commercial Environment (ACE) changes, CATAIR/documentation updates, tariff-related notices, quota messages, broker/compliance information, outages, filing guidance, corrections, reminders, and other trade-system notices.

Official sources used by this Actor:

- [CBP CSMS homepage](https://www.cbp.gov/trade/automated/cargo-systems-messaging-service)
- official GovDelivery CSMS RSS surfaced by the CBP page
- individual official GovDelivery bulletins
- [CBP CSMS archive](https://www.cbp.gov/document/publications/csms-archive) as the official gap fallback

Production acquisition does not depend on search engines or third-party mirrors.

### One CSMS message = one paid signal

The primary business event is:

`NEW_CSMS_MESSAGE`

A single new CSMS message produces at most one Dataset signal for one monitor. `messageClass`, `topicTags`, related CSMS numbers, relationships, and summary text are metadata on that same row; they are not separate paid events.

The stable source identity is the official **CSMS message number**. Message numbers are not assumed to be sequential.

### Deterministic message classes

The Actor recognizes explicit source-native title prefixes:

- `GUIDANCE`
- `UPDATED_GUIDANCE`
- `CORRECTION`
- `MANDATORY`
- `REMINDER`
- `UPDATE`
- `INFORMATION`
- `OTHER`

`OTHER` is the fallback when no approved explicit prefix is present. These are deterministic routing labels, not legal interpretations.

### Topic tags

The Actor can add deterministic tags when title/body text directly supports them:

- `ACE_SYSTEM`
- `CATAIR_OR_SCHEMA`
- `HTS_UPDATE`
- `TRADE_REMEDY`
- `QUOTA`
- `BROKER_COMPLIANCE`
- `OUTAGE_OR_MAINTENANCE`
- `FORCED_LABOR`
- `PGA`
- `EXPORT_FILING`
- `IMPORT_FILING`

A message can have multiple topic tags but still emits only one signal.

### Related CSMS messages

The Actor extracts referenced CSMS numbers. When the bulletin explicitly uses language such as updates, corrects, replaces, supersedes, or follow-up, the Actor stores the corresponding structured relationship.

Allowed relationship values are:

`UPDATES`, `CORRECTS`, `REPLACES`, `SUPERSEDES`, `FOLLOW_UP_TO`, `RELATED_TO`.

The Actor does not infer a stronger relationship than the source text states.

### First live run: baseline only

Each unique monitor starts independently.

On the first valid live run:

1. the Actor enumerates the official current CSMS window;
2. stores the accepted message identities for that monitor;
3. emits **zero business signals**.

Existing messages are not replayed as paid `NEW_CSMS_MESSAGE` events.

Later runs emit only newly observed messages that match that monitor.

### Filter-specific monitor identity

Monitor state is isolated by a deterministic fingerprint of these normalized filters:

- `messageClasses`
- `topicTags`
- `includeKeywords`
- `excludeKeywords`

`maxItems` is intentionally excluded.

Changing filters creates a new monitor baseline and does not replay historical messages as paid changes for the old monitor. Changing only `maxItems` keeps the same monitor identity.

### Pending queue and maxItems

`maxItems` caps Dataset output only.

If 80 new matching CSMS messages are discovered and `maxItems` is 30, the first 30 are emitted and the other 50 remain in the monitor's pending queue. On later runs, existing pending signals drain before newly created signals.

A successfully emitted signal is removed from pending state only after Dataset and `OUTPUT` persistence succeed and the accepted state is committed.

### Source-gap safety

The normal current source is the official GovDelivery RSS surfaced by the CBP CSMS page.

The Actor stores the accepted current-window identities. If a later run has no overlap with the previously accepted source window, it resolves the official CBP archive PDF, maps its CSMS rows to the GovDelivery short links embedded by the official archive, follows only the approved `lnks.gd -> content.govdelivery.com` path, and verifies that the destination bulletin carries the same CSMS number before using it.

If the archive cannot prove continuity into the current source window, a row cannot be mapped, a redirect leaves the approved hosts, or the destination bulletin number does not match, the Actor fails closed:

`SOURCE_GAP_ANOMALY`

In that state:

- business signals = 0
- accepted monitor state remains unchanged
- the Actor does not silently skip an unknown interval

Rotation out of the current source window is **never** interpreted as a deletion, revocation, or legal-status change.

### Input example

```json
{
  "mode": "live",
  "messageClasses": ["GUIDANCE", "CORRECTION", "MANDATORY"],
  "topicTags": ["ACE_SYSTEM", "CATAIR_OR_SCHEMA"],
  "includeKeywords": ["cargo release"],
  "excludeKeywords": ["test environment"],
  "maxItems": 30
}
```

Filter lists use OR matching within a list. Different filter groups must all pass. Exclude keywords take precedence.

### Output example

```json
{
  "signalType": "NEW_CSMS_MESSAGE",
  "csmsNumber": "70000001",
  "messageClass": "GUIDANCE",
  "topicTags": ["ACE_SYSTEM", "IMPORT_FILING"],
  "title": "GUIDANCE: Example ACE filing clarification",
  "issuedAt": "2026-09-25T12:00:00.000Z",
  "issuedAtOriginal": "09/25/2026 08:00 AM EDT",
  "bulletinUrl": "https://content.govdelivery.com/accounts/USDHSCBP/bulletins/example",
  "relatedMessageNumbers": ["69999999"],
  "explicitRelationships": [
    { "type": "FOLLOW_UP_TO", "csmsNumber": "69999999" }
  ],
  "matchedFilters": ["messageClass:GUIDANCE", "topicTag:ACE_SYSTEM"],
  "summary": "Official CBP CSMS 70000001: GUIDANCE: Example ACE filing clarification",
  "sourcePublisher": "U.S. Customs and Border Protection",
  "sourceUrl": "https://www.cbp.gov/trade/automated/cargo-systems-messaging-service",
  "detectedAt": "2026-09-25T12:05:00.000Z"
}
```

The Actor does not persist full raw bulletin HTML in Dataset output.

### Failure and state-commit safety

The accepted monitor state advances only after required acquisition/parsing succeeds and Dataset + `OUTPUT` persistence succeeds.

The run fails closed with no accepted-state mutation when, for example:

- official enumeration is empty;
- a required CSMS number or timestamp cannot be parsed;
- one CSMS number maps to conflicting bulletin URLs;
- a newly observed bulletin fails to fetch or parse;
- publisher/host validation fails;
- a source gap cannot be safely bridged.

### Sample mode

`mode: "sample"` is deterministic and self-contained.

It uses three synthetic messages to demonstrate:

- `GUIDANCE`
- `CORRECTION`
- `MANDATORY`

The sample runs the production classification, topic-tag, relationship, filtering, monitor-fingerprint, and pending-queue logic.

Hard guarantees for sample mode:

- CBP HTTP requests: 0
- GovDelivery HTTP requests: 0
- production named KVS open/read/write: 0
- production snapshot updated: false

### Legal reuse and attribution

Source attribution: **U.S. Customs and Border Protection Cargo Systems Messaging Service (CSMS).**

CBP-authored U.S. Government works are generally not protected by U.S. copyright under 17 U.S.C. § 105, subject to statutory exceptions and third-party rights. This Actor limits persisted/output content to source metadata, concise source-grounded summaries, and deterministic classifications needed for the product.

It does not redistribute third-party attachments or material carrying explicit third-party copyright merely because a CSMS bulletin links to it.

CBP/DHS seals and logos are not used. No endorsement, sponsorship, or association with CBP or DHS is implied.

### Privacy

CSMS bulletins are institutional operational notices. V1 does not persist unnecessary individual contact names, direct phone numbers, or personal email addresses.

### Important limitation / no legal advice

This Actor provides operational monitoring, not legal advice. It does not emit claims such as `IMPORT_NOW_LEGAL`, `IMPORT_NOW_ILLEGAL`, `DUTY_INCREASED`, `DUTY_DECREASED`, `FILING_REQUIRED`, `RULING_REVOKED`, or `COMPLIANCE_VIOLATION`.

Always consult the controlling statutes, regulations, Federal Register notices, CBP rulings, HTS material, official filing specifications, and other underlying authorities where applicable.

### Scheduling

CBP does not guarantee a fixed publication cadence. Schedule the Actor at a frequency appropriate to your operations. The Actor is designed for recurring monitoring without making a fixed cadence promise.

# Actor input Schema

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

Live monitors official CSMS sources. Sample runs deterministic synthetic bulletins with zero CBP/GovDelivery requests and zero production-state access.

## `messageClasses` (type: `array`):

Optional exact deterministic class filter.

## `topicTags` (type: `array`):

Optional exact deterministic topic-tag filter.

## `includeKeywords` (type: `array`):

Optional literal keywords matched against normalized title and bulletin body text.

## `excludeKeywords` (type: `array`):

Optional literal keywords that exclude a message when present in normalized title or bulletin body text.

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

Caps Dataset output only. Unemitted matching signals remain pending for later runs.

## Actor input object example

```json
{
  "mode": "sample",
  "maxItems": 30
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `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/us-cbp-cargo-systems-messaging-service-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/us-cbp-cargo-systems-messaging-service-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/us-cbp-cargo-systems-messaging-service-change-signals --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,starshaped_bullsnake/us-cbp-cargo-systems-messaging-service-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/xu421rd4BTJYDRYgQ/builds/YhzJF5N07BoRsRFgq/openapi.json
