FEC Campaign Finance Scraper
Pricing
from $0.96 / 1,000 item extracteds
FEC Campaign Finance Scraper
Search official OpenFEC candidates, committees, filings, receipts, disbursements, and finance summaries for recurring campaign research.
Pricing
from $0.96 / 1,000 item extracteds
Rating
0.0
(0)
Developer
Automation Lab
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
18 days ago
Last modified
Categories
Share
Export official FEC campaign finance data from OpenFEC as clean, integration-ready dataset records. Search candidates and committees, retrieve filings, inspect itemized receipts and disbursements, or compare candidate and committee finance summaries across election cycles.
The Actor uses the official Federal Election Commission API. Every result includes the complete source record plus normalized fields for spreadsheets, databases, dashboards, and recurring research.
What can this FEC campaign finance scraper do?
- Look up federal candidates by name or FEC candidate ID.
- Search committees and PACs by name or committee ID.
- Export official campaign filings for selected candidates or committees.
- Retrieve itemized Schedule A receipts and contributions.
- Retrieve itemized Schedule B disbursements.
- Export candidate or committee totals, including receipts, spending, and cash on hand.
- Filter by election cycle and bounded transaction dates.
- Stop at an exact
maxItemslimit and deduplicate source records. - Preserve the complete OpenFEC response under
datafor advanced analysis.
Who is it for?
Political researchers use it to build auditable candidate and committee datasets.
Journalists use it to inspect filings, contributions, spending, and campaign totals.
Compliance teams use scheduled runs to collect source-backed records for review.
Civic data teams use normalized output instead of maintaining OpenFEC pagination code.
Developers and analysts connect the dataset to Python, JavaScript, SQL, Google Sheets, or BI tools.
Why use the Actor instead of calling OpenFEC directly?
OpenFEC is already an excellent public source. This Actor adds an input form, validation, bounded pagination, transient retries, deduplication, normalized fields, Apify datasets, scheduling, webhooks, API access, and MCP access.
It does not replace or obscure the source. Each row includes a FEC URL and the complete returned record.
No browser or proxy is used. That keeps runs lightweight and makes API failures explicit rather than silently returning empty output.
What FEC data is extracted?
| Record type | Typical fields |
|---|---|
candidate | candidate ID, name, party, office, state, active cycles |
committee | committee ID, name, designation, type, party, candidate IDs |
filing | filing ID, committee, form/report type, coverage dates, totals |
receipt | contributor, amount, date, employer, occupation, memo, committee |
disbursement | payee, amount, date, purpose, category, committee |
candidate_summary | cycle totals, receipts, disbursements, cash on hand |
committee_summary | cycle totals, receipts, spending, debts, cash on hand |
Fields vary by OpenFEC record type.
Normalized properties may be absent when the upstream record does not contain that concept.
The data object preserves all source fields.
How to run an FEC candidate lookup
- Open the Actor input page.
- Select
Candidatesas the record type. - Enter a name such as
Bernie Sanders. - Choose a small
maxItemsvalue for the first run. - Click Start.
- Open the default dataset to inspect or export results.
Example input:
{"recordType": "candidate","query": "Bernie Sanders","maxItems": 5}
This query currently returns official candidate identities including P60007168.
Input parameters
| Field | Type | Required | Description |
|---|---|---|---|
recordType | string | Yes | Candidate, committee, filing, receipt, disbursement, or a finance summary. |
query | string | By mode | Candidate or committee name search. |
candidateIds | string[] | By mode | Exact nine-character FEC candidate IDs. |
committeeIds | string[] | By mode | Exact nine-character FEC committee IDs. |
cycle | integer | No | Even election-cycle year from 1976 onward. |
minDate | string | Transactions | Start date in MM/DD/YYYY format. |
maxDate | string | Transactions | End date in MM/DD/YYYY format. |
apiKey | string | No | Data.gov API key for higher limits; stored as a secret input. |
maxItems | integer | No | Maximum unique rows, from 1 to 10,000. |
Candidate searches require query or candidateIds.
Committee searches require query or committeeIds.
Filings require at least one candidate or committee ID.
Receipts and disbursements require committee IDs and both transaction dates.
Summary modes require IDs for the selected entity.
Output example
A candidate lookup produces rows like this abbreviated real record:
{"recordType": "candidate","sourceId": "P60007168","sourceUrl": "https://www.fec.gov/data/candidate/P60007168/","name": "SANDERS, BERNARD","candidateId": "P60007168","party": "DEM","office": "P","state": "US","retrievedAt": "2026-08-28T20:20:00.000Z","data": {"candidate_id": "P60007168","name": "SANDERS, BERNARD","office": "P","party": "DEM"}}
Export dataset rows as JSON, CSV, Excel, XML, RSS, or JSONL using Apify's dataset endpoints.
How much does it cost to export FEC campaign finance records?
Pricing uses one small start event plus one item event for each accepted dataset row.
Rejected, duplicate, or failed records are not charged as items.
The exact tier applicable to your account is displayed by Apify before a run. At the current Bronze configuration, the start fee is $0.00005 and 100 records cost about $0.16005 in Actor charges. A 1,000-record run costs about $1.60005 at that tier. Higher usage tiers have lower per-record prices.
Apify platform compute is accounted for by the pay-per-event price. A personal Data.gov key is free to obtain from Data.gov and is not sold by this Actor.
Candidate, committee, and filing workflows
Use a name search first to discover official IDs. Then use those stable IDs in filing or summary runs.
A repeatable workflow can be:
- Search a candidate name.
- Save the returned candidate ID.
- Retrieve candidate summaries by cycle.
- Find associated committee IDs in the complete source data.
- Export filings for selected committees.
- Schedule the same inputs and compare datasets over time.
For receipts or disbursements, keep date ranges narrow. This improves API response time and reduces the chance of upstream query timeouts.
Transaction export examples
Receipt export with a bounded date range:
{"recordType":"receipt","committeeIds":["C00577130"],"cycle":2020,"minDate":"01/01/2020","maxDate":"12/31/2020","maxItems":5}
Narrow disbursement export:
{"recordType":"disbursement","committeeIds":["C00577130"],"cycle":2020,"minDate":"01/01/2020","maxDate":"01/31/2020","maxItems":5}
Schedule A and B use the source's transaction cursors, not numbered pages. The limit is global across all committee IDs and pages. Duplicate records do not consume the limit or an item charge. Missing/repeated cursors or later-page failures fail explicitly; a failed run may contain already delivered partial rows and must not be treated as a complete export. Use the Receipts and disbursements dataset view for contributor, employer, occupation, payee and purpose columns.
Comparing finance periods and filing provenance
Use candidate_summary with candidateIds:["P60007168"] and cycle:2020 for two-year cycle totals.
Omit cycle to retrieve the source's available periods, which may include full-election totals.
electionYear, electionFull, coverageStartDate and coverageEndDate preserve that distinction: full-election totals with no source cycle do not receive an inferred cycle.
Compare only equivalent coverage periods; use the Finance periods dataset view.
Summary deduplication includes election and coverage labels. When comparing snapshots, combine sourceId with these period fields rather than assuming a source ID alone distinguishes every summary period.
Filings expose exact fileNumber and imageNumber as text. Existing image-based filingId and sourceId remain unchanged.
Unsafe numeric identifiers fail rather than silently round; the complete source record is retained in data.
Candidate IDs begin H, S or P; committee IDs begin C. IDs are trimmed and uppercased, with duplicate IDs removed.
Dates must be real calendar dates in ascending order. Optional blank strings are treated as omitted.
Name queries apply only to candidate/committee searches; other modes ignore query. In name-search modes, queries and IDs are both passed to OpenFEC when both are supplied; matching is defined by OpenFEC, not an Actor-side exact-name match.
Scheduling and monitoring
Create an Apify Task from a tested input. Set a daily, weekly, or monthly schedule. Use a webhook to notify a data pipeline after successful runs.
The Actor exports snapshots; it does not itself calculate changes or send alerts.
Compare stable sourceId values and source fields between scheduled datasets to identify new or changed records.
Use from the Apify API with cURL
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~fec-candidates-campaign-finance/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"recordType":"candidate_summary","candidateIds":["P60007168"],"maxItems":20}'
For production systems, send the Apify token in an authorization header rather than storing it in source code. Poll the returned run ID or use a webhook to wait for completion.
Use from JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/fec-candidates-campaign-finance').call({recordType: 'filing',committeeIds: ['C00577130'],cycle: 2020,maxItems: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Use from Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('automation-lab/fec-candidates-campaign-finance').call(run_input={'recordType': 'committee_summary','committeeIds': ['C00577130'],'maxItems': 20,})items = client.dataset(run['defaultDatasetId']).list_items().itemsprint(items)
Use with MCP and AI assistants
Add the Actor to Claude Code:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/fec-candidates-campaign-finance"
Claude Desktop, Cursor, and VS Code MCP setup
Use this JSON configuration in Claude Desktop, Cursor, or VS Code:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/fec-candidates-campaign-finance"}}}
MCP example prompts:
Example prompt: “Use the FEC Campaign Finance Scraper MCP tool to look up candidates named Bernie Sanders and return their IDs and election cycles.”
- “Using MCP, run the Actor to export 2020 filings for committee C00577130 and summarize the report types.”
- “Call the campaign-finance MCP tool for candidate P60007168 and compare receipts with disbursements.”
Data.gov API keys and rate limits
If apiKey is omitted, the Actor loads the current public API configuration from the official FEC data site and uses its browser-facing OpenFEC key. This avoids relying on the globally shared, low-quota DEMO_KEY.
For higher-volume recurring jobs, request a free Data.gov API key and provide it in the secret apiKey field.
The Actor redacts the key from request logs.
Keys belong in Actor inputs or secure Task configuration, never in README files or code.
Transient transport failures/timeouts, 429 and 5xx responses are retried twice with bounded backoff. Authorization and validation failures are not retried. Requests have a 30-second timeout; exhausted errors do not expose API keys or raw response bodies. Persistent quota, authorization, or upstream errors fail the run with a non-zero status.
Limits and failure behavior
- OpenFEC controls source freshness, coverage, and field definitions.
- A successful no-result query produces an empty dataset.
- Invalid IDs, dates, cycles, modes, and missing mode-specific filters fail before extraction.
- Transaction queries must include a committee and bounded date range.
- The Actor does not infer donor identity or merge people with similar names.
- The Actor does not bypass redactions made by the FEC.
- The Actor does not provide legal compliance advice.
maxItemsis capped at 10,000 per run; the Apify run budget can stop delivery earlier. Only budget-accepted rows are delivered and charged.- Defaults remain 100 rows, 256 MiB and 300 seconds. An upstream error or platform timeout is not a complete export.
- Large OpenFEC queries can time out upstream even when the Actor is healthy.
Diagnostic privacy
Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL query strings are removed, and reports are retained for 30 days. Normal retries and valid empty results are not reported as terminal errors.
Responsible use and legal considerations
FEC records are official public government data. Use them for lawful research, journalism, compliance, civic analysis, and public-interest work.
Campaign-finance records can contain names, addresses, occupations, and employers. Apply applicable privacy, data-retention, security, and fair-use requirements. Do not use the output for harassment, identity theft, unlawful discrimination, or unsupported allegations. Always verify consequential conclusions against the linked FEC source and current law.
Troubleshooting
The run failed with HTTP 429. The current official FEC public key can still enforce upstream limits. Provide your own Data.gov API key, reduce concurrent scheduled runs, or retry after the quota window resets.
A transaction request timed out.
Use a smaller date range, one committee per run, and a lower maxItems value.
The dataset is empty. Check the official ID, election cycle, and date range on fec.gov. An empty result can be valid when no matching source records exist.
The Actor rejects my ID.
Use the nine-character ID shown by FEC, such as P60007168 or C00577130.
Some normalized fields are missing.
Different OpenFEC collections expose different fields.
Inspect the complete data object for source-specific values.
FAQ
Does the Actor scrape web pages?
No. It calls the official OpenFEC JSON API directly.
Does it require a proxy?
No. No proxy option or automatic proxy fallback is enabled.
Can it export all receipts for every committee?
The current product is intentionally query-driven. Provide committee IDs and dates, then use scheduled or partitioned runs for large research projects.
Are election cycles included?
Yes when OpenFEC exposes them.
Candidate records preserve their cycles array in data, while summary and transaction rows expose normalized cycle fields where available.
Are all outputs charged separately?
No.
There is one item event for every accepted row, regardless of record type.
The complete source object does not incur a separate event.
Can I use the data in Google Sheets?
Yes. Export CSV or Excel from the dataset, or connect Apify to Google Sheets through an integration or webhook workflow.
Storage and support
Records are stored in your run's Apify default dataset, with no shared cross-run cache or named dataset. Dataset, input and run-log retention follows your Apify account settings; delete run storage through Apify when no longer needed. The Actor does not transmit exported transaction records to another enrichment service or use AI to generate output. The only additional recipient is our private diagnostic service described above. This is an independent Automation Lab tool, not affiliated with or endorsed by the Federal Election Commission. For problems, open an issue on the Actor's Apify page and provide a run link and a sanitized input example; never post API keys.
Related Actors
This Actor is currently positioned as a standalone official FEC research tool. No existing Automation Lab Actor provides a directly adjacent workflow that would improve the supported buyer journey without creating a misleading cross-link.
For general Apify integrations, use dataset exports, schedules, webhooks, Make, Zapier, JavaScript, Python, or MCP.