# Federal Register: Comment Deadlines & Effective Dates (`felixgoldwin/federal-register-deadline-monitor`) Actor

Track Federal Register comment deadlines and effective dates from the public API. Compare saved snapshots for metadata changes and approaching deadlines. Export an iCalendar file with source document and official PDF links for review.

- **URL**: https://apify.com/felixgoldwin/federal-register-deadline-monitor.md
- **Developed by:** [Felix GoldWin](https://apify.com/felixgoldwin) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 delivered documents

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

## Federal Register Deadline and Change Monitor

Turn a focused Federal Register search into a reproducible regulatory watchlist. Export structured effective dates and comment deadlines, exact before/after metadata changes, deadline threshold crossings, official PDF links, and an iCalendar file. Intended for regulatory researchers, policy analysts, trade associations, and teams that need an auditable input to their own review process.

This Actor reads the public FederalRegister.gov API. No API key, login, proxy, or browser is needed. It does not collect public comments, contact lists, or account data. It never submits a comment or takes a regulatory action.

### What makes the output useful

- Keep the original `datesText` next to the API's structured dates. Qualifications and additional deadlines remain visible for human review.
- Compare an explicit previous snapshot and receive `{field, before, after}` changes for titles, dates, actions, agencies, docket IDs, CFR references, correction links, and other stable metadata.
- Keep calendar movement separate from source changes: an unchanged deadline entering the next seven days appears in `thresholdCrossings`.
- Preserve document number, Federal Register citation, source API URL, source document URL, and official govinfo.gov PDF link.
- See whether the query was fully scanned. Bounded or incomplete scans never imply withdrawal or deletion.

### Start locally

Use Node.js 24 or newer, then run `npm ci`, `npm test`, and `npm start` from this directory. The input file is `storage/key_value_stores/default/INPUT.json`; copy `examples/input.json` there before starting. Local runs read public APIs and write local Apify SDK storage. They require network access but do not need an Apify account or token.

The included fixture tests are offline. They use fictional documents clearly marked synthetic; those fixtures must not be cited as real regulations. The sample output is also labeled as synthetic in its source fixture.

### Example input

```json
{
  "agencySlugs": ["environmental-protection-agency"],
  "documentTypes": ["PRORULE", "RULE"],
  "publicationLookbackDays": 90,
  "maxItems": 100,
  "maxRequests": 20,
  "deadlineWindowDays": 30
}
```

Find agency URL slugs in the [Federal Register agency directory](https://www.federalregister.gov/agencies). A syntactically valid misspelling can yield zero results; it is not automatically corrected. Search term semantics are those of the source API.

| Input | Default | Meaning |
| --- | --- | --- |
| `searchTerm` | empty | Full-text query, up to 200 characters. |
| `agencySlugs` | `[]` | Up to 20 agency slugs. Empty means all agencies. |
| `documentTypes` | `PRORULE`, `RULE` | One or more of `RULE`, `PRORULE`, `NOTICE`, `PRESDOCU`. |
| `publicationLookbackDays` | 90 | Inclusive lookback of 1–3650 days ending at `publishedTo` or `asOfDate`. |
| `publishedFrom` | omitted | Inclusive `YYYY-MM-DD`; overrides the lookback. Earliest allowed date: 1994-01-01. |
| `publishedTo` | `asOfDate` | Inclusive `YYYY-MM-DD`, no later than `asOfDate`. |
| `significantOnly` | false | Source API significance filter; unknown values in output remain `null`. |
| `maxItems` | 100 | Maximum delivered documents, 1–5000. A separate conservative provider ceiling limits the scan to 2000 source rows. |
| `maxRequests` | 20 | Total HTTP attempt budget, 1–200, including retries and redirects. |
| `requestIntervalMs` | 1000 | Sequential request spacing, 500–60000 ms. |
| `requestTimeoutSecs` | 30 | Timeout per request, 5–60 seconds. |
| `maxRetries` | 2 | Retries after an initial request, 0–3, for transient failures only. |
| `deadlineWindowDays` | 90 | Deadline classification window, 1–730 days; does not filter documents from output. |
| `asOfDate` | current UTC day | Comparison date in `YYYY-MM-DD`; not a historical-data replay. |
| `previousSnapshot` | omitted | The exact prior `SNAPSHOT` JSON object, at most 2 MiB, from this Actor with the same source filters. |

Supply narrow agency, term, or publication filters for repeatable monitoring. The source searches publication dates, not a complete universe of all future deadlines. A rule published before the selected window is not included even if its effective date is still in the future. Every matched document can be returned, including those with no structured deadline.

### Output and comparison workflow

Each dataset item is one document. In addition to normalized source fields, it has:

| Field | Meaning |
| --- | --- |
| `id`, `documentNumber` | The source document number; corrections can have prefixes such as `C1-`. |
| `effectiveOn`, `commentsCloseOn` | Structured API dates, or `null`. No dates are inferred from prose. |
| `deadlines` | `{kind, date}` entries for the available structured dates. |
| `datesText` | The original date text, including qualifications and potentially additional dates. |
| `deadlineStatus` | Per-date UTC calendar-day countdown and bucket, such as `past`, `today`, `within-7-days`, or `beyond-window`. |
| `changeType` | `baseline`, `added`, `changed`, or `unchanged`. `added` means first seen in the supplied comparison, not newly enacted. |
| `changes` | Exact stable-field differences as `{field, before, after}`. Computed countdowns are not source edits. |
| `thresholdCrossings` | An unchanged date's classification changed since the prior `asOfDate`. |
| `correctionOf`, `corrections` | Correction links explicitly supplied by the API. |
| `sourceUrl`, `sourceApiUrl`, `officialPdfUrl` | Provenance links. |

The default key-value store contains `OUTPUT` (run summary, limits, request counts, diagnostics), `SNAPSHOT` (bounded baseline), and `DEADLINES.ics` (calendar). Dataset export is available through Apify in JSON, CSV, and other supported formats. Nested fields are most useful in JSON.

For a first run, omit `previousSnapshot`. To compare, download the prior `SNAPSHOT` record and place that JSON object in the next input's `previousSnapshot`, retaining the same source filters. A schedule by itself does not carry a previous run's default storage forward; use your integration to feed the snapshot explicitly. This prevents different customers or queries from accidentally sharing mutable state. Snapshot input and generated output are limited to 2 MiB; narrow the query if that limit is reached.

Every delivered document is a billable result when pay-per-event pricing is enabled, including `unchanged` documents. A changes-only consumer should filter downstream. The `OUTPUT` summary, snapshot, and calendar do not generate additional custom charges.

### Completeness and legal meaning

The API is a government-maintained informational service. FederalRegister.gov states that its XML rendition is **not the official legal edition**. Verify any legal obligation, filing cutoff, or effective-date qualification against the linked official PDF and subsequent actions. This Actor does not make compliance determinations or provide legal advice. See the source's [legal-status notice](https://www.federalregister.gov/developers/documentation/api/v1).

The Actor monitors exact metadata for each document number. Amendments, extensions, withdrawals, and corrections often receive new numbers. They will be discovered only if they match the selected query and publication window. This is not a complete amendment graph or a consolidated current-law database. A `null` date means no valid structured date was supplied, not that no deadline exists. Comment-close dates do not provide a filing time or timezone; calendar entries use date-only values.

The provider's [REST API guidance](https://www.federalregister.gov/reader-aids/developer-resources/rest-api) documents a 2000-result pagination ceiling. This Actor enforces that conservative scan limit, also follows the returned cursor links, and reports truncation. It does not silently claim complete coverage when `maxItems`, request budget, provider pagination, or the billing budget stops the scan. Narrow the window or split separate explicit date windows for larger research jobs. `sourceScanComplete` describes this query, not completeness of the legal record. `notObservedIds` never means deleted, withdrawn, or no longer applicable.

Access is sequential, host-restricted, and response-size bounded. Transient responses receive bounded retries with backoff and `Retry-After` handling; authentication failures and access restrictions fail clearly. HTML search, CAPTCHA solving, credential use, and restriction bypass are outside this Actor's behavior. Robots and terms should be reviewed again before publication; the source currently disallows HTML search routes and exposes its API for public use. Official NARA/OFR logos and seals must not be used.

### Upload and price

See [PUBLISHING.md](PUBLISHING.md) for the upload and monetization checklist. Upload this standalone source folder or its source ZIP to a new Actor in Apify Console. Keep `.actor/`, `src/`, `package.json`, `package-lock.json`, and `Dockerfile` together. Build a private Actor first, run the sample input with a small `maxItems`, inspect the dataset and `OUTPUT`, and then review the Store listing before publishing. No publication or paid Apify run was performed in preparing this package.

Approved launch pricing is **$0.005 per automatic start billing unit plus $0.003 per delivered document** ($3 per 1,000 documents, plus the start fee). Configure `apify-actor-start` and `apify-default-dataset-item` in Apify Console. Apify charges startup automatically; the code only uses ordinary `Actor.pushData()` for results. Never manually charge startup or add duplicate custom start/result events.

Up to and including 1 GB RAM, startup is one unit; above that its count increases with each additional GB (4 GB means four units). The supplied default is 256 MB and maximum is 512 MB, so startup is $0.005 within this configuration. A 256 MB run delivering 100 documents has $0.305 in event charges. A started run with no results or a later failure can still incur $0.005. Other applicable costs follow Apify's terms.

Every delivered document, including unchanged documents, counts once. Errors, summaries, snapshots and calendars create no extra dataset-item charge. The SDK's remaining budget includes charges already incurred for automatic startup; the runtime checks it before collection and each delivery. With less than one result's allowance, no source request occurs. `OUTPUT.billing` describes the item-cap check, not a complete bill. See [examples/pricing.json](examples/pricing.json). These approved prices do not guarantee revenue or profit.

Use an original icon and clear independent branding. Suitable listing copy: “Track Federal Register structured deadlines, exact metadata changes and calendar transitions with explicit snapshots, complete-query diagnostics and official document provenance.” Avoid promising complete compliance coverage, real-time legal validity, or affiliation with the government.

### Verification

Source unit tests cover strict input validation, metadata normalization, no prose-based date inference, nullable significance, correction documents, provenance checks, stable arrays, date/type filter checks, pagination, deduplication, repeated-page defense, request limits, and the 2000-result ceiling. Common runtime tests cover HTTP retry and billing-budget behavior, snapshots, deltas, and calendar generation.

A small **live source collector check on 2026-10-11** used the implemented collector and shared HTTP client against `https://www.federalregister.gov/api/v1/documents.json`: 1 request, 0 retries, 7240 response bytes, three normalized documents (`C1-2026-20019`, `2026-20792`, `2026-20790`) in the inclusive 2026-10-01–2026-10-11 publication window. It correctly reported `complete: false` at `maxItems: 3` from a reported count of 135. This establishes sampled live API compatibility, not a full-corpus audit or an Apify cloud execution. Fixture tests and live checks are separate evidence.

### Sources

- [Official interactive API documentation](https://www.federalregister.gov/developers/documentation/api/v1)
- [Official REST API guide, pagination and reuse restriction](https://www.federalregister.gov/reader-aids/developer-resources/rest-api)
- [Robots.txt](https://www.federalregister.gov/robots.txt)
- [Privacy and authorized public retrieval](https://www.federalregister.gov/reader-aids/government-policy-and-ofr-procedures/privacy)

See `NOTICE` for attribution and source limitations.

# Actor input Schema

## `searchTerm` (type: `string`):

Optional Federal Register full-text query (up to 200 characters). Empty searches all documents within the other filters.

## `agencySlugs` (type: `array`):

Optional agency URL slugs, e.g. environmental-protection-agency. Maximum 20. See federalregister.gov/agencies. A misspelled but well-formed slug can return no results.

## `documentTypes` (type: `array`):

One or more of RULE, PRORULE, NOTICE, PRESDOCU. Defaults to final and proposed rules. Notices may also carry comment dates.

## `publicationLookbackDays` (type: `integer`):

Inclusive publication window ending at publishedTo or asOfDate. Ignored when publishedFrom is supplied. Older documents with future deadlines are outside this window.

## `publishedFrom` (type: `string`):

Optional inclusive YYYY-MM-DD date, on or after 1994-01-01. Overrides lookback. Leave empty to use the rolling window.

## `publishedTo` (type: `string`):

Optional inclusive YYYY-MM-DD date; defaults to asOfDate. Must not be later than asOfDate.

## `significantOnly` (type: `boolean`):

Apply the API significant-document filter. Unknown significance remains null in output, rather than being treated as false.

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

Hard cap on unique delivered and billable records. Runtime also respects the Apify spending cap.

## `maxRequests` (type: `integer`):

Total source HTTP attempts, including retries and redirects.

## `requestIntervalMs` (type: `integer`):

Sequential requests only; minimum 500 ms between attempts.

## `requestTimeoutSecs` (type: `integer`):

Timeout for each response including its body.

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

Retries only transient network failures, 429, 500, 502, 503 and 504; all count toward maxRequests.

## `deadlineWindowDays` (type: `integer`):

Classify dated deadlines into UTC calendar-day buckets. This does not filter records.

## `asOfDate` (type: `string`):

Optional YYYY-MM-DD reference for date arithmetic and the Federal Register publication window; defaults to UTC today. This does not retrieve historical source state.

## `previousSnapshot` (type: `object`):

Optional JSON object copied from this Actor’s SNAPSHOT output. Max 2 MiB and 5000 records, same filters. Never paste secrets. Each run uses only the snapshot explicitly supplied.

## Actor input object example

```json
{
  "searchTerm": "",
  "agencySlugs": [],
  "documentTypes": [
    "PRORULE",
    "RULE"
  ],
  "publicationLookbackDays": 90,
  "significantOnly": false,
  "maxItems": 100,
  "maxRequests": 20,
  "requestIntervalMs": 1000,
  "requestTimeoutSecs": 30,
  "maxRetries": 2,
  "deadlineWindowDays": 90
}
```

# Actor output Schema

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

No description

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

No description

## `snapshot` (type: `string`):

No description

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

// Run the Actor and wait for it to finish
const run = await client.actor("felixgoldwin/federal-register-deadline-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("felixgoldwin/federal-register-deadline-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 felixgoldwin/federal-register-deadline-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,felixgoldwin/federal-register-deadline-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/AaiReoH0bcIQnYbnN/builds/JaorRRumOjVwMXGaO/openapi.json
