Politicians Trading API
Track congressional STOCK Act trading disclosures: purchases, sales, and exercises by U.S. Senators and Representatives. Updated daily from official filings.
Overview
The Politicians Trading API provides access to congressional STOCK Act trading disclosures. Under the STOCK Act (2012), members of the U.S. Senate and House of Representatives must publicly disclose securities transactions within 45 days. This data reveals what elected officials are buying and selling in their personal portfolios.
Use cases:
- Track which stocks members of Congress are buying and selling
- Filter by chamber (Senate vs House), party, or state
- Identify stocks with heavy congressional interest
- Cross-reference politician trades with insider trading (Form 4) and institutional flows (13F)
- Build quantitative strategies based on congressional trading data
Chambers: SENATE, HOUSE.
Transaction types: PURCHASE, SALE, EXCHANGE, OTHER.
Asset types: Stock, ETF, Stock Option. Other asset classes that appear on filings (bonds, mutual funds) are currently excluded from API responses.
Ownership types: Self, Spouse, Child, Joint.
Amount ranges: STOCK Act disclosures report dollar amounts as ranges (e.g., "$1,001 - $15,000"), not exact values. The API returns the raw range string plus parsed amountMin and amountMax fields.
Access: All endpoints require an API key. PRO subscribers get the full data; FREE-tier callers receive a limited preview with isPreview: true in the response.
Migrating from a bulk JSON dump of congressional filings? Endpoint-by-endpoint mapping: the migration guide.
GET /activity
Returns recent congressional trading activity across all politicians, sorted by disclosure date (most recently disclosed first), falling back to transaction date when a disclosure date is absent. Each entry is a single STOCK Act disclosure record. Note that "recent" means recently disclosed, not recently traded: a filing can disclose a transaction made up to 45 days earlier, so a trade with an older transactionDate can appear at the top when its disclosureDate is fresh.
Authentication: PRO required. Free users receive a preview of the top 5 trades.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
lookbackDays |
integer | No | 90 | Size of the trailing window, applied to the disclosure date. Must be between 1 and 365 (inclusive); returns 400 otherwise |
limit |
integer | No | 200 | Rows per page. Values above 500 are clamped to 500 rather than rejected; a value below 1 returns 400 invalid_limit |
offset |
integer | No | 0 | Rows to skip, for paging through the window. A negative value returns 400 invalid_offset |
Example Request:
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/politicians/activity?lookbackDays=90&limit=50&offset=0"
from sentisense import SentiSenseClient
client = SentiSenseClient(api_key="ss_live_YOUR_KEY")
activity = client.get_politician_activity(lookback_days=90)
for trade in activity.data:
print(f"{trade['politicianName']} ({trade['party']}-{trade['state']}): {trade['transactionType']} {trade['ticker']} {trade['amountRange']}")
Response Schema:
| Field | Type | Description |
|---|---|---|
isPreview |
boolean | true when response is limited (FREE tier) |
previewReason |
string | "PRO_REQUIRED" or null |
totalCount |
integer | Size of the whole window, not of the page. offset + data.length < totalCount means there is another page |
upgrade |
object | Present only when isPreview is true. Carries plan, message, price, url and relay: surface message and url to your user in one line, then continue with the preview data |
data |
array | Array of trade objects (see below) |
Trade object:
| Field | Type | Description |
|---|---|---|
politicianName |
string | Full name (e.g., "Nancy Pelosi") |
firstName |
string | First name |
lastName |
string | Last name |
chamber |
string | SENATE or HOUSE |
party |
string | Political party (e.g., "Democrat", "Republican") |
state |
string | Two-letter state code (e.g., "CA") |
bioguideId |
string | Official Bioguide identifier |
imageUrl |
string | URL to politician's headshot image |
ticker |
string | Stock ticker symbol |
assetDescription |
string | Security description from filing |
assetType |
string | Stock, ETF, or Stock Option |
assetMetadata |
object | Structured asset detail, or null for plain stocks and ETFs. Discriminated by kind. For options: { "kind": "OPTION", "optionType": "CALL" or "PUT", "strikePrice": number, "expirationDate": "YYYY-MM-DD" } |
transactionType |
string | PURCHASE, SALE, EXCHANGE, or OTHER |
transactionDate |
string | Date of the transaction (ISO format) |
disclosureDate |
string | Date the disclosure was filed |
disclosureDelayDays |
int | Days between transaction and disclosure |
amountRange |
string | Raw STOCK Act range (e.g., "$1,001 - $15,000") |
amountMin |
long | Minimum dollar amount of the range |
amountMax |
long | Maximum dollar amount of the range |
owner |
string | Who made the trade: Self, Spouse, Child, or Joint |
urlSlug |
string | Politician's URL slug for /member/{slug} lookup |
sentiSenseScore |
double|null | Reserved for the politician's sentiment reading; currently always null |
Example Response:
{
"isPreview": false,
"previewReason": null,
"data": [
{
"politicianName": "Nancy Pelosi",
"firstName": "Nancy",
"lastName": "Pelosi",
"chamber": "HOUSE",
"party": "Democrat",
"state": "CA",
"bioguideId": "P000197",
"imageUrl": "https://sentisense-image-gallery.s3.us-east-2.amazonaws.com/politicians/P000197.jpg",
"ticker": "NVDA",
"assetDescription": "NVIDIA Corporation",
"assetType": "Stock",
"transactionType": "PURCHASE",
"transactionDate": "2026-03-15",
"disclosureDate": "2026-03-28",
"disclosureDelayDays": 13,
"amountRange": "$500,001 - $1,000,000",
"amountMin": 500001,
"amountMax": 1000000,
"owner": "Spouse",
"urlSlug": "Nancy-Pelosi"
},
{
"politicianName": "Nancy Pelosi",
"firstName": "Nancy",
"lastName": "Pelosi",
"chamber": "HOUSE",
"party": "Democrat",
"state": "CA",
"bioguideId": "P000197",
"imageUrl": "https://sentisense-image-gallery.s3.us-east-2.amazonaws.com/politicians/P000197.jpg",
"ticker": "NVDA",
"assetDescription": "NVIDIA Corporation - Call Options",
"assetType": "Stock Option",
"assetMetadata": {
"kind": "OPTION",
"optionType": "CALL",
"strikePrice": 50,
"expirationDate": "2026-12-18"
},
"transactionType": "PURCHASE",
"transactionDate": "2026-03-15",
"disclosureDate": "2026-03-28",
"disclosureDelayDays": 13,
"amountRange": "$1,000,001 - $5,000,000",
"amountMin": 1000001,
"amountMax": 5000000,
"owner": "Spouse",
"urlSlug": "Nancy-Pelosi"
}
]
}
FREE tier: same shape with isPreview: true, previewReason: "PRO_REQUIRED", and data truncated to top 5.
GET /filings/{ticker}
Returns congressional trades for a specific stock, sorted by disclosure date (most recently disclosed first), falling back to transaction date when a disclosure date is absent. Use this to see which politicians have been buying or selling a particular ticker.
Authentication: PRO required. Free users receive a preview of the top 3 trades.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
ticker |
path | Yes | - | Stock ticker symbol (e.g., AAPL) |
lookbackDays |
integer | No | 90 | Size of the trailing window, applied to the disclosure date. Must be between 1 and 365 (inclusive); returns 400 otherwise |
Example Request:
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/politicians/filings/NVDA?lookbackDays=180"
filings = client.get_politician_filings("NVDA", lookback_days=180)
for f in filings.data:
print(f"{f['politicianName']}: {f['transactionType']} {f['amountRange']} on {f['transactionDate']}")
Response: Same preview wrapper and trade object schema as /activity.
GET /directory
Discover every tracked member of Congress and the page slug that identifies them, so you can find what is worth querying without knowing slugs upfront. Summary only: this endpoint returns no trade data. Use GET /member/{slug} for a member's filings.
Unlike /members, the directory includes members who have left Congress. That roster lists who currently holds office; this lists who we track. Former members carry former: true and the year they left, and are otherwise reachable only if you already know their slug.
Authentication: API key required. Not tier-gated, so FREE and PRO callers receive the same full response. Does not count against your monthly request quota.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q |
string | No | - | Case-insensitive filter across display name, state and slug (max 100 chars) |
limit |
integer | No | 50 | Results per page (max 200) |
offset |
integer | No | 0 | Results to skip, for paging |
Example Request:
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/politicians/directory?q=pelosi&limit=5"
directory = client.get_politician_directory(q="pelosi", limit=5)
for m in directory["members"]:
seat = "Former " if m["former"] else ""
print(f"{m['displayName']} ({m['party']}-{m['state']}) {seat}{m['chamber']} -> /member/{m['urlSlug']}")
Response Schema:
| Field | Type | Description |
|---|---|---|
data.members |
array | Array of directory entries (see below) |
data.totalCount |
integer | Size of the whole matched set. offset + members.length < totalCount means another page |
Directory entry object:
| Field | Type | Description |
|---|---|---|
urlSlug |
string | URL-friendly identifier (use with /member/{slug}) |
displayName |
string | Full display name |
chamber |
string | "SENATE" or "HOUSE" |
party |
string | Political party |
state |
string | Two-letter state code |
bioguideId |
string | Official Congressional Biographical Directory id |
imageUrl |
string | Official portrait URL, or null |
former |
boolean | true for a member who has left Congress |
servedUntil |
string | Year the member left, e.g. "2021". null for a sitting member |
Example Response:
{
"data": {
"members": [
{
"urlSlug": "Nancy-Pelosi",
"displayName": "Nancy Pelosi",
"chamber": "HOUSE",
"party": "Democrat",
"state": "CA",
"bioguideId": "P000197",
"imageUrl": "https://sentisense-image-gallery.s3.us-east-2.amazonaws.com/politicians/P000197.jpg",
"former": false,
"servedUntil": null
}
],
"totalCount": 1
}
}
GET /members
Returns all tracked politicians with trading summary statistics, sorted by total trade count (most active first).
Authentication: PRO required. Free users receive a preview of the top 5 members.
Parameters: None.
Example Request:
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/politicians/members"
members = client.get_politician_members()
for m in members.data:
print(f"{m['displayName']} ({m['party']}-{m['state']}): {m['totalTrades']} trades ({m['purchaseCount']} buys, {m['saleCount']} sells)")
Response Schema:
| Field | Type | Description |
|---|---|---|
isPreview |
boolean | true when response is limited |
previewReason |
string | "PRO_REQUIRED" or null |
upgrade |
object | Present only when isPreview is true. Carries plan, message, price, url and relay: surface message and url to your user in one line, then continue with the preview data |
data |
array | Array of politician summary objects (see below) |
Politician summary object:
| Field | Type | Description |
|---|---|---|
urlSlug |
string | URL-friendly identifier (use with /member/{slug}) |
displayName |
string | Full display name |
firstName |
string | First name |
lastName |
string | Last name |
chamber |
string | SENATE or HOUSE |
party |
string | Political party |
state |
string | Two-letter state code |
bioguideId |
string | Official Bioguide identifier |
imageUrl |
string | URL to headshot image |
totalTrades |
int | Total number of disclosed trades |
purchaseCount |
int | Number of purchase transactions |
saleCount |
int | Number of sale transactions |
latestTradeDate |
string | Date of most recent trade |
kbEntityId |
string|null | Internal ontology entity ID |
sentiSenseScore |
double|null | Reserved for the politician's sentiment reading; currently always null |
GET /member/{slug}
Returns a detailed profile for a single politician, including their summary statistics, recent trades, and most-traded tickers.
Authentication: PRO required. Free users receive a preview-wrapped response.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
slug |
path | Yes | - | Politician URL slug (e.g., Nancy-Pelosi). Get slugs from /members |
limit |
integer | No | 200 | Trades per page in recentTrades. Values above 500 are clamped to 500 rather than rejected; a value below 1 returns 400 invalid_limit |
offset |
integer | No | 0 | Trades to skip, for paging through the member's history. A negative value returns 400 invalid_offset |
Note: slugs are Capitalized-Hyphenated (derived from the politician's name with case preserved, e.g.
Nancy-Pelosi) and the lookup is case-sensitive:nancy-pelosireturns 404.
Paging:
recentTradesis one page of the member's history, newest transaction first, not the entire history. Most members disclose a few dozen trades and arrive complete in the default page; a handful have disclosed thousands. ReadtotalCountto size the whole history rather than treatingrecentTrades.lengthas the total.profileandtopTickersalways describe the whole history regardless of the page requested, soprofile.totalTradesdoes not shrink when you pass a smalllimit.
Example Request:
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/politicians/member/Nancy-Pelosi?limit=50&offset=0"
detail = client.get_politician_member("Nancy-Pelosi", limit=50)
profile = detail.data["profile"]
print(f"{profile['displayName']} - {profile['totalTrades']} trades")
for trade in detail.data["recentTrades"]:
print(f" {trade['transactionDate']}: {trade['transactionType']} {trade['ticker']} {trade['amountRange']}")
# Walk the rest of the history
offset = 50
while offset < detail.total_count:
page = client.get_politician_member("Nancy-Pelosi", limit=50, offset=offset)
offset += len(page.data["recentTrades"])
Response Schema:
| Field | Type | Description |
|---|---|---|
isPreview |
boolean | true when response is limited |
previewReason |
string | "PRO_REQUIRED" or null |
totalCount |
integer | Trades in the member's whole history, not in the page. offset + data.recentTrades.length < totalCount means there is another page |
upgrade |
object | Present only when isPreview is true. Carries plan, message, price, url and relay: surface message and url to your user in one line, then continue with the preview data |
data |
object | Politician detail object (see below) |
Politician detail object:
| Field | Type | Description |
|---|---|---|
profile |
object | Politician summary (same schema as /members entries), describing the whole history |
recentTrades |
array | One page of trade objects, newest transaction first (same schema as /activity entries) |
topTickers |
array | Most-traded ticker symbols (strings) across the whole history |
Example Response:
{
"isPreview": false,
"previewReason": null,
"totalCount": 42,
"data": {
"profile": {
"urlSlug": "Nancy-Pelosi",
"displayName": "Nancy Pelosi",
"chamber": "HOUSE",
"party": "Democrat",
"state": "CA",
"bioguideId": "P000197",
"imageUrl": "https://sentisense-image-gallery.s3.us-east-2.amazonaws.com/politicians/P000197.jpg",
"totalTrades": 42,
"purchaseCount": 28,
"saleCount": 14,
"latestTradeDate": "2026-03-15"
},
"recentTrades": [
{
"ticker": "NVDA",
"transactionType": "PURCHASE",
"transactionDate": "2026-03-15",
"amountRange": "$500,001 - $1,000,000",
"owner": "Spouse"
}
],
"topTickers": ["NVDA", "AAPL", "MSFT", "GOOG", "AMZN"]
}
}
Try It
Test endpoints directly from your browser. Paste your API key once: it's saved locally and shared across all widgets. Get a free key
GET/api/v1/politicians/activity
Recent congressional trades across all politicians
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/politicians/activity"GET/api/v1/politicians/filings/{ticker}
Congressional trades for a specific stock
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/politicians/filings/AAPL"GET/api/v1/politicians/directory
Discover every tracked member and their page slug
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/politicians/directory"GET/api/v1/politicians/members
All tracked politicians with trading summaries
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/politicians/members"