GovGreed API Documentation
REST API and MCP server for the integrated US civic accountability dataset — 218M FEC contributions, 190K STOCK Act trades, 61K bills, 159 indexed tables joined into one queryable graph. Free tier 250 calls/day. Self-serve. No sales calls.
Building an AI agent or MCP integration? Start with GET /atlas to discover every queryable entity, then chain into the entity-specific endpoints. The /openapi spec is also live for codegen.
Who this is for
- Journalists / newsrooms — pull a CSV of every donor at a hedge fund or every carveout in a bill.
- Researchers — backtest political-money signals or build conflict-of-interest scores.
- Developers / AI agents — wrap our endpoints in your own product or hook the MCP server into Claude / Cline.
- Citizens — query who funds your representative, what bills they sponsor, who profits.
What's in scope
Donors
FEC individual contributions ≥ $200, 5 cycles. Fuzzy search + per-donor profiles.
Employers
FEC employer aggregates — find every donor at a firm.
Politicians
538 sitting members of Congress + their donors.
Bills
Full intelligence: stage, sponsor, pass-likelihood model, affected tickers, congressional + insider trades.
Companies
Public-ticker political exposure: lobbying, donations, contracts, insider signal.
Atlas
The full data catalog — 159 tables, what's in each, what RPCs read them.
Quickstart
1. Get a key
While in closed beta, sign in to govgreed.com with the email we allowlisted, then visit /internal/api-dashboard and click "Issue new key". The plaintext key is shown once — copy it immediately.
2. Hit a public endpoint (no key needed)
curl https://www.govgreed.com/api/v1/status
Should return a JSON envelope with data.service: "govgreed-api".
3. Hit your first authed endpoint
KEY=gg_pub_yourkeyhere
curl -H "Authorization: Bearer $KEY" \
"https://www.govgreed.com/api/v1/donors/search?q=mercer&limit=5"
4. Inspect the rate-limit headers
Every authed response includes:
X-RateLimit-Limit: 250
X-RateLimit-Remaining: 2487
X-RateLimit-Reset: 1746230400 # unix seconds until midnight UTC
X-Tier: free
Authentication
Send your API key on every authed request via the Authorization header
(Bearer token) or the X-API-Key header. The Authorization form
is canonical.
Authorization: Bearer gg_pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# or
X-API-Key: gg_pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Key format
- Prefix:
gg_pub_— distinguishes published API keys from internal tokens. - Body: 48 lowercase hex characters (24 bytes of randomness).
- Total length: 55 characters.
- We store only the SHA-256 hash; the plaintext is shown once at issuance.
Revoking a key
Hit "Revoke" on the dashboard, or call revoke_api_key from a Supabase-authenticated
session. Revoked keys return 403 KEY_REVOKED immediately.
Rate limits
Two layers, both enforced at the gateway.
| Layer | Free | Pro ( | Behavior on excess |
|---|---|---|---|
| Burst | 5 req/sec | 5 req/sec | 429 BURST_LIMIT_EXCEEDED + Retry-After: 1 |
| Daily | 250 calls/day | 2,500 calls/day | 429 DAILY_QUOTA_EXCEEDED, resets 00:00 UTC |
| Keys per account | 5 active | 20 active | 422 on issue attempt |
Need more than 2,500/day? Email team@mmamodel.ai — we negotiate a commercial license per use case rather than maintain a self-serve enterprise tier.
Response envelope
All successful responses share this shape:
{
"data": [...] | {...} | scalar,
"meta": {
"version": "v1",
"request_id": "req_abc123def4",
"count": 25,
"tier": "free",
"quota": {
"limit": 250,
"remaining": 237,
"reset_at": "2026-05-03T00:00:00.000Z"
}
}
}
The shape of data depends on the endpoint — usually an array for searches,
an object for profiles. Array endpoints set meta.count to the array length.
Errors
Errors are RFC 7807 problem+json:
{
"type": "https://www.govgreed.com/docs/errors/daily-quota-exceeded",
"title": "Daily quota exceeded",
"status": 429,
"detail": "Tier 'free' is capped at 250 calls/day per key. Resets at 00:00 UTC.",
"instance": "/api/v1/donors/search",
"code": "DAILY_QUOTA_EXCEEDED",
"request_id": "req_abc123def4"
}
Common codes
| Code | HTTP | Meaning |
|---|---|---|
MISSING_API_KEY | 401 | No Authorization or X-API-Key header. |
INVALID_API_KEY_FORMAT | 401 | Key doesn't match gg_pub_[hex]{32+}. |
INVALID_API_KEY | 401 | Hash not found. |
KEY_REVOKED | 403 | Key was revoked. |
BURST_LIMIT_EXCEEDED | 429 | >5 req/sec on this key. |
DAILY_QUOTA_EXCEEDED | 429 | Daily cap hit. Retry-After: 3600. |
BAD_REQUEST | 400 | Missing/invalid query params. |
NOT_FOUND | 404 | Resource doesn't exist (or unknown route). |
INTERNAL_ERROR | 500 | Backend RPC failed. request_id for support. |
Endpoints
curl https://www.govgreed.com/api/v1/status
/atlas/{table} for one entity's details.curl -H "Authorization: Bearer $KEY" https://www.govgreed.com/api/v1/atlas
| Param | Type | Required | Notes |
|---|---|---|---|
q | string | yes | Donor name (any format). |
limit | int | no | Default 25, max 100. |
curl -H "Authorization: Bearer $KEY" \
"https://www.govgreed.com/api/v1/donors/search?q=mercer&limit=10"
{name} must be the URL-encoded name_display from search_donors
— usually LASTNAME%2C%20FIRSTNAME.
curl -H "Authorization: Bearer $KEY" \
"https://www.govgreed.com/api/v1/employers/search?q=renaissance"
{bioguide_id} = one uppercase letter + 6 digits (e.g. P000197 for Pelosi).
| Param | Type | Notes |
|---|---|---|
q | string | Optional name filter. |
limit | int | Default 25, max 100. |
| Param | Type | Notes |
|---|---|---|
q | string | Required, min 2 chars. |
limit | int | Default 25, max 100. |
curl -H "Authorization: Bearer $KEY" \
"https://www.govgreed.com/api/v1/politicians/search?q=pelosi"
curl -H "Authorization: Bearer $KEY" \
https://www.govgreed.com/api/v1/politicians/P000197/profile
{bill_number} is the dotted form: HR.4521, S.5, HJRES.7.
curl -H "Authorization: Bearer $KEY" \
https://www.govgreed.com/api/v1/bills/HR.4420
| Param | Type | Notes |
|---|---|---|
congress | int | Optional (117/118/119). Defaults to most recent. |
| Param | Type | Notes |
|---|---|---|
congress | int | Optional. Defaults to most recent. |
max_trades | int | Cap on trade events. Default 200. |
min_impact_ratio | float | 0–1. Filter trades by ticker impact ratio. Default 0.02. |
| Param | Type | Notes |
|---|---|---|
days | int | Lookback window. Default 90, min 7, max 365. |
| Param | Type | Notes |
|---|---|---|
congress | int | 117/118/119. Default 119. |
duplicate_count exposes how many raw extractions agreed. Example: LMT returns ~$9B canonical carveouts (F-35 $4.3B, Sikorsky $3.6B, UH-60 $630M, Apache $504M).curl -H "Authorization: Bearer $KEY" \
https://www.govgreed.com/api/v1/companies/LMT/llm-analysis
| Param | Type | Notes |
|---|---|---|
tier | string | Min tier: S, A+, A, B, C, D, F. Default B. |
limit | int | Default 25, max 100. |
fresh | bool | Only freshness-flagged. Default true. |
| Param | Type | Notes |
|---|---|---|
tier | string | Optional minimum herd_tier filter. |
days | int | Lookback window. Default 90, max 365. |
limit | int | Default 25, max 100. |
| Param | Type | Notes |
|---|---|---|
tier | string | Min tier. Default A. |
status | string | ACTIVE / DARK_WINDOW / CONFIRMED / MISSED / EXPIRED. Default ACTIVE. |
limit | int | Default 25, max 100. |
| Param | Type | Notes |
|---|---|---|
congress | int | Default 119. |
min_pass_pct | int | 0-100. Default 40. |
min_impact_ratio | float | 0-1. Default 0.05. |
limit | int | Default 25, max 100. |
Sector match is case-insensitive against companies.sector (Technology, Healthcare, Energy, Financial Services, etc).
| Param | Type | Notes |
|---|---|---|
days | int | Lookback. Default 30, max 365. |
| Param | Type | Notes |
|---|---|---|
q | string | Free-text on description / organization / citation. |
status | string | e.g. Confirmed, Returned, Withdrawn. |
congress | int | 117/118/119. |
limit | int | Default 25, max 100. |
| Param | Type | Notes |
|---|---|---|
q | string | Required, min 2 chars. |
subsection | int | 3, 4, 5, 6, 19, or 527. |
state | string | 2-letter code. |
political | bool | Filter to political nonprofits only. |
| Param | Type | Notes |
|---|---|---|
ticker | string | Stock ticker. |
agency | string | Awarding agency fuzzy match. |
min_amount | number | Minimum award_amount in USD. |
limit | int | Default 50, max 200. |
| Param | Type | Notes |
|---|---|---|
series | string | Comma-separated series IDs. |
start | date | ISO date. |
/districts/CA/11/demographics for Pelosi's CA-11.| Param | Type | Notes |
|---|---|---|
days | int | Default 30, max 90. |
MCP Server
The same API ships as a local Model Context Protocol server, so AI agents (Claude Desktop, Cline, Cursor) can investigate political accountability with one tool installation. Distributed via Node + STDIO transport for v1 — hosted SSE later.
Install
git clone https://github.com/mmamodelai/govgreed-mcp ~/.local/govgreed-mcp
cd ~/.local/govgreed-mcp && npm install
(For the closed beta, the same code lives at ~/.claude/mcp-servers/govgreed/
if you got it directly from us.)
Wire it into Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"govgreed": {
"command": "node",
"args": ["/absolute/path/to/govgreed-mcp/index.js"],
"env": {
"GOVGREED_API_KEY": "gg_pub_..."
}
}
}
}
Restart Claude Desktop. You should see a govgreed tool icon in the chat composer.
Tools exposed
43 tools, 1-to-1 with the REST endpoints above:
search_donorsget_donor_profilesearch_employersget_employer_profilesearch_politiciansget_politicianget_politician_profileget_politician_conflict_scoreget_politician_committeessearch_politician_donorsget_billget_bill_pass_likelihoodget_bill_carveoutsget_bill_timelineget_bill_votesget_companyget_company_political_influenceget_company_insider_signalget_company_llm_analysisget_company_carveoutsget_company_contractsget_company_forecastget_top_signalsget_herd_signalsget_top_predictionsget_whale_opportunitiesget_sector_positioningsearch_nominationsget_nominationsearch_nonprofitsget_nonprofit_profileget_government_contractsget_government_equity_stakessearch_oge_officialsget_oge_official_profilesearch_fara_registrantsget_fred_indicatorsget_eia_indicatorsget_kalshi_marketsget_vessel_eventsget_district_demographicsget_atlasget_my_account
Example prompt
Claude will call search_donors, then get_donor_profile on the
best match — without you orchestrating.
SDKs
Official SDKs are not shipped yet. The API is small enough that a tiny wrapper is trivial. Reference implementations:
Python (~30 lines)
import os, urllib.parse, urllib.request, json
BASE = "https://www.govgreed.com/api/v1"
KEY = os.environ["GOVGREED_API_KEY"]
def gg(path, **params):
url = f"{BASE}{path}"
if params:
url += "?" + urllib.parse.urlencode({k:v for k,v in params.items() if v is not None})
req = urllib.request.Request(url, headers={"Authorization": f"Bearer {KEY}"})
with urllib.request.urlopen(req) as r:
return json.loads(r.read())["data"]
print(gg("/donors/search", q="mercer", limit=5))
print(gg("/bills/HR.4420")["title"])
TypeScript / Node
const BASE = "https://www.govgreed.com/api/v1";
const KEY = process.env.GOVGREED_API_KEY!;
async function gg<T>(path: string, params?: Record<string, unknown>): Promise<T> {
const url = new URL(BASE + path);
for (const [k, v] of Object.entries(params || {})) if (v != null) url.searchParams.set(k, String(v));
const r = await fetch(url, { headers: { Authorization: `Bearer ${KEY}` } });
if (!r.ok) throw new Error((await r.json()).title);
return (await r.json()).data;
}
console.log(await gg("/donors/search", { q: "mercer", limit: 5 }));
OpenAPI spec
OpenAPI 3.1 spec at /api/v1/openapi.
Drop into Swagger Editor or
Insomnia to explore interactively.
Changelog
v1.6.0 — 2026-05-03 (insider awards + ticker carveouts)
/companies/{ticker}/insider-signalnow returns 5 new fields:award_count,award_total_value,exercise_count,exercise_total_value,recent_awards. Defense primes (LMT/RTX/NOC/GD/BA) where execs receive comp via stock awards (not open-market buys) finally surface real activity. Grant values estimated via daily_prices.close JOIN.- NEW
/companies/{ticker}/carveouts+ MCPget_company_carveouts— bill carveouts targeting one ticker, deduplicated server-side on (bill_number, purpose, recipient). Highest-confidence LLM extraction wins. Example: LMT returns ~$9B canonical pork (F-35 $4.3B, Sikorsky $3.6B, etc). - MCP server: 42 → 43 tools.
- Backend cleanup:
hedge_fund_holdingsx1000 unit bug fixed (14,892 rows).campaign_contributionstable quarantined (OpenFEC API silently ignored candidate_id, mis-attributing rows to wrong politicians; replacement:fec_pac_contributions+fec_individual_contributionsvia FEC bulk).
v1.5.0 — 2026-05-02 (quota recalibration)
- Free tier daily quota: 2,500 → 250 calls/day (10x reduction). Real usage in heavy founder testing was <100/day.
- Paid tier daily quota: 25,000 → 2,500 calls/day (10x reduction). Still 50+ MCP-questions/day for power users.
- Burst limit: 10 → 5 req/sec per key. Normal interactive + AI agent usage unaffected; slows scrapers.
- Need more headroom? Email team@mmamodel.ai.
v1.4.0 — 2026-05-02 (Phase C — context layer)
- FARA:
/fara/registrants/search— foreign agent registrations. - Macro:
/macro/fred(17 series),/macro/eia(6 petroleum series). - Markets:
/markets/kalshi— live prediction markets with our BPI overlay (edge_pp + signal_side). - Vessels:
/vessels/chokepoints— AIS chokepoint vessel events. - Districts:
/districts/{state}/{district}/demographics— Census ACS per congressional district. - MCP server bumped 36 → 42 tools.
v1.3.0 — 2026-05-02 (Phase B — fresh data exposure)
- Senate confirmations:
/nominations/search,/nominations/{c}/{n}— 6,727 nominations across 117/118/119. - Nonprofits / dark money:
/nonprofits/search,/nonprofits/{ein}— 40K orgs from ProPublica Nonprofit Explorer (501c3/4/5/6/19/527). - Federal contracts:
/government-contracts,/companies/{ticker}/contracts— 39K ticker-mapped USASpending awards. - Government equity stakes:
/government-equity-stakes— Trump-era CHIPS / DoD / Commerce deals into public companies, with announcement-window price reaction. - Cabinet conflicts (OGE):
/oge/officials,/oge/officials/{slug}— Trump cabinet + senior WH staff + 32 holders + financial disclosures + conflict flags. - Per-ticker forecasts:
/companies/{ticker}/forecast— LLM 30-day politician trade forecasts with catalyst bills + historical precedent. - MCP server bumped 26 → 36 tools.
v1.2.0 — 2026-05-02 (Phase A — flagship + foundational)
- Flagship signals on the API:
/signals/top,/herd-signals,/predictions/top,/whale-opportunities,/sectors/{sector}/positioning. - Foundational lookups:
/politicians/search(no more guessing P000197 = Pelosi),/politicians/{id}/committees,/bills/{n}/votes. - MCP server bumped 18 → 26 tools.
- Bug fix:
/donors/searchnow filters out JFC / PAC / leadership committee names that leaked in via refund flows.
v1.1.0 — 2026-05-02 (synthesis layer)
- +5 endpoints surfacing intelligence we'd already computed: bill carveouts, bill timeline, politician profile, politician conflict score, company LLM analysis.
- MCP server bumped 13 → 18 tools.
- Bug fix:
/companies/{ticker}/insider-signaldropped legacytierfield (usesignal_tier). - Bug fix:
/bills/{n}and/bills/{n}/pass-likelihoodnow agree on Congress (defaults to 119, override with?congress=). - Bug fix:
/bills/{n}/timelineoverload-disambiguation (was returning 300 PGRST203).
v1.0.0 — 2026-05-02
- Initial closed-beta launch.
- 16 endpoints across 5 entity domains (donors, employers, politicians, bills, companies).
- Local STDIO MCP server with 13 tools.
- 2,500/day free tier, 25,000/day paid. (Recalibrated 2026-05-02 to 250/2,500.)
- 10 req/sec burst limit per key. (Recalibrated 2026-05-02 to 5 req/sec.)
- RFC 7807 problem+json error format.
Questions? team@mmamodel.ai ·
Service status: /api/v1/status ·
Pricing: /founders