---
title: "Returns FEC Schedule A contribution data — money flowing INTO federal committees — in AGGREGATED form"
method: GET
path: "/v1/fec-contributions"
---

# Returns FEC Schedule A contribution data — money flowing INTO federal committees — in AGGREGATED form

`GET /v1/fec-contributions`

## Request

- Base URL: `https://api.keyvex.com`
- URL: `https://api.keyvex.com/v1/fec-contributions`
- Auth: API key in header `x-api-key`

Returns FEC Schedule A contribution data — money flowing INTO federal committees — in AGGREGATED form. Individual donors are never exposed as searchable per-record rows: the FEC sale-or-use rule (11 CFR 104.15) permits aggregated presentation only, so this tool serves group totals and a bounded ORGANISATION leaderboard (the same posture as Quiver Quantitative's public pages).  Source: api.open.fec.gov (official FEC API), queried live per request with a cached-rollup fallback (responses carry source: live | cache).  THREE MODES (pick one):  1. Aggregate totals — pass group_by:   - group_by='employer' + recipient_committee_id + cycle → total +     count per employer for that committee (FEC-computed, all itemized     rows). E.g. which employers' workforces fund committee X.   - group_by='state' + recipient_committee_id + cycle → geographic     fundraising pattern for a committee.   ⚠ On employer and state rows, contribution_count is the number of     CONTRIBUTIONS, not contributors — the FEC publishes no contributor     count for these aggregates. A cell can carry a dozen contributions     from ONE person (measured: an employer cell with 14 contributions and     a single contributor). Do not read it as a crowd, and do not use it to     judge whether a cell describes a population or an individual.   - group_by='candidate' + cycle (optionally candidate_id) → per-     candidate cycle receipts, itemized-individual share, disbursements,     cash on hand. Sorted by receipts DESC — 'who raised the most'.   - group_by='committee' + recipient_committee_id (cycle optional) →     that committee's cycle totals. Top-committee LISTS come from the     rollup cache and may lag a day.   - group_by='cycle' + candidate_id or recipient_committee_id →     per-cycle rows across cycles (fundraising trajectory).  2. Donor leaderboard — pass leaderboard=true + cycle + EXACTLY ONE    scope: recipient_committee_id | candidate_id | contributor_state |    contributor_employer. Returns top ORGANISATION donors (PAC / party /    committee / company) as name + summed total + contribution count,    PLUS the individual side as STATISTICS ONLY: individual_donor_count    and individual_total. NO median and NO maximum are served — each is    one person's number (a median over an odd count IS one contributor's    gift) and re-identifies against the FEC's own site. ⚠ SMALL-CELL    FLOOR: when fewer than 5 distinct individuals contributed in the    scope, the whole individual block is WITHHELD — count and total both    null, suppressed=true, and the envelope carries suppressed_small_cells.    Three donors plus a total is three people's gifts nearly    reconstructed, and the scope is public. The organisation board is    never floored; entities are not natural persons.    NO NATURAL PERSON IS NAMED BY THIS TOOL, IN ANY MODE. A paid service    ranking named individuals by their contribution history is a    prohibited commercial use of contributor lists (11 CFR 104.15;    52 U.S.C. 30111(a)(4)). An empty organisation list means no    organisation gave in that scope above the floor — it is never a    reason to look for people. No addresses, no city/ZIP, no per-record    rows. The response's leaderboard.complete    flag is true when every itemized row at or above the fixed $1,000    floor (min_amount is not accepted in this mode) for the scope was    aggregated — totals are then exact; otherwise the    pull hit its page cap and ranks are amount-weighted approximations.  3. Per-record (NON-INDIVIDUAL only) — pass entity_type (COM, CCM, PAC,    PTY, ORG) with optional recipient_committee_id / candidate_id /    contributor_state / cycle / amount / date filters, or sub_id for a    direct lookup. Individual (IND) rows are never returned per-record;    memo subtotals are excluded by default (exclude_memos=false to    include). Useful for PAC-to-PAC transfer analysis.  There is NO contributor_name search and no individual street/city/ZIP anywhere in this tool's output — by design, permanently.  Killer query patterns:   - Who raised the most this cycle? group_by='candidate' + cycle=2026.   - Who funds Senator X? get_fec_candidate_profile → principal     committee → leaderboard=true + recipient_committee_id + cycle.   - Which employers' staff fund committee Y? group_by='employer' +     recipient_committee_id + cycle.   - Where does committee Y's money come from? group_by='state' +     recipient_committee_id + cycle.   - PAC-to-PAC flows into committee Z? entity_type='PAC' +     recipient_committee_id.

## Query parameters

- `group_by` 'employer' | 'state' | 'candidate' | 'committee' | 'cycle'
- `leaderboard` boolean
- `recipient_committee_id` string
- `candidate_id` string
- `contributor_state` string
- `contributor_employer` string
- `entity_type` 'COM' | 'CCM' | 'PAC' | 'PTY' | 'ORG'
- `sub_id` string
- `cycle` integer
- `min_amount` number
- `max_amount` number
- `since` string
- `until` string
- `exclude_memos` boolean
- `sort_by` 'contribution_receipt_date' | 'contribution_receipt_amount'
- `sort_order` 'asc' | 'desc'
- `limit` integer

## Response `200`

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

## Other responses

- `400`: Invalid parameter.
- `401`: Missing or invalid API key.
- `402`: This tool requires a higher plan (upgrade_required). Retrying will not help.
- `429`: Tier rate/quota limit reached (rate_limited). Retry-After points at the reset.

---

[API](https://skmtc.dev/keyvex/apis/keyvex-api.md) · [All operations](https://skmtc.dev/keyvex/apis/keyvex-api/llms.txt) · [OpenAPI document](https://skmtc.dev/keyvex/apis/keyvex-api/revisions/01c0210c19cd?raw)
