# Congress Stock Trades Scraper - House and Senate PTRs (`dami_studio/congress-stock-trades-scraper`) Actor

Stock trades members of Congress disclose in their periodic transaction reports, one row per trade: member, state, owner, ticker, purchase or sale, trade and disclosure dates, amount range and a link to the filing. Read from the House Clerk's and the Senate's own sites. No API key.

- **URL**: https://apify.com/dami\_studio/congress-stock-trades-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** News, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.65 / 1,000 trade returneds

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

## Congress Stock Trades Scraper

The stock trades members of Congress report in their Periodic Transaction Reports, one row per trade. Each row has the member, their chamber, state and district, whose account it was, the asset and its ticker, the kind of trade, the day it was made and the day it was disclosed, the amount range, and a link to the filing it came from.

It reads the two official sources and nothing else: the House Clerk's financial disclosure site and the Senate's eFD search. There's no API key to get and no account to open.

### The law on these reports

Federal law, 5 U.S.C. § 13107, makes it unlawful to obtain or use these reports for any commercial purpose other than by news and communications media for dissemination to the general public. It also rules out using them to set anyone's credit rating, or to ask people for money for a political, charitable or other cause. The Attorney General can sue over it, and a court can add a penalty of up to $10,000.

The Senate site asks every visitor to confirm they understand those rules before it shows a single report. This actor gives that confirmation when it opens the site for you. Whether your use is allowed is your decision to make, with a lawyer if you're unsure.

### What it doesn't do

- **Paper filings aren't read.** Some members still file on paper, and those filings are scanned forms. Each one comes back as a single row with `paperFiling` set to true and a link to the scan. None of them is charged, and the trade filters can't see inside them.
- **Mostly ranges, not amounts.** Members report a range, such as $1,001 - $15,000, and you get it with both ends as numbers too. Now and then a member writes an exact figure instead, like $2,722.50, and then both ends are that figure.
- **House filings start in 2015.** The Clerk's yearly lists hold no periodic transaction reports before then. The Senate's search goes back to 2012.
- **Older House filings mix up capital letters.** In House filings from 2015 to 2021 the text itself reads "apple Inc." for Apple Inc. and "(TsLa)" for TSLA. Tickers are put back in capitals. Names are left the way the filing's text has them.
- **Categories follow the filing.** The Senate files most ETFs as plain Stock, so an ETF filter finds mostly House trades. A trade with no ticker (a bond, a private company, a fund inside an account) never matches a ticker filter.
- **Amended trades come back twice.** When a member amends a filing, the amendment repeats its trades. You get both copies, and `filingStatus` tells them apart.
- **No prices or returns.** Only what the filings say.

### Input

**Last days.** Filings disclosed in the last few days, today included. Set it to 7 on a weekly schedule, or 2 on a daily one so a late filing isn't missed.

**Disclosed from, Disclosed to.** A range of disclosure dates instead, written like `2026-08-01`. Leave the end empty to run up to today.

**Chamber.** House and Senate together, or just one.

**Members.** Names, whole or in part: `Pelosi`, `Nancy Pelosi`, `Tuberville`. A filing matches when the member's name contains every word you typed.

**States, House districts.** Two-letter states, and House seats written like `CA11`. An at-large seat is `00`, as in `AK00`. A district only exists in the House, so setting one leaves the Senate out.

**Traded from, Traded to.** The day the trade was made, which is usually weeks before it's disclosed. Members have 30 days from being told about a trade, and never more than 45 days from the trade itself, to report it.

**Tickers, Transaction types, Minimum amount, Asset types, Owners.** Narrow the trades down. The minimum amount keeps trades whose range starts at or above the one you pick.

**List paper filings.** On unless you switch it off.

**Maximum trades.** 1,000 unless you change it, up to 50,000, newest filings first.

```json
{
  "lastDays": 30,
  "chamber": "both",
  "tickers": ["NVDA", "MSFT"],
  "transactionTypes": ["purchase"],
  "minAmount": "15001",
  "maxTrades": 500
}
```

### Output

One row per trade, newest filing first, in the order each filing lists its trades.

| Field | Example | Notes |
|---|---|---|
| `memberName` | `Kevin Hern` | as the chamber's own list writes it |
| `chamber` | `House` | or `Senate` |
| `state`, `district` | `OK`, `01` | district is empty for senators; `00` is an at-large seat |
| `owner` | `Joint` | `Self`, `Spouse`, `Joint` or `Dependent child` |
| `ticker` | `ADBE` | empty for bonds, private companies and anything filed without one; an exchange can carry two, as `OLD/NEW` |
| `assetName` | `Adobe Inc. - Common Stock` | |
| `assetType` | `Stocks (including ADRs)` | the filing's own words; the Senate writes them out (`Municipal Security`) |
| `assetCategory` | `stock` | one of the nine the Asset types filter uses |
| `transactionType` | `Partial sale` | `Purchase`, `Sale`, `Partial sale` or `Exchange` |
| `transactionDate` | `2026-08-14` | the day of the trade |
| `notificationDate` | `2026-08-27` | House only: the day the member learned of it |
| `disclosureDate` | `2026-09-01` | the day the filing was received |
| `amountRange` | `$15,001 - $50,000` | as filed |
| `amountMin`, `amountMax` | `15001`, `50000` | `amountMax` is empty for "Over" ranges; an exact figure fills both |
| `capitalGainsOver200` | `false` | the House form's "Cap. Gains > $200?" box; empty for the Senate and for House filings from 2015 to 2017, which have no box |
| `comment` | | the Senate's comment column |
| `description` | `Purchased 100 call options with a strike price of $100 and an expiration date of 6/17/27.` | the House's description line, or the Senate's details under the asset (coupon, maturity, company) |
| `subholdingOf` | `Hern Family Foundation` | House only: the account or trust that holds the asset |
| `filingStatus` | `New` | House: `New` or `Amended` for each trade; Senate: `New` or the amendment number |
| `paperFiling`, `note` | `false` | true on the one row a paper filing gets |
| `reportId`, `reportUrl` | `20035326`, the PDF | the filing itself, to check any row against |

