# eCFR Regulations Scraper — Codified Federal Rules (`devilscrapes/ecfr-regulations-scraper`) Actor

Extract currently-in-force US federal regulations from the Electronic Code of Federal Regulations (eCFR). Give it Title/Part pairs and get one row per section with citation, heading and full body text as clean JSON.

- **URL**: https://apify.com/devilscrapes/ecfr-regulations-scraper.md
- **Developed by:** [DevilScrapes](https://apify.com/devilscrapes) (community)
- **Categories:** News, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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?

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

<div align="center">
  <img src=".actor/icon.svg" width="160" alt="Devil Scrapes mark" />

## eCFR Regulations Scraper — Codified Federal Rules

**💰 $2.20 / 1 000 results**  ·  pay only for results  ·  no credit card to try

*We do the dirty work so your dataset stays clean.* 😈

Extract currently-in-force US federal regulations from the Electronic Code of Federal Regulations (eCFR) by Title/Part — one row per section, with citation, heading and full body text as clean JSON.

</div>

***

### 🎯 What this scrapes

The eCFR (ecfr.gov, National Archives) is the codified, currently-in-force text of US federal regulations — Title > Chapter > Part > Subpart > Section. Give this Actor a bounded list of `{title, part}` pairs and it fetches each part's official XML, walks every section, and returns one clean row per section: a well-formed citation like `"29 CFR 570.1"`, its heading, and the full verbatim body text. This is **not** a change feed — for "what changed today" in the Federal Register's daily journal of rulemaking, see our [Federal Register Scraper](https://apify.com/DevilScrapes/federal-register-documents-scraper). This Actor answers a different question: "what is the rule right now, verbatim."

### 🔥 What we handle for you

- 📄 **Section-level parsing** — the GPO XML nests sections inside subject groups and part wrappers; we walk every `SECTION` node regardless of nesting and give you one flat row per provision.
- 📅 **Date resolution** — omit a date and we look up the latest in-force date for that title automatically, instead of you guessing a valid one.
- 🔁 **We retry with exponential backoff** on `408 / 429 / 503` and honour `Retry-After`. Up to 5 attempts per request.
- 🧊 **We keep the dataset clean** — Pydantic-validated rows, a regex-checked citation on every section, ISO-8601 timestamps.
- 💰 **You pay only for results that land.** No data → no charge (only the small `actor-start` warm-up fee).

### 💡 Use cases

- Pull the verbatim text of a regulation for a compliance checklist or GRC platform.
- Feed a legal-ops search index with clean, citation-tagged section text.
- Snapshot a Part's in-force text on a given date for an audit trail.
- Monitor a handful of Parts your industry cares about without downloading an entire Title.

### ⚙️ How to use it

1. Click **Try for free** at the top of the page.
2. List the `{title, part}` pairs you need under **Title/Part targets** — up to 20 per run.
3. Optionally set **As-of date**; leave it empty to use the latest in-force date automatically.
4. Click **Start**. Output streams into the run's dataset, one row per section.
5. Export from **Storage → Dataset** as JSON, CSV, or Excel — or fetch via the API.

### 📥 Input

| Field | Type | Required | Default | Notes |
|---|---|:--:|---|---|
| `targets` | `array` | yes | `[{"title": 1, "part": "1"}]` | `{title, part}` pairs to fetch. 1-20 pairs per run — whole-title fetches are not supported. |
| `asOfDate` | `string` | no | `null` | Fetch date as `YYYY-MM-DD`. Leave empty to resolve the latest in-force date automatically per title. |
| `proxyConfiguration` | `object` | no | `{"useApifyProxy": true}` | eCFR is a public, keyless government API and does not fingerprint clients; proxy is wired per org standard. |

#### Example input

```json
{
  "targets": [
    { "title": 1, "part": "1" }
  ],
  "asOfDate": null
}
```

### 📤 Output

Every row is one codified CFR section.

| Field | Type | Notes |
|---|---|---|
| `citation` | `string` | e.g. `"1 CFR 1.1"`. |
| `title_number` | `integer` | CFR title number. |
| `title_name` | `string` | Title name, e.g. "General Provisions". |
| `part` | `string` | CFR part identifier. |
| `section_identifier` | `string` | Section number, e.g. `"1.1"`. |
| `heading` | `string` | Section heading text, whitespace-collapsed. |
| `body_text` | `string` | Full paragraph text, joined with blank lines. |
| `as_of_date` | `string` | Resolved fetch date (`YYYY-MM-DD`). |
| `scraped_at` | `string` | ISO-8601 UTC fetch timestamp. |

#### Example output

```json
{
  "citation": "1 CFR 1.1",
  "title_number": 1,
  "title_name": "General Provisions",
  "part": "1",
  "section_identifier": "1.1",
  "heading": "§ 1.1 Definitions.",
  "body_text": "As used in this chapter, unless the context requires otherwise—\n\nAdministrative Committee means...",
  "as_of_date": "2026-08-28",
  "scraped_at": "2026-09-01T00:00:00Z"
}
```

### 💰 Pricing

Pay-Per-Event — you pay only when these events fire:

| Event | USD | What it is |
|---|---:|---|
| `actor-start` | $0.20 | One-off warm-up charge per run |
| `result` | $0.002 | Per codified section emitted |

Example: 1 000 sections at the rates above ≈ **$2.20** ($0.20 start + $2.00 for 1 000 sections at $0.002 each). No subscription, no minimum, no card to start — Apify gives every new account $5 of free credit.

### 🚧 Limitations

- Whole-title fetches are not supported by design — a single Part can already be tens of megabytes (Title 40 Part 60 alone is over 14 MB / 1,830 sections), so the Actor bounds every run to the Parts you name.
- One `asOfDate` per run — point-in-time diffing across two dates isn't a supported mode.
- Amendment/version history and agency metadata aren't included — this Actor returns the in-force text as it stands on the resolved date, not a change history.

### ❓ FAQ

**Do I need an API key?**

No. The eCFR versioner API is public and keyless, so a run needs no credentials from you.

**How is this different from your Federal Register Actor?**

Federal Register is the daily journal of rulemaking activity — "what changed." This Actor returns the eCFR's codified, currently-in-force text — "what the rule says right now." Different site, different API, different corpus.

**Why can't I just fetch a whole Title?**

Some Titles run to tens of megabytes for a single Part. Naming exact `{title, part}` pairs keeps every run's cost and runtime predictable — list the Parts you actually need.

**What happens if a Part has no in-force text?**

The run finishes successfully with zero rows for that Part and a status message explaining why — an empty result is not a failure.

### 💬 Your feedback

Spotted a bug, hit a weird edge case, or need a new field? Open an
issue on the Actor's **Issues** tab on Apify Console — we ship
fixes weekly and we read every report.

***

<div align="center">

Built by **[Devil Scrapes](https://apify.com/DevilScrapes)** 😈 — a small fleet of
opinionated public-data Actors. Honest pricing, real engineering, zero fine print.

</div>

# Actor input Schema

## `targets` (type: `array`):

`{title, part}` pairs to fetch, e.g. <code>{"title": 29, "part": "570"}</code>. 1-20 pairs per run — a single part can be large, so whole-title fetches are not supported.

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

Fetch the regulation as it stood on this date, as <code>YYYY-MM-DD</code>. Leave empty to resolve the latest date automatically per title.

## `proxyConfiguration` (type: `object`):

eCFR is a public, keyless government API and does not fingerprint clients. Apify Proxy is wired per org standard but is not required for this target to answer.

## Actor input object example

```json
{
  "targets": [
    {
      "title": 1,
      "part": "1"
    },
    {
      "title": 29,
      "part": "570"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

All dataset items as JSON.

## `datasetItemsCsv` (type: `string`):

Same data exported to CSV.

## `datasetView` (type: `string`):

Open the run dataset in the Console.

# 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 = {
    "targets": [
        {
            "title": 1,
            "part": "1"
        },
        {
            "title": 29,
            "part": "570"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("devilscrapes/ecfr-regulations-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 = {
    "targets": [
        {
            "title": 1,
            "part": "1",
        },
        {
            "title": 29,
            "part": "570",
        },
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("devilscrapes/ecfr-regulations-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 '{
  "targets": [
    {
      "title": 1,
      "part": "1"
    },
    {
      "title": 29,
      "part": "570"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call devilscrapes/ecfr-regulations-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devilscrapes/ecfr-regulations-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/5VMbeGeZxq3XNNwVr/builds/LSH2VglgTSzte4VtZ/openapi.json
