Returns FEC Schedule E independent expenditures — money spent BY a super PAC (or IE-only PAC) uncoordinatedly FOR or AGAINST a federal candidate

Returns FEC Schedule E independent expenditures — money spent BY a super PAC (or IE-only PAC) uncoordinatedly FOR or AGAINST a federal candidate. Hallmark vehicle for political ad spending since Citizens United (2010). Critical signal: support_oppose_indicator — 'S' = support, 'O' = oppose. A single candidate often has dozens of S and O entries across many super PACs in one cycle. Filter by support_oppose='O' to find attack ads; 'S' to find positive ads. Source: api.open.fec.gov/v1/schedules/schedule_e/. F24 filings (24-hour notices within 20 days of an election) and F5 (quarterly IE reports) both flow through this endpoint. Filers FEC classes as "a person or a group" (Form 5 filers, committee types I and E) are served when the filer is a group; a filer whose name is, or may be, a natural person's is withheld per record, as is any filer KeyVex holds no committee record for (FEC sale-or-use rule, 11 CFR 104.15). Killer query patterns: - Attack ads on Senator X: candidate_id='S6PA00091' + support_oppose='O' - Recent spend across a cycle: support_oppose='O' + since='2025-01-01' - Top political ad vendors: payee_name='AXIOM' (substring) - Negative spend in a race: candidate_office_state='PA' + support_oppose='O' Filter combinations note: server-side indexes support one equality filter (candidate_id / committee_id / support_oppose / candidate_office_state) + a date / amount sort. Other filters (payee_name, description, exclude_memos) are applied client-side. NOTE on cycle: the FEC leaves two_year_transaction_period null on many rows, so the cycle filter is INCOMPLETE (it undercounts) and is not currently indexed — scope a cycle by DATE instead, e.g. since='2025-01-01' for the 2026 cycle.

get/v1/fec-independent-expenditures

Request

  • Base URL: https://api.keyvex.com
  • URL: https://api.keyvex.com/v1/fec-independent-expenditures
  • Auth: API key in header x-api-key

Query parameters

sub_idstring

FEC sub_id (globally unique row ID). Direct doc lookup.

committee_idstring

FEC committee that spent the money (typically a super PAC). A filer who is, or may be, a natural person returns no rows — see the description.

candidate_idstring

Target candidate being supported or opposed.

support_oppose'S' | 'O'

'S' = filter to ads supporting the target; 'O' = filter to ads opposing. Omit for both.

payee_namestring

Case-insensitive substring on the payee_name (ad agency, media buyer, vendor). Client-side filter.

descriptionstring

Case-insensitive substring on disbursement_description (free-text purpose of the spend, e.g., 'tv ad', 'mailer', 'digital advertising'). Client-side filter.

candidate_office'H' | 'S' | 'P'

Office of the target candidate: H/S/P.

candidate_office_statestring

2-letter state code of the target candidate (e.g., 'PA', 'TX').

min_amountnumber

Inclusive lower bound on expenditure_amount in dollars.

max_amountnumber

Inclusive upper bound on expenditure_amount.

sincestring

Inclusive lower bound on expenditure_date (YYYY-MM-DD).

untilstring

Inclusive upper bound on expenditure_date (YYYY-MM-DD).

cycleinteger

Election cycle (2-year transaction period), e.g. 2026/2024/2022. INCOMPLETE — the FEC leaves this field (two_year_transaction_period) null on many rows, so filtering by cycle undercounts, and the cycle index is not provisioned (a cycle query currently returns INDEX_MISSING). For complete cycle coverage, scope by DATE instead: since='<cycle start>' (e.g. since='2025-01-01' for the 2026 cycle).

exclude_memosboolean

When true (DEFAULT), filters out rows flagged memoed_subtotal=true — FEC's aggregate / receipt-account duplicates that double-count the same dollars across multiple rows. Top-spender queries are misleading without this filter. Pass exclude_memos=false to include the raw memo rows.

sort_by'expenditure_date' | 'expenditure_amount'

Sort key. Default: expenditure_date.

sort_order'asc' | 'desc'

Default: desc.

limitinteger

Max records. Default 50, max 500.

Response

JSON envelope: { results: [...], count, has_more }.

Changes

No recorded changes to this operation across all 1 revision of this API.