# OFAC Recent Actions - Sanctions, Licenses & Guidance (`maydit/ofac-recent-actions-monitor`) Actor

Track OFAC announcements by date, category and title keywords. Optional announcement text, resource links and saved-run changes. No key required; announcement monitoring, not sanctions screening.

- **URL**: https://apify.com/maydit/ofac-recent-actions-monitor.md
- **Developed by:** [Brandt May](https://apify.com/maydit) (community)
- **Categories:** News, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 ofac action observations

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?

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

![Follow official OFAC announcements — illustrative workflow](https://api.apify.com/v2/key-value-stores/YGxD9JRpduom8Q5Zd/records/ofac-recent-actions-monitor-5344facc425b.png?signature=1LwtL0D8j0VUnDm28QGlQ)

### Follow official OFAC announcements

For researchers following sanctions policy updates: collect OFAC Recent Actions announcements by category, date and literal title keywords. Optional details add announcement text and resource links.

[Open this Actor in Console](https://console.apify.com/actors/h5q9mk01CCgkF3hxn/input) · [First run](#try-this-actor) · [Results](#result-preview) · [Cost](#usage-and-pricing) · [Full guide](#full-guide)

### Try this Actor

- **First run:** Use **1. Latest official actions** below: one listing page and up to 10 announcements. Leave announcement details off unless you need the body text or linked resources.
- **Read the results:** Open the default Dataset for announcements and **SUMMARY** for fetched-page coverage. Each row keeps an official source link; dates retain the source's day-level precision.
- **Keep in mind:** This monitors announcements, not sanctions lists or counterparties. It does not screen names or issue compliance decisions. Linked PDFs are not downloaded, and body edits are visible only when details are collected.

**Latest OFAC Sanctions, Licenses and Guidance** — copy this input into the JSON editor in Console.

```json
{
  "maxResults": 10,
  "maxPages": 1
}
```

### Result preview

The dataset view highlights these columns:

- **Announcement** · `title`
- **Published date** · `publishedDate`
- **Category** · `categoryTitle`
- **Comparison** · `comparisonStatus`
- **Official source** · `url`
- **Action ID** · `actionId`

Use the original source links and the field definitions below when interpreting the results. CSV works well for flat columns; JSON preserves nested values.

### Usage and pricing

Base result rate on the FREE tier: **$3 per 1,000 ofac action observations**. The [Pricing tab](https://apify.com/maydit/ofac-recent-actions-monitor/pricing) shows your plan's result rate and any Actor Start charge. Set a small result limit for the first run; the requested limit is not a guarantee of that many results.

***

### Full guide

Turn the U.S. Treasury's official [OFAC Recent Actions](https://ofac.treasury.gov/recent-actions) pages into dated announcement records. Use the output for a sanctions-policy news digest, a general-license watchlist, a regulatory research queue, or alerts when a previously observed announcement changes.

No account, API key, proxy, or browser is required. Run with `{}` to read the newest ten announcements from one listing page. Optional detail fetching adds the announcement's source text and linked resources.

#### What you receive

Each saved record contains:

| Field | Meaning |
| --- | --- |
| `actionId`, `url` | OFAC's announcement-path identifier and canonical official link. Date suffixes remain distinct. |
| `title` | The source announcement title, without an generated summary. |
| `publishedDate` | OFAC's displayed release date, as `YYYY-MM-DD`; no invented time or timezone. |
| `category`, `categoryTitle` | OFAC's category slug and label. |
| `sourceListingUrl`, `observedAt` | Listing-page provenance and this observation's UTC timestamp. |
| `comparisonStatus`, `changedFields`, `previous` | `not_requested`, `baseline`, `new`, `changed`, or `unchanged`; previous saved title/date/category/hash when available. |

With `includeDetails: true`, successful rows additionally contain `contentText`, `contentHash`, `contentLength`, `contentTruncated`, `resourceLinks`, and `resourceLinksTruncated`. Text is plain announcement text. Its SHA-256 hash covers the complete fetched text even when `maxTextChars` truncates the displayed text. Up to200 resource links are retained; linked PDFs, licenses and other pages are **not downloaded or interpreted**.

The source may publish listed-party names and other public identifying details inside announcement text. Details are opt-in. This Actor does not create person profiles, perform name matching, or make sanctions/compliance decisions.

#### Inputs and coverage

- `category`: `all` (default), `sanctions-list-updates`, `general-licenses`, `regulations-and-guidance`, `enforcement-actions`, or `miscellaneous`.
- `titleKeywords`: optional literal, case-insensitive title substrings; any match qualifies. These are not semantic country/program filters.
- `startDate` / `endDate`: optional inclusive official dates, `YYYY-MM-DD`.
- `maxResults`: maximum **saved** records, default10, maximum500.
- `maxPages`: listing-page window, default1, maximum50. OFAC currently lists ten announcements per page.
- `includeDetails`: defaultfalse. Adds a separate GET request per selected announcement.
- `maxTextChars`: default10000; applies only to optional detail text.
- `comparePrevious`, `onlyChanges`, `snapshotName`: opt-in monitoring, described below.
- `maxRunSeconds`: own deadline, default240 seconds, minimum30, maximum3600. A platform deadline also reserves25 seconds for shutdown.

Date and keyword filters apply **within the pages actually scanned**. Increase `maxPages` to cover older announcements. A keyword with no match in that window can correctly return zero records. Categories reflect OFAC's classification: a sanctions-list announcement can also discuss a general license, so select `all` if that matters to your workflow.

`SUMMARY` gives actual saved rows, scanned records/pages, source-reported total, `hasMore`, selected caps, failures, time/spending stops and history persistence. Reaching a user-selected cap is ordinary bounded coverage; it does not mean the whole archive was scanned. No result establishes that a party is sanctioned or that a proposed transaction is allowed.

#### Saved comparisons

Set `comparePrevious: true` to retain observations in a named key-value store. The first saved observations are labeled `baseline`. Later records report changes to their title, official date, category, or complete announcement-text hash when details are enabled. Without details, edits confined to the announcement body cannot be detected. Resource-link-only changes are not separately compared.

`onlyChanges: true` also enables comparison. A first run emits the baseline; a matching repeat can return zero dataset rows with an `ok` summary. History contains confirmed saved observations only. Rejected spending-limit rows do not advance it; successful earlier records remain saved. Unchanged skipped records retain their earlier saved observation.

The comparison scope includes category, normalized keywords, date filters and `includeDetails`. Result/page limits do not change the scope. Use a different `snapshotName` for independent workflows. **Run the same snapshot name sequentially.** A reread prevents a known overlapping write from replacing changed history, but the storage API does not provide a transactional lock. Source outages, window limits and vanished listing entries never produce removal/deletion claims. Snapshots support up to50,000 observed IDs; start a new namespace if that limit is reached.

#### Three ready-to-run examples

##### 1. Latest official actions

Use the [copyable first-run input](#try-this-actor) above.

##### 2. Latest general-license announcement with text and resources

```json
{
  "category": "general-licenses",
  "maxResults": 1,
  "maxPages": 1,
  "includeDetails": true
}
```

##### 3. Regulatory guidance with a saved comparison

```json
{
  "category": "regulations-and-guidance",
  "maxResults": 5,
  "maxPages": 1,
  "comparePrevious": true,
  "snapshotName": "example-guidance-watch-v1"
}
```

All observations are returned in example3. Add `"onlyChanges": true` on later scheduled runs when you want unchanged records omitted.

#### Pricing and failure behavior

Proposed base price: **$0.003 per saved announcement** ($3 per1,000), plus the Actor Start event shown in the live pricing panel (base $0.00005). Detail text is part of that same announcement record. Review the live pricing panel for the current plan and tier discounts. Unchanged rows skipped by `onlyChanges`, robots denials, failed fetches and parse errors are not saved dataset items. A zero-result repeat can still incur the start event and any platform charges shown by Apify.

Source access respects robots rules, validates public DNS destinations, rejects redirects for the fixed OFAC endpoints, bounds response sizes and retries, and honors `Retry-After` within the remaining budget. An HTTP200 response must contain the expected official page shape. Individual failed details are reported in `SUMMARY.failedSources`; no fabricated error rows are charged. If all usable source observations fail, the run fails with a diagnostic summary.

#### Limits and source changes

- This is an official-announcement monitor. It does not download the SDN list, screen counterparties, calculate ownership/control, or determine legal obligations.
- OFAC retired its recent-actions RSS feed in2025. This Actor reads the current official HTML pages and validates their structure.
- An announcement title or date can change, and source availability can vary. Saved comparison means "changed since this Actor's last saved observation," not the effective date of a legal amendment.
- No browser rendering, proxy rotation or access-control bypass is used. If OFAC blocks automated access or changes its page structure, the Actor stops or reports incomplete coverage.
- Bounded sample QA demonstrates the documented examples and targeted failure cases, not every historical page or legal accuracy of source announcements.

Primary references: [Recent Actions](https://ofac.treasury.gov/recent-actions), [OFAC technical notices](https://ofac.treasury.gov/sdn-list-data-formats-data-schemas/ofac-technical-actions-in-reverse-chronological-order), [RSS retirement notice](https://ofac.treasury.gov/recent-actions/20250206).

#### Local development

Node20.18.1+; locked `apify3.7.2`, `cheerio1.1.2`, and `basic-ftp6.2.2` override. Run `npm ci`, `npm test`, then `npm start`. Use an isolated `CRAWLEE_STORAGE_DIR` for local testing. Production source data and cloud billing are separate from local fixture tests.

### Help with your run

Open the **Issues** tab on this Actor with the run URL, the input field that caused trouble and what you expected to receive. Remove API keys and private information before posting.

[Explore more Mayd-It Actors](https://apify.com/maydit)

### Understand your run

Open **Run report** in the run’s Output tab for saved-record counts, reported source issues and limits, and suggested next steps. Use **CSV export** to take the saved results into a spreadsheet. The existing JSON results and detailed machine-readable summary remain available.

The report reflects this run’s recorded coverage. A successful run or a saved result does not establish that every possible source record was collected.

# Actor input Schema

## `category` (type: `string`):

OFAC classification. Sanctions-related content can also occur in general licenses or guidance; all reads every category.

## `titleKeywords` (type: `array`):

Optional case-insensitive literal substrings matched only against the announcement title. Maximum20 phrases,100 characters each; no inferred country or program classifications.

## `startDate` (type: `string`):

Optional inclusive official publication date in YYYY-MM-DD. Filtering happens within the scanned page window; increase maxPages for older records.

## `endDate` (type: `string`):

Optional inclusive official publication date in YYYY-MM-DD, not earlier than startDate.

## `maxResults` (type: `integer`):

Stop after this many confirmed saved records. Unchanged rows skipped by onlyChanges do not consume this limit.

## `maxPages` (type: `integer`):

OFAC normally lists10 announcements per page. This selected window is explicit in SUMMARY; reaching it is not a source outage. New announcements outside it are not observed.

## `includeDetails` (type: `boolean`):

Fetch each selected announcement page for its text, a full-text hash, and up to200 linked resources. Slower; linked PDFs/pages are referenced but not downloaded. Source text may contain public listed-party details.

## `maxTextChars` (type: `integer`):

Used when includeDetails is true. Text is truncated with an explicit flag, while contentHash covers the complete fetched announcement text.

## `comparePrevious` (type: `boolean`):

Opt in to persistent named-store history. First saved observations are baseline; later rows show new, changed or unchanged. History advances only for confirmed saved rows. Same snapshotName must run sequentially.

## `onlyChanges` (type: `boolean`):

Also enables comparison. A first baseline emits rows; later unchanged observations are skipped. A bounded window never establishes removals. Leave false for a nonempty recurring sample.

## `snapshotName` (type: `string`):

1–40 letters, digits, hyphens or underscores. Comparison scope also includes category, keywords, dates and includeDetails. Use a dedicated namespace and run it sequentially.

## `maxRunSeconds` (type: `integer`):

Own runtime budget; the Actor also reserves25 seconds before its platform deadline. Source failures and incomplete runs are recorded in SUMMARY.

## Actor input object example

```json
{
  "category": "all",
  "maxResults": 10,
  "maxPages": 1,
  "includeDetails": false,
  "maxTextChars": 10000,
  "comparePrevious": false,
  "onlyChanges": false,
  "snapshotName": "default",
  "maxRunSeconds": 240
}
```

# Actor output Schema

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

Confirmed announcement observations; failures are never paid error rows.

## `runReport` (type: `string`):

Readable summary of saved records, reported source coverage, limits and next steps. Available when this run saves its SUMMARY.

## `csvExport` (type: `string`):

Download saved dataset records as a CSV file for spreadsheets and other tools.

## `summary` (type: `string`):

Actual saved count, scanned pages, selected caps, failed sources, budget stops and history persistence.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("maydit/ofac-recent-actions-monitor").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("maydit/ofac-recent-actions-monitor").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 '{}' |
apify call maydit/ofac-recent-actions-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maydit/ofac-recent-actions-monitor"
        }
    }
}
```

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/h5q9mk01CCgkF3hxn/builds/1vP9F6weBnlsuigjl/openapi.json