The run also leaves a report, `RUN_REPORT`, in its key-value store: how many filings each chamber listed and matched, which ones were read, trades your filters left out, and why the run stopped.

### What you pay

Each trade in your dataset is one charge. Nothing else costs anything: not a paper filing, not a trade your filters leave out, not a filing that couldn't be read, not the sample row you get when no dates are set. If you set a maximum charge for the run, it stops when that's reached. The price is on the Pricing tab.

### Limits

- 50,000 trades and 3,000 filings per run, newest filings first. A run that reaches either stops and says where.
- It reads one House file every half second and one Senate page a second, so a long range takes a while.
- A filing is only used after it has been checked against the list that pointed to it: the House PDF must carry the same filing number and the member's name, and a Senate page must name the member and hold as many trades as it says it has. A filing that fails is listed in the run report and not charged.

### Where the data comes from

The House Clerk's financial disclosure reports (disclosures-clerk.house.gov), through its yearly list of filings, and the Senate's Electronic Financial Disclosure search (efdsearch.senate.gov). Every row links to the filing it was read from.

### Questions

**Can I get new trades every morning?** Schedule the actor with Last days set to 2. Filings arrive through the day, so a two-day window catches the ones that came in after yesterday's run.

**Why was this trade made weeks before it was disclosed?** That's normal. The law gives members up to 45 days from the trade.

**Why do some rows have no trade in them?** Those are paper filings, marked `paperFiling`. Open `reportUrl` to see the scan.

**Is a missing trade my fault or the filing's?** Check the filing's own link first. If the trade is there and not in your data, `RUN_REPORT` shows whether that filing was read, and which filter left the trade out.

# Actor input Schema

## `lastDays` (type: `integer`):

Filings disclosed in the last N days, today included. 7 means this week's filings, which suits a daily or weekly schedule. Used when Disclosed from is empty.

## `disclosedFrom` (type: `string`):

The first day a filing was disclosed, as YYYY-MM-DD. Periodic transaction reports start in 2012. Leave it empty to use Last days instead.

## `disclosedTo` (type: `string`):

The last day. Leave it empty to run up to today.

## `chamber` (type: `string`):

Which chamber's filings to read.

## `members` (type: `array`):

Names, whole or in part: Pelosi, Nancy Pelosi, Tuberville. A filing matches when the member's name holds every word of one of these. Leave it empty for everyone.

## `states` (type: `array`):

Members from these states. The House also has delegates for DC and the territories. Leave it empty for every state.

## `districts` (type: `array`):

Seats written like CA11 or NY14. An at-large seat is 00, as in AK00. Senators have no district, so giving one reads House filings only.

## `tradedFrom` (type: `string`):

Only trades made on or after this day. Members have up to 45 days to disclose a trade, so a trade from last month can sit in a filing disclosed this week.

## `tradedTo` (type: `string`):

Only trades made on or before this day.

## `tickers` (type: `array`):

Only these tickers, such as NVDA or BRK.B. Many rows have no ticker at all (bonds, private companies, funds held in an account), and those never match.

## `transactionTypes` (type: `array`):

Leave it empty for all four.

## `minAmount` (type: `string`):

Filings give an amount range, not a figure. This keeps trades whose range starts at or above the one you pick.

## `assetTypes` (type: `array`):

Each row's category comes from how the member filed it. The Senate files most ETFs under Stock, for instance, so ETF finds mostly House rows.

## `owners` (type: `array`):

Whose holding the trade was in. Leave it empty for all.

## `includePaperFilings` (type: `boolean`):

Some members still file on paper. Those filings are scans, so their trades aren't read; each one comes back as a single row with its link, and none of them is charged. The trade filters above can't see inside them.

## `maxTrades` (type: `integer`):

The most trades returned in one run, newest filings first. Each trade returned is one charge.

## Actor input object example

```json
{
  "lastDays": 7,
  "chamber": "both",
  "includePaperFilings": true,
  "maxTrades": 50
}
```

# Actor output Schema

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

One row per transaction disclosed in your dates: member, chamber, state and district, owner, ticker and asset, trade type, trade and disclosure dates, amount range, and the filing's id and link. Paper filings appear as rows marked paperFiling, with their link.

## `report` (type: `string`):

What each chamber's list held, which filings were read, rows left out and why, and why the run stopped.

# 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 = {
    "lastDays": 7,
    "maxTrades": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/congress-stock-trades-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 = {
    "lastDays": 7,
    "maxTrades": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/congress-stock-trades-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 '{
  "lastDays": 7,
  "maxTrades": 50
}' |
apify call dami_studio/congress-stock-trades-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/congress-stock-trades-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/vueXBMhUbN6REY5Iv/builds/dn6GlXNfYqLdxJvEC/openapi.json
