# Stock Research Report API: Sentiment, Insider & Congress (`sentisense/stock-research-report`) Actor

One research row per US stock: AI sentiment score, quote, news stories, insider trades, congressional trades and analyst consensus. 10 tickers a run.

- **URL**: https://apify.com/sentisense/stock-research-report.md
- **Developed by:** [SentiSense](https://apify.com/sentisense) (community)
- **Categories:** Business, AI, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$250.00 / 1,000 ticker reports

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Stock Research Report API: Sentiment, Insider & Congress

Everything a first-pass research read needs, in one row per ticker: the sentiment picture, the quote,
the stories moving the name, who inside the company is buying or selling, which members of Congress
traded it, and where Wall Street's price targets sit. Six lookups, one call, one flat dataset row.

**Who it is for**

- Traders screening a watchlist who want smart-money and sentiment context next to the price.
- Analysts building a morning sheet or client report and tired of stitching six sources.
- AI agents doing equity research that need one dense, typed row per ticker instead of six tool calls.

**The six sections**

- **Sentiment**: the daily SentiSense Score with its 30-day regime, direction, trend, mention momentum,
  per-source tone (News, Reddit, X, YouTube, Substack), story drivers and a written narrative.
- **Quote**: price (15-minute delayed), day and 52-week ranges, market cap, P/E, EPS TTM, dividend
  yield, 200-day moving average.
- **Stories**: up to 5 AI-clustered news stories on the ticker, each with tone and an impact score.
- **Insider trades**: up to 5 of the most recent Form 4 transactions in the window, plus the full count.
- **Congressional trades**: up to 3 of the most recently disclosed trades in the window, plus the count.
- **Analyst consensus**: target low, mean, median and high, analyst count, upside, consensus label.

Built by SentiSense, which ingests news, social media, filings and market data all day and distills it
with AI. For a sentiment-only read at a lower price, use the companion actor `stock-sentiment-score`.

Data by [SentiSense](https://sentisense.ai). API docs: [sentisense.ai/docs/api](https://sentisense.ai/docs/api/).

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `tickers` | string\[] | required | US stock symbols, e.g. `["NVDA", "AAPL"]`. Up to 10 per run, case-insensitive, duplicates removed. ETF symbols are accepted and return a smaller, uncharged row (see the FAQ). |
| `lookbackDays` | integer | `90` | Trailing window (1 to 365) for insider and congressional trades. Congress uses the disclosure date. |
| `includeStories` | boolean | `true` | Include the news stories section. |

### Output

One dataset row per ticker. Illustrative row, every value invented, lists shortened:

```json
{
  "ticker": "NVDA", "companyName": "NVIDIA Corporation", "instrumentType": "STOCK",
  "sentiment": {"asOf": "2025-11-03", "sentisenseScore": 18.7, "sentisenseScoreAvg30d": 24.1,
    "scoreLabel": "Bullish", "direction": "Bullish", "trend": "DOWN", "mentions": 1420,
    "bySource": [{"source": "News", "direction": "Bullish", "mentionShare": 58, "value": 0.22}],
    "drivers": [{"title": "Example headline", "tone": 0.41}], "narrative": "Example narrative."},
  "quote": {"currentPrice": 172.4, "changePercent": -0.8, "marketCap": 4210000000000, "peRatio": 48.2,
    "epsTTM": 3.58, "week52High": 196.0, "week52Low": 121.5},
  "stories": [{"title": "Example story title", "averageSentiment": 0.31, "impactScore": 6.4,
    "brokeAt": 1762128000, "storyId": "example-id"}],
  "insiderTrades": [{"insiderName": "Example Insider", "insiderTitle": "EVP", "transactionType": "SELL",
    "transactionCode": "S", "transactionDate": "2025-10-28", "sharesTransacted": 12000,
    "pricePerShare": 170.1, "totalValue": 2041200}],
  "insiderTradeCountInWindow": 14,
  "congressTrades": [{"politicianName": "Example Member", "chamber": "House", "party": "D", "state": "CA",
    "transactionType": "PURCHASE", "transactionDate": "2025-10-15", "disclosureDate": "2025-11-01",
    "amountRange": "$15,001 - $50,000", "owner": "Spouse"}],
  "congressTradeCountInWindow": 3,
  "analystConsensus": {"targetLow": 140.0, "targetMean": 205.5, "targetMedian": 210.0, "targetHigh": 250.0,
    "numberOfAnalysts": 46, "upsidePercent": 19.2, "consensusLabel": "STRONG_BUY",
    "updatedAt": "2025-11-03T14:05:11Z"}
}
```

An ETF row, also invented, carries only the two sections that apply to a fund:

```json
{
  "ticker": "SPY", "companyName": "Example S&P 500 ETF", "instrumentType": "ETF",
  "coverageNote": "etf: sentiment and price only",
  "sentiment": {"asOf": "2025-11-03", "sentisenseScore": -4.2, "sentisenseScoreAvg30d": 2.8,
    "scoreLabel": "Neutral", "direction": "Neutral", "trend": "FLAT"},
  "quote": {"currentPrice": 571.2, "changePercent": 0.3, "week52High": 590.0, "week52Low": 480.5,
    "dividendYield": 0.012, "aum": 600000000000, "expenseRatio": 0.0009, "nav": 571.0,
    "inceptionDate": "1995-06-01"}
}
```

Reading the row:

- `instrumentType` is `STOCK` for a full report and `ETF` for a fund row.
- A section that could not be fetched is left out and named in `sectionErrors`, e.g.
  `["analystConsensus:http_404"]` for a stock with no analyst coverage. The row still counts as a report
  when the sentiment or quote section is present.
- `sentiment.sentisenseScore` is today's reading and `null` before it lands (late morning US Eastern);
  the 30-day fields are always present.
- Insider `transactionType` is `BUY`, `SELL`, `AWARD`, `EXERCISE`, `GIFT` or `OTHER`. Rows with
  `transactionCode` `F` are shares withheld for taxes and arrive typed `SELL`, so read the code before
  headlining a sale. Congress `transactionType` is `PURCHASE`, `SALE`, `EXCHANGE` or `OTHER`.
- `analystConsensus.upsidePercent` is measured against the price captured when the analyst snapshot was
  written (`updatedAt`), not `quote.currentPrice`, so the two can differ by a few percent.
- A ticker with no sentiment and no quote returns `{"ticker": "XYZ", "error": "no_coverage"}`, uncharged.

### Pricing

$0.25 per stock report, charged only when the row carries the sentiment or quote core. ETF rows, no
coverage and failed requests cost nothing. A 10-stock watchlist refresh costs $2.50.

### FAQ

**How fresh is each section?** Quote: 15-minute delayed. Sentiment: a daily reading, today's lands late
morning US Eastern. Insider trades: Form 4 filings, updated daily. Congressional trades: official
disclosures, updated daily; a disclosure can trail the trade by up to 45 days, which is why the window
applies to the disclosure date. Analyst consensus: about once a day, `updatedAt` says when.

**What does `no_coverage` mean, and why is a section missing?** `no_coverage` means neither a sentiment
picture nor a quote exists for that symbol, so nothing is reported or charged. A missing section on a
covered stock is normal: small caps often have no analyst coverage, most stocks have no congressional
trades in 90 days, and some have no insider filings. The counts and `sectionErrors` say which case it is.

**What about ETFs?** An ETF symbol such as SPY returns a fund row: the sentiment section, a 15-minute
delayed fund quote (price, day and 52-week range, dividend yield, AUM, expense ratio, NAV, inception
date), `instrumentType` `ETF` and `coverageNote` `"etf: sentiment and price only"`. The stories,
insider, congressional and analyst sections are left out of fund rows. ETF rows are not charged. The
companion `stock-sentiment-score` covers ETFs too and charges them like any other ticker.

**How often should I run it?** Once a day per watchlist: the Score, filings and consensus move on a
daily clock and only the quote moves faster. Widen `lookbackDays` to surface a quieter name's history.

Educational and informational use only. Not investment advice.

# Actor input Schema

## `tickers` (type: `array`):

US stock tickers to research, e.g. NVDA, TSLA, AAPL. Up to 10 per run, case-insensitive, duplicates removed. An ETF ticker returns sentiment and price only and is not charged.

## `lookbackDays` (type: `integer`):

Trailing window for insider trades and congressional trades. Congress uses the disclosure date.

## `includeStories` (type: `boolean`):

Include the news stories section (up to 5 AI-clustered stories per stock).

## Actor input object example

```json
{
  "tickers": [
    "NVDA"
  ],
  "lookbackDays": 90,
  "includeStories": true
}
```

# Actor output Schema

## `results` (type: `string`):

One row per requested ticker, in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "tickers": [
        "NVDA"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sentisense/stock-research-report").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "tickers": ["NVDA"] }

# Run the Actor and wait for it to finish
run = client.actor("sentisense/stock-research-report").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "tickers": [
    "NVDA"
  ]
}' |
apify call sentisense/stock-research-report --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sentisense/stock-research-report"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/kzwl7IKorAh0lQwz3/builds/IZm0hlUfnnggpE8Vu/openapi.json
