# Federal Register Scraper: Rules, Notices & Executive Orders (`arman-bd/federal-register-scraper`) Actor

Track every document in the Federal Register: proposed rules, final rules, notices and presidential documents, with agency, docket, effective dates and comment deadlines.

- **URL**: https://apify.com/arman-bd/federal-register-scraper.md
- **Developed by:** [Arman Hossain](https://apify.com/arman-bd) (community)
- **Categories:** Business, Developer tools, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.56 / 1,000 document scrapeds

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

## Federal Register Scraper: Rules, Notices & Executive Orders

![Federal Register Scraper: Proposed rules, final rules, notices and executive orders, with agency, docket IDs, RIN and comment deadlines attached](https://api.apify.com/v2/key-value-stores/ZQOcNAOHrIgTacAmy/records/federal-register-scraper.jpg)

**Federal Register Scraper** tracks every document the US government publishes in the Federal Register, proposed rules, final rules, agency notices and presidential documents, with the agency, docket IDs, RIN, effective date and comment deadline attached to each one.

The Federal Register is the daily journal of the US government, and the day a rule appears in it is the day the clock starts on your comment window. This Actor reads the official API directly: **no proxy setup, no browser, no credentials to manage.**

**Agent skill: [SKILL.md](https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/federal-register-scraper.md)**

```
https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/federal-register-scraper.md
```

### What you get

| Output field | Meaning |
|---|---|
| `documentNumber` | The Federal Register document number, e.g. `2026-16083`, the stable identifier |
| `title` | Full document title |
| `type` | `Rule`, `Proposed Rule`, `Notice` or `Presidential Document` |
| `abstract` | The agency's own summary, or `null` for document types that have none |
| `agencies`, `agencySlugs` | Issuing agency names, and the slugs you feed back into the `agencies` input |
| `publicationDate` | Date it appeared in the Federal Register |
| `effectiveOn` | Date the rule takes effect, when the document sets one |
| `commentsCloseOn` | Comment deadline, the field that matters most on proposed rules |
| `docketIds` | Agency docket identifiers, e.g. `EPA-R09-OAR-2026-3797` |
| `regulationIdNumbers` | RINs linking the document to the Unified Agenda |
| `htmlUrl`, `pdfUrl` | Canonical page on federalregister.gov and the govinfo.gov PDF |
| `significant` | `true` when flagged significant under EO 12866 |
| `scrapedAt` | Run timestamp |

A `RUN_SUMMARY` record in the key-value store holds per-query counts, duplicates skipped, the filters used, and any query that failed.

### Common use cases

- **Alert compliance teams to new rules in your sector.** A daily sweep of one agency's rulemaking.

```json
{
"agencies": ["environmental-protection-agency"],
"documentTypes": ["RULE", "PRORULE"],
"fromDate": "2026-08-01"
}
```

- **Track comment deadlines for lobbying.** Proposed rules only, so every record carries a `commentsCloseOn` to diary.

```json
{
"searchTerms": ["pfas", "per- and polyfluoroalkyl"],
"documentTypes": ["PRORULE"],
"fromDate": "2026-01-01"
}
```

- **Build a RegTech monitoring product.** The economically significant subset across every agency.

```json
{
"documentTypes": ["RULE", "PRORULE"],
"significantOnly": true,
"fromDate": "2026-01-01",
"maxResults": 5000
}
```

### Quick start

Everything the EPA published this month:

```json
{
 "agencies": ["environmental-protection-agency"],
 "fromDate": "2026-08-01"
}
```

Two topics across all agencies, de-duplicated, capped:

```json
{
 "searchTerms": ["carbon capture", "artificial intelligence"],
 "documentTypes": ["RULE", "PRORULE", "NOTICE"],
 "fromDate": "2026-01-01",
 "maxResults": 500
}
```

Executive orders and other presidential documents for a quarter:

```json
{
 "documentTypes": ["PRESDOCU"],
 "fromDate": "2026-04-01",
 "toDate": "2026-06-30"
}
```

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `searchTerms` | array | `[]` | Full-text terms over title, abstract and body. Each runs as its own query; results are de-duplicated by `documentNumber`. Empty = no text search. |
| `agencies` | array | `[]` | Agency slugs. Names and `federalregister.gov/agencies/.` URLs are slugified automatically. Multiple agencies are OR-ed. |
| `documentTypes` | array | `[]` | Any of `RULE`, `PRORULE`, `NOTICE`, `PRESDOCU`. Empty = all four. |
| `fromDate` | string | `""` | Publication date lower bound, `YYYY-MM-DD`. |
| `toDate` | string | `""` | Publication date upper bound, `YYYY-MM-DD`. |
| `significantOnly` | boolean | `false` | Keep only documents significant under EO 12866. |
| `maxResults` | integer | `1000` | Total documents for the whole run, across every search term. `0` = no limit. Must be a whole number of `0` or more: anything else (`-5`, `0.5`, `"abc"`) is rejected before the run starts rather than read as "no limit". |

**Which combinations make sense.** Every filter is applied by the API before anything is downloaded, and they combine with AND, except multiple values inside one filter, which are OR-ed. So `agencies: ["a", "b"]` with `documentTypes: ["RULE"]` means *final rules from either agency*. `searchTerms` is the exception: each term is a separate query and the results are unioned, which is what you want for synonyms.

The one combination to be deliberate about is a broad query with no date bound. The API will not page past roughly 10,000 documents for a single query, so if you are backfilling history, walk it in date windows, a month or a quarter at a time, rather than asking for everything at once.

### Output example

A real record, an EPA proposed rule:

```json
{
 "documentNumber": "2026-16083",
 "title": "Partial Approval and Partial Disapproval of Air Quality State Implementation Plans; Arizona; Prevention of Significant Deterioration Infrastructure Requirements for the 2012 Fine Particulate Matter National Ambient Air Quality Standard",
 "type": "Proposed Rule",
 "abstract": "The Environmental Protection Agency (EPA) is proposing to partially approve and partially disapprove a revision to the Arizona State implementation plan (SIP) …",
 "agencies": ["Environmental Protection Agency"],
 "agencySlugs": ["environmental-protection-agency"],
 "publicationDate": "2026-08-06",
 "effectiveOn": "2026-09-08",
 "commentsCloseOn": "2024-06-13",
 "docketIds": ["EPA-R09-OAR-2026-3797", "FRL-13389-01-R9"],
 "regulationIdNumbers": [],
 "htmlUrl": "https://www.federalregister.gov/documents/2026/08/06/2026-16083/partial-approval-and-partial-disapproval-of-air-quality-state-implementation-plans-arizona",
 "pdfUrl": "https://www.govinfo.gov/content/pkg/FR-2026-08-06/pdf/2026-16083.pdf",
 "significant": null,
 "scrapedAt": "2026-08-06T11:42:18.559Z"
}
```

`RUN_SUMMARY` looks like this:

```json
{
 "queriesRequested": 2,
 "queriesFailed": 0,
 "queriesSkippedAtCap": [],
 "failures": [],
 "documentsSaved": 119,
 "duplicatesSkipped": 4,
 "documentsWithoutNumber": 0,
 "capReached": false,
 "perQuery": [
 { "term": "pfas", "reported": 119, "fetched": 119, "saved": 115, "truncated": null, "error": null }
 ],
 "filters": {
 "searchTerms": ["pfas"],
 "agencies": ["environmental-protection-agency"],
 "documentTypes": ["RULE", "PRORULE"],
 "fromDate": "2026-01-01",
 "toDate": "",
 "significantOnly": false,
 "maxResults": 1000
 },
 "finishedAt": "2026-08-06T11:42:18.559Z"
}
```

`truncated` is non-null whenever a query stopped short of its own `reported` count, either because `maxResults` was hit or because the query exceeded what the API will page through. `error` is non-null when a query stopped because it failed, and the rows it had already delivered are still counted in `saved`. `queriesSkippedAtCap` lists the terms that were never run because the run-wide cap was already spent, so a query that never ran is never mistaken for one that matched nothing.

### Finding an agency slug

Open [federalregister.gov/agencies](https://www.federalregister.gov/agencies) and click any agency. The slug is the last path segment:

| URL you see | Slug |
|---|---|
| `federalregister.gov/agencies/environmental-protection-agency` | `environmental-protection-agency` |
| `federalregister.gov/agencies/securities-and-exchange-commission` | `securities-and-exchange-commission` |
| `federalregister.gov/agencies/food-and-drug-administration` | `food-and-drug-administration` |

You can paste the whole URL, or the agency's display name, the Actor slugifies it. An unrecognised slug is rejected by the API with a clear error rather than being silently ignored, and every returned document carries its own `agencySlugs`, so one exploratory run tells you the exact strings to use.

### API example

```bash
curl -X POST "https://api.apify.com/v2/acts/arman-bd~federal-register-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
 "agencies": ["environmental-protection-agency"],
 "documentTypes": ["RULE", "PRORULE"],
 "fromDate": "2026-01-01",
 "maxResults": 200
 }'
```

### JavaScript example

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('arman-bd/federal-register-scraper').call({
 searchTerms: ['pfas'],
 documentTypes: ['PRORULE'],
 fromDate: '2026-01-01',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const doc of items) {
 if (doc.commentsCloseOn) console.log(`${doc.commentsCloseOn}, ${doc.title} (${doc.agencies.join(', ')})`);
}
```

### Limits and behaviour

- **`maxResults` bounds the whole run, not each term.** Five terms with `maxResults: 100` return at most 100 documents in total, and you are charged for at most 100. Terms that never ran because the budget was spent are listed in `RUN_SUMMARY.queriesSkippedAtCap` rather than reported as having matched nothing. Put the most important term first.
- **An unusable `maxResults` stops the run instead of removing the cap.** `0` is the only value that means "no limit". A negative, fractional or non-numeric cap is an error raised before the first request, because reading it as "everything" is how a run intended to return five documents returns hundreds of billable ones.
- **A single query tops out near 10,000 documents.** The API stops issuing further pages past that point, and asking for a page beyond `total_pages` silently re-serves page one rather than erroring. The Actor stops at the reported page count instead of walking into that trap, and records the shortfall in `RUN_SUMMARY.perQuery[].truncated`. Use date windows to go deeper.
- **Search terms are separate queries, unioned.** Each term is fetched independently, so a term that errors is recorded in `RUN_SUMMARY.failures` while the others continue. Documents matching more than one term are written once; the count is in `duplicatesSkipped`.
- **A bad filter value is reported, not swallowed.** An unknown agency slug returns HTTP 400 with the offending field named, which is passed straight through to the failure record.
- **Zero matches is not an error.** A query that matches nothing returns a count of zero and no results block at all; the Actor treats that as an empty result, not a malformed response.
- **Abstracts keep the source's inline markup.** The Federal Register embeds tags such as `<INF>2.5</INF>` for subscripts in agency abstracts. These are left exactly as published rather than stripped, because removing them naively would destroy chemical and standards notation.
- **Transient errors are retried.** 429 and 5xx get three attempts with linear backoff. 400 and 404 are not retried, because they will never succeed.
- **Comment deadlines can be in the past.** Some documents reuse a deadline from an earlier related notice. The Actor reports `commentsCloseOn` exactly as the API gives it and does not second-guess the agency.

### FAQ

**Do I need a proxy?** No. Proxy configuration is not required to run this Actor.

**Do I need an account or API key?** No. You supply no credentials.

**What happens if one query fails?** It is logged, added to `RUN_SUMMARY.failures`, and the run continues with the remaining queries. The Actor only errors out if *every* query fails.

**How do I backfill several years?** Run it once per quarter with `fromDate` and `toDate`, or schedule a rolling window. Any single query is capped near 10,000 documents by the API.

**Can I get the full document text?** Not in this Actor's output, it returns the agency's abstract plus `htmlUrl` and `pdfUrl`. The full text lives behind those links and is often hundreds of pages.

**What is the difference between RULE and PRORULE?** `PRORULE` is a proposed rule open for comment; `RULE` is the final rule that follows. Track `PRORULE` for `commentsCloseOn`, `RULE` for `effectiveOn`.

**Why is `significant` sometimes null?** The flag comes from the Unified Agenda linkage under EO 12866 and is only populated where that linkage exists. `null` means unknown, not "not significant", use `significantOnly` if you want just the confirmed ones.

**Can I schedule it?** Yes, the Federal Register publishes every business day. A daily run with `fromDate` set to yesterday keeps a feed current.

**Can I integrate it with something else?** Yes, Apify API, client libraries, webhooks, scheduled runs, dataset exports (JSON/CSV/Excel) or MCP. Output is structured JSON.

# Actor input Schema

## `searchTerms` (type: `array`):

Full-text terms searched across title, abstract and document body. Each term runs as its own query and results are de-duplicated, so 'pfas' and 'per- and polyfluoroalkyl' together give you the union, not double the cost. Leave empty to skip full-text search entirely.

## `agencies` (type: `array`):

Agency slugs as they appear in federalregister.gov/agencies URLs. 'environmental-protection-agency', 'securities-and-exchange-commission'. Agency names and full URLs are accepted and slugified automatically. Multiple agencies are OR-ed. Leave empty for all agencies.

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

Restrict to certain kinds of document. RULE is a final rule, PRORULE a proposed rule, NOTICE an agency notice, PRESDOCU a presidential document such as an executive order. Leave empty for all four.

## `fromDate` (type: `string`):

Earliest publication date, as YYYY-MM-DD. The Federal Register API caps any single query at roughly 10,000 documents, so a date window is the reliable way to work through a large back catalogue.

## `toDate` (type: `string`):

Latest publication date, as YYYY-MM-DD. Leave empty to run through to today's issue.

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

Keep only documents flagged significant under Executive Order 12866. the economically consequential rulemakings that get OMB review. Useful for cutting routine notices out of a compliance feed.

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

Stop after this many documents for the whole run, counting every search term together. This is the most you can be charged for in one run. Set 0 for no limit, bounded only by what can be paged through. Must be a whole number of 0 or more, anything else stops the run rather than being treated as no limit.

## Actor input object example

```json
{
  "searchTerms": [
    "carbon capture",
    "artificial intelligence"
  ],
  "agencies": [
    "food-and-drug-administration",
    "securities-and-exchange-commission"
  ],
  "documentTypes": [
    "RULE",
    "PRORULE"
  ],
  "fromDate": "2025-06-01",
  "toDate": "2026-06-30",
  "significantOnly": false,
  "maxResults": 1000
}
```

# Actor output Schema

## `items` (type: `string`):

Every record the run produced.

## `runsummary` (type: `string`):

The RUN\_SUMMARY record from the run's key-value store.

# 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 = {
    "searchTerms": [
        "pfas"
    ],
    "agencies": [
        "environmental-protection-agency"
    ],
    "fromDate": "2026-01-01"
};

// Run the Actor and wait for it to finish
const run = await client.actor("arman-bd/federal-register-scraper").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 = {
    "searchTerms": ["pfas"],
    "agencies": ["environmental-protection-agency"],
    "fromDate": "2026-01-01",
}

# Run the Actor and wait for it to finish
run = client.actor("arman-bd/federal-register-scraper").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 '{
  "searchTerms": [
    "pfas"
  ],
  "agencies": [
    "environmental-protection-agency"
  ],
  "fromDate": "2026-01-01"
}' |
apify call arman-bd/federal-register-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,arman-bd/federal-register-scraper"
        }
    }
}

```

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/yFkA6WvGhsuqVedJt/builds/OsePXiSuyXxd6h4wx/openapi.json
