Congressional Trading API
Retrieve stock trading activity from US House Representatives and Senators disclosed under the STOCK Act. House and Senate trades are served by separate endpoints with an identical schema.
Endpoints
Section titled “Endpoints”GET /v2/congress/house/{symbol}GET /v2/congress/senate/{symbol}Authentication
Section titled “Authentication”The API supports multiple authentication methods:
| Method | Example |
|---|---|
| Bearer token (recommended) | Authorization: Bearer YOUR_API_KEY |
| X-API-Key header | X-API-Key: YOUR_API_KEY |
| Query parameter | ?apiKey=YOUR_API_KEY |
| Legacy query parameter | ?token=YOUR_API_KEY |
Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
symbol |
string | Yes | Stock ticker symbol (e.g., AAPL, NVDA) |
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
startDate |
string | No | Start date (YYYY-MM-DD) |
endDate |
string | No | End date (YYYY-MM-DD) |
limit |
integer | No | Maximum number of results to return |
startDate and endDate filter on the transaction date, not on disclosureDate. A trade executed inside the window is returned even if it was disclosed after endDate.
Request
Section titled “Request”from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
house_df = fb.house_trades.ticker("NVDA", date_from="2025-01-01", date_to="2025-06-30", as_dataframe=True)senate_df = fb.senate_trades.ticker("NVDA", date_from="2025-01-01", date_to="2025-06-30", as_dataframe=True)print(house_df)print(senate_df)curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.finbrain.tech/v2/congress/house/AAPL"
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.finbrain.tech/v2/congress/senate/AAPL"import requests
headers = {"Authorization": "Bearer YOUR_API_KEY"}
for chamber in ["house", "senate"]: response = requests.get( f"https://api.finbrain.tech/v2/congress/{chamber}/AAPL", headers=headers, params={"limit": 10} ) data = response.json()
for t in data["data"]["trades"]: disclosed = t["disclosureDate"] or "not disclosed" print(f"{t['date']} - {t['politician']} ({chamber}): " f"{t['transactionType']} ({t['amount']}) disclosed {disclosed}")#include <iostream>#include <string>#include <curl/curl.h>#include <nlohmann/json.hpp>
using json = nlohmann::json;
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) { userp->append((char*)contents, size * nmemb); return size * nmemb;}
json get_congress_trades(const std::string& chamber, const std::string& symbol, const std::string& api_key) { CURL* curl = curl_easy_init(); std::string response;
if (curl) { std::string url = "https://api.finbrain.tech/v2/congress/" + chamber + "/" + symbol;
struct curl_slist* headers = nullptr; std::string auth_header = "Authorization: Bearer " + api_key; headers = curl_slist_append(headers, auth_header.c_str());
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); curl_easy_perform(curl); curl_slist_free_all(headers); curl_easy_cleanup(curl); }
return json::parse(response);}
int main() { for (const std::string& chamber : {"house", "senate"}) { auto result = get_congress_trades(chamber, "AAPL", "YOUR_API_KEY");
for (auto& t : result["data"]["trades"]) { std::string disclosed = t["disclosureDate"].is_null() ? "not disclosed" : t["disclosureDate"].get<std::string>();
std::cout << t["date"].get<std::string>() << " - " << t["politician"].get<std::string>() << " (" << chamber << "): " << t["transactionType"].get<std::string>() << " (" << t["amount"].get<std::string>() << ")" << " disclosed " << disclosed << std::endl; } }
return 0;}use reqwest::blocking::Client;use serde::Deserialize;use std::error::Error;
#[derive(Debug, Deserialize)]struct CongressTrade { date: String, politician: String, #[serde(rename = "transactionType")] transaction_type: String, amount: String, #[serde(rename = "disclosureDate")] disclosure_date: Option<String>,}
#[derive(Debug, Deserialize)]struct CongressData { symbol: String, name: String, chamber: String, trades: Vec<CongressTrade>,}
#[derive(Debug, Deserialize)]struct CongressTradesResponse { success: bool, data: CongressData,}
fn get_congress_trades(chamber: &str, symbol: &str, api_key: &str) -> Result<CongressTradesResponse, Box<dyn Error>> { let url = format!( "https://api.finbrain.tech/v2/congress/{}/{}", chamber, symbol );
let client = Client::new(); let response: CongressTradesResponse = client .get(&url) .bearer_auth(api_key) .send()? .json()?;
Ok(response)}
fn main() -> Result<(), Box<dyn Error>> { for chamber in ["house", "senate"] { let result = get_congress_trades(chamber, "AAPL", "YOUR_API_KEY")?;
for t in &result.data.trades { let disclosed = t.disclosure_date.as_deref().unwrap_or("not disclosed"); println!("{} - {} ({}): {} ({}) disclosed {}", t.date, t.politician, chamber, t.transaction_type, t.amount, disclosed); } }
Ok(())}for (const chamber of ["house", "senate"]) { const response = await fetch( `https://api.finbrain.tech/v2/congress/${chamber}/AAPL`, { headers: { "Authorization": "Bearer YOUR_API_KEY" } } ); const result = await response.json();
for (const t of result.data.trades) { const disclosed = t.disclosureDate ?? "not disclosed"; console.log(`${t.date} - ${t.politician} (${chamber}): ${t.transactionType} (${t.amount}) disclosed ${disclosed}`); }}Response
Section titled “Response”Success Response (200 OK)
Section titled “Success Response (200 OK)”{ "success": true, "data": { "symbol": "AAPL", "name": "Apple Inc.", "chamber": "house", "trades": [ { "date": "2025-11-24", "politician": "Debbie Dingell", "transactionType": "Sale", "amount": "$50,001 - $100,000", "disclosureDate": "2025-12-16" }, { "date": "2024-03-11", "politician": "Debbie Dingell", "transactionType": "Purchase", "amount": "$1,001 - $15,000", "disclosureDate": null } ] }, "meta": { "timestamp": "2026-01-19T15:06:31.764Z" }}The Senate endpoint returns the same structure with "chamber": "senate".
Response Fields
Section titled “Response Fields”| Field | Type | Description |
|---|---|---|
success |
boolean | Whether the request was successful |
data.symbol |
string | Stock ticker symbol |
data.name |
string | Company name |
data.chamber |
string | Congressional chamber (house or senate) |
data.trades |
array | Array of trade objects |
meta.timestamp |
string | Response timestamp (ISO 8601) |
Trade Object Fields
Section titled “Trade Object Fields”| Field | Type | Description |
|---|---|---|
date |
string | Transaction date (YYYY-MM-DD) |
politician |
string | Name of the House or Senate member |
transactionType |
string | Transaction type (Purchase or Sale) |
amount |
string | Transaction amount (exact value or range) |
disclosureDate |
string or null | Date the trade was publicly disclosed in the periodic transaction report (YYYY-MM-DD). The STOCK Act allows up to 45 days, so this is the correct point-in-time anchor for backtesting. null on historical rows filed before this field was captured |
Amount Ranges
Section titled “Amount Ranges”| Range | Min | Max |
|---|---|---|
| $1,001 - $15,000 | $1,001 | $15,000 |
| $15,001 - $50,000 | $15,001 | $50,000 |
| $50,001 - $100,000 | $50,001 | $100,000 |
| $100,001 - $250,000 | $100,001 | $250,000 |
| $250,001 - $500,000 | $250,001 | $500,000 |
| $500,001 - $1,000,000 | $500,001 | $1,000,000 |
| $1,000,001 - $5,000,000 | $1,000,001 | $5,000,000 |
| Over $5,000,000 | $5,000,001 | N/A |
Errors
Section titled “Errors”| Code | Error | Description |
|---|---|---|
| 400 | Bad Request | Invalid symbol |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | Authenticated, but not authorized to access this resource |
| 404 | Not Found | Ticker not found |
| 429 | Too Many Requests | Rate limit exceeded — wait and retry |
| 500 | Internal Server Error | Server-side error |
Related
Section titled “Related”- Congressional Trading Dataset - Use cases and analysis examples
- Screener API - Screen congressional trades across tickers
- Insider Transactions - SEC Form 4 data
- Price Forecasts - Price forecasts
