The EODHD Congressional Trades API returns stock-trade disclosures filed by members of the US Congress. Under the STOCK Act, senators and representatives must publicly disclose their securities transactions within 45 days.
Each record pairs the trading member with the traded asset and the transaction, and adds fields the raw filings do not provide directly: numeric bounds parsed from the disclosed amount range, the number of days between the trade and its disclosure, a flag for filings that missed the 45-day window, and a link back to the original filing for verification.
Overview
The endpoint is reached over HTTPS with a GET request and authenticated by an api_token query parameter, the same token used across the EODHD API. It returns a JSON object with three top-level keys: data (the array of trade records), meta (the total row count for the current filter and the active page window), and links (the URL of the next page, when one exists). Results are paged with page[offset] and page[limit], where the default page size is 20 rows and the maximum is 100.
https://eodhd.com/api/congressional-trades?api_token=YOUR_TOKEN
Filter parameters are passed as flat query keys, for example chamber=senate and transaction_type=purchase,sale. Only the two pagination parameters use bracket notation: page[offset] and page[limit]. Every value is validated at the gateway, so an invalid value returns HTTP 422 before the request reaches the data service.
Request
All parameters are optional except api_token. Filters combine with logical AND, and the member, date-range, symbol, and transaction-type filters can be used together to narrow the result set.
Parameters
api_token
string
required
symbol
string
optional
chamber
enum
optional
bioguide_id
string
optional
transaction_type
enum
optional
transaction_date_from
date
optional
transaction_date_to
date
optional
disclosure_date_from
date
optional
disclosure_date_to
date
optional
page[limit]
integer
optional
page[offset]
integer
optional
Request Example
https://eodhd.com/api/congressional-trades?api_token=YOUR_TOKEN&chamber=senate&transaction_type=purchase,sale&transaction_date_from=2026-01-01&page[limit]=5
curl --location "https://eodhd.com/api/congressional-trades?api_token=YOUR_TOKEN&chamber=senate&transaction_type=purchase,sale&transaction_date_from=2026-01-01&page[limit]=5&fmt=json"
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://eodhd.com/api/congressional-trades?api_token=YOUR_TOKEN&chamber=senate&transaction_type=purchase,sale&transaction_date_from=2026-01-01&page[limit]=5&fmt=json',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$data = curl_exec($curl);
curl_close($curl);
try {
$data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
var_dump($data);
} catch (Exception $e) {
echo 'Error. '.$e->getMessage();
}
import requests
url = f'https://eodhd.com/api/congressional-trades?api_token=YOUR_TOKEN&chamber=senate&transaction_type=purchase,sale&transaction_date_from=2026-01-01&page[limit]=5&fmt=json'
data = requests.get(url).json()
print(data)
library(httr)
library(jsonlite)
url <- 'https://eodhd.com/api/congressional-trades?api_token=YOUR_TOKEN&chamber=senate&transaction_type=purchase,sale&transaction_date_from=2026-01-01&page[limit]=5&fmt=json'
response <- GET(url)
if (http_type(response) == "application/json") {
content <- content(response, "text", encoding = "UTF-8")
cat(content)
} else {
cat("Error while receiving data\n")
}
Try it now (it's free)!
How to use it (YouTube)
Response
Each record carries a top-level chamber field and four nested objects: member, asset, transaction, and source. The example below is a single record; a real response returns an array under data.
Response Example
{
"data": [
{
"chamber": "senate",
"member": {
"bioguide_id": "W000802",
"first_name": "Sheldon",
"last_name": "Whitehouse",
"full_name": "Sheldon Whitehouse",
"office": "Whitehouse, Sheldon (Senator)",
"state": null,
"party": null,
"district": null
},
"asset": {
"symbol": "NVDA",
"description": "NVIDIA Corporation - Common Stock",
"asset_type": "Stock"
},
"transaction": {
"type": "sale",
"transaction_date": "2026-06-30",
"disclosure_date": "2026-07-08",
"owner": "Self",
"amount_range": "$15,001 - $50,000",
"amount_low": 15001,
"amount_high": 50000,
"days_to_disclose": 8,
"is_late": false,
"comment": null
},
"source": {
"filing_url": "https://efdsearch.senate.gov/search/view/ptr/5d9b1b8e-2ae1-442b-860c-e79b8a701dc6/",
"source_system": "senate",
"filing_identifier": "5d9b1b8e-2ae1-442b-860c-e79b8a701dc6"
}
}
],
"meta": { "total": 44604, "page": { "offset": 0, "limit": 20 } },
"links": { "next": "https://eodhd.com/api/congressional-trades?page[offset]=20&page[limit]=20" }
}
Response Fields
| Field | Type | Description |
|---|---|---|
| chamber | string | Chamber of Congress: senate or house |
| member.bioguide_id | string or null | Congressional Biographical Directory identifier, when matched |
| member.first_name | string | Member first name |
| member.last_name | string | Member last name |
| member.full_name | string | Member full name as filed |
| member.office | string or null | Office label as it appears in the source filing |
| member.state | string or null | Two-letter US state code, when available |
| member.party | string or null | Political party, when available |
| member.district | number or null | House district number. Null for senators |
| asset.symbol | string or null | Ticker symbol, when the asset maps to a listed instrument. Null for assets without a ticker, such as many bonds |
| asset.description | string | Asset description as filed |
| asset.asset_type | string | Normalised asset class, for example Stock, Bond, or Other |
| transaction.type | string | Transaction type: purchase, sale, or exchange |
| transaction.transaction_date | string (date) | Date the trade took place, YYYY-MM-DD |
| transaction.disclosure_date | string (date) | Date the trade was disclosed, YYYY-MM-DD |
| transaction.owner | string or null | Account owner: Self, Spouse, or Joint |
| transaction.amount_range | string | Disclosed transaction amount band, as filed, for example $1,001 – $15,000 |
| transaction.amount_low | number or null | Lower bound of the amount range, in US dollars |
| transaction.amount_high | number or null | Upper bound of the amount range, in US dollars |
| transaction.days_to_disclose | number | Days between transaction_date and disclosure_date |
| transaction.is_late | boolean | True when the filing missed the 45-day STOCK Act disclosure window |
| transaction.comment | string or null | Free-text note from the filing, when present |
| source.filing_url | string | Link to the original filing on the official government portal |
| source.source_system | string | Origin of the filing: senate or house |
| source.filing_identifier | string | Identifier of the filing at the source system |
Response Codes
| Code | Meaning |
|---|---|
| 200 | Success. Response body carries data, meta, and links |
| 401 | Missing or invalid api_token |
| 403 | Token is valid but the plan does not include Congressional Trades |
| 422 | Invalid parameter — malformed date, page[limit] above 100 or below 1, end date before start date, an unknown chamber or transaction type, or a malformed symbol or bioguide_id |
Notes and Limitations
- Both chambers are returned together. Use chamber=senate or chamber=house to restrict to one; the chamber field on each record identifies its origin.
- Filters are passed as flat query keys such as chamber=senate and transaction_type=purchase,sale, not as filter[…] keys. Only pagination uses brackets: page[offset] and page[limit].
- The amount_low and amount_high fields are parsed from the disclosed amount band; days_to_disclose and is_late are computed against the 45-day STOCK Act window. These are provided by EODHD and are not part of the raw filing.
- Some holdings, including many bonds and other instruments, carry no ticker symbol. For those records asset.symbol is null while asset.description and asset.asset_type remain populated.
- Source data is reproduced as filed. Member details such as party and state are populated only where the source provides them, and occasional data-entry errors in the original disclosures, such as an implausible transaction date, are passed through rather than silently corrected. The filing_url on each record links to the official source for verification.
- Filings are polled from the official Senate EFD and House Clerk portals several times a day, with a nightly reconciliation pass. New disclosures appear after the source publishes them.