Search FEC Schedule A — every itemized contribution to a federal political committee (>264M rows across all cycles). Filter by recipient committeeId or candidateId, contributor name / city / state / zip / employer / occupation, amount range, cycle (twoYearTransactionPeriod e.g. 2024), date range, isIndividual (true = individuals only; false = committee-to-committee). Sort by contribution date or amount, asc/desc. Requires at least one scope (committeeId, candidateId, twoYearTransactionPeriod cycle, or a date range) — an unscoped query scans every cycle and times out. The investigative-journalism + political-research goldmine: who gives, how much, when, working where, doing what. Each row carries the contribution receipt date, amount, contributor aggregate YTD, receipt type, memo, entity type, and link to the underlying PDF filing.
/api/gov/fec-contributionsPAYMENT-SIGNATURE.The fec contributions API is a pay-per-call gov endpoint built for AI agents and autonomous software. Search FEC Schedule A — every itemized contribution to a federal political committee (>264M rows across all cycles).
There is no signup and no API key. An agent (or any HTTP client) hits the endpoint, receives an x402 "402 Payment Required" challenge, signs a sub-cent USDC payment on Base or Solana, and retries — the data comes back on the paid request. That makes it a drop-in fec contributions data source for an agent tool-use loop, an MCP host, or a backend that needs gov data on demand without onboarding to yet another vendor portal.
| Name | Type | Description |
|---|---|---|
committeeId | string | match ^C\d{8}$ |
candidateId | string | match ^[A-Z]\d[A-Z0-9]{7}$ |
contributorName | string | min 1 chars · max 120 chars |
contributorCity | string | min 1 chars · max 80 chars |
contributorState | string | min 2 chars · max 2 chars · match ^[A-Za-z]{2}$ |
contributorZip | string | match ^\d{5}(\d{4})?$ |
contributorEmployer | string | min 1 chars · max 120 chars |
contributorOccupation | string | min 1 chars · max 120 chars |
minAmount | number | min 0 |
maxAmount | number | min 0 |
twoYearTransactionPeriod | integer | min 1980 · max 2100 |
minDate | string | match ^\d{4}-\d{2}-\d{2}$ |
maxDate | string | match ^\d{4}-\d{2}-\d{2}$ |
isIndividual | boolean | |
perPage | integer | min 1 · max 100 |
page | integer | min 1 |
sortField | string | one of: contribution_receipt_date | contribution_receipt_amount |
sortDirection | string | one of: asc | desc |
# 1. Probe with no auth → 402 envelope with PaymentRequirements curl -sS 'https://2s.io/api/gov/fec-contributions?committeeId=example&candidateId=example&contributorName=example&contributorCity=example&contributorState=xx&contributorZip=12345&contributorEmployer=example&contributorOccupation=example&minAmount=0&maxAmount=0&twoYearTransactionPeriod=1980&minDate=2024-01-01&maxDate=2024-01-01&isIndividual=false&perPage=25&page=1&sortField=contribution_receipt_date&sortDirection=asc' # 2. Sign + retry with PAYMENT-SIGNATURE: curl -sS 'https://2s.io/api/gov/fec-contributions?committeeId=example&candidateId=example&contributorName=example&contributorCity=example&contributorState=xx&contributorZip=12345&contributorEmployer=example&contributorOccupation=example&minAmount=0&maxAmount=0&twoYearTransactionPeriod=1980&minDate=2024-01-01&maxDate=2024-01-01&isIndividual=false&perPage=25&page=1&sortField=contribution_receipt_date&sortDirection=asc' \ -H 'PAYMENT-SIGNATURE: <base64-json-payload>' # Or use the canonical runner (handles probe → sign → retry): # EVM_PRIVATE_KEY=0x... node --env-file=.env.local \ # --experimental-strip-types scripts/x402-pay.ts \ # 'https://2s.io/api/gov/fec-contributions?committeeId=example&candidateId=example&contributorName=example&contributorCity=example&contributorState=xx&contributorZip=12345&contributorEmployer=example&contributorOccupation=example&minAmount=0&maxAmount=0&twoYearTransactionPeriod=1980&minDate=2024-01-01&maxDate=2024-01-01&isIndividual=false&perPage=25&page=1&sortField=contribution_receipt_date&sortDirection=asc'
import { TwoS } from '@2sio/sdk'
const client = new TwoS({
privateKey: process.env.EVM_PRIVATE_KEY as `0x${string}`,
})
const result = await client.gov.fecContributions({
"committeeId": "example",
"candidateId": "example",
"contributorName": "example",
"contributorCity": "example",
"contributorState": "xx",
"contributorZip": "12345",
"contributorEmployer": "example",
"contributorOccupation": "example",
"minAmount": 0,
"maxAmount": 0,
"twoYearTransactionPeriod": 1980,
"minDate": "2024-01-01",
"maxDate": "2024-01-01",
"isIndividual": false,
"perPage": 25,
"page": 1,
"sortField": "contribution_receipt_date",
"sortDirection": "asc"
})
console.log('endpoint:', result.endpoint)
console.log('cost:', result.costUsd, 'USDC')
console.log('tx:', result.settlement?.txHash)
console.log('data:', result.data)import os
from twosio import TwoS
client = TwoS(private_key=os.environ["EVM_PRIVATE_KEY"])
result = client.gov.fec_contributions(committeeId="example", candidateId="example", contributorName="example", contributorCity="example", contributorState="xx", contributorZip="12345", contributorEmployer="example", contributorOccupation="example", minAmount=0, maxAmount=0, twoYearTransactionPeriod=1980, minDate="2024-01-01", maxDate="2024-01-01", isIndividual=False, perPage=25, page=1, sortField="contribution_receipt_date", sortDirection="asc")
print("endpoint:", result.endpoint)
print("cost:", result.cost_usd, "USDC")
print("tx:", (result.settlement or {}).get("tx_hash"))
print("data:", result.data)// 1. Add @2sio/mcp to your MCP host config (Claude Desktop example below).
// EVM_PRIVATE_KEY funds x402 payments per call.
// claude_desktop_config.json
{
"mcpServers": {
"2sio": {
"command": "npx",
"args": ["-y", "@2sio/mcp"],
"env": { "EVM_PRIVATE_KEY": "0x..." }
}
}
}
// 2. Once the server is running, agents call this tool via standard MCP:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "gov.fec-contributions",
"arguments": {
"committeeId": "example",
"candidateId": "example",
"contributorName": "example",
"contributorCity": "example",
"contributorState": "xx",
"contributorZip": "12345",
"contributorEmployer": "example",
"contributorOccupation": "example",
"minAmount": 0,
"maxAmount": 0,
"twoYearTransactionPeriod": 1980,
"minDate": "2024-01-01",
"maxDate": "2024-01-01",
"isIndividual": false,
"perPage": 25,
"page": 1,
"sortField": "contribution_receipt_date",
"sortDirection": "asc"
}
}
}| Field | Type | Description |
|---|---|---|
ok | boolean | one of: true |
items | array | |
total | integer | Total matching rows upstream; null when unknown. |
source | object | |
page | object |
{
"ok": true,
"items": [
{}
],
"total": 1,
"source": {
"provider": "example",
"url": "example",
"license": "example"
},
"page": {
"number": 1,
"size": 1,
"pages": 1
}
}