# Earnings & Investor Day Deck Scraper - KPIs & Guidance (`jungle_synthesizer/q4cdn-investor-relations-earnings-deck-pdf-scraper`) Actor

Get public-company earnings decks and investor-day presentations as structured data: every slide as text, plus key metrics, guidance, segment, capex, buyback and dividend lines. Search by ticker, index or sector. Built for analysts and finance AI.

- **URL**: https://apify.com/jungle_synthesizer/q4cdn-investor-relations-earnings-deck-pdf-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Business, Other, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 record scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Earnings & Investor Day Deck Scraper

Get public-company earnings decks and investor-day presentations as structured data. Every slide comes back as text, together with the key metrics, forward guidance, segment, capex, buyback and dividend lines pulled out of the deck, and a direct link to the original PDF. Pick issuers by ticker, by index (S\&P 500, Russell 1000, Nasdaq-100) or by sector, or ask for everything published in the last 90 days.

***

### Earnings Deck Scraper Features

- One record per deck: ticker, company name, exchange, deck type, fiscal period, deck date, title, slide count and the PDF link
- Per-slide text for the whole deck, in order, ready for search, summarisation or an LLM context window
- Key metric lines (revenue, margins, operating income, net income, EPS, EBITDA, cash flow) with the slide they came from and the numbers on the line
- Forward-guidance lines from the outlook slides, plus capex, share-repurchase and dividend lines, each with slide numbers
- Segment and regional breakdown lines, and quoted CEO / CFO statements where a deck carries them
- Earnings, investor-day, analyst-day and conference decks, newest fiscal period first, going back years where the company keeps them online
- Chart-only slides are counted (`image_only_slide_count`), not treated as failures

***

### Who Uses Earnings Deck Data?

- **Hedge fund and mutual fund analysts** - quote what management put on the slide, and compare guidance against the next quarter's actuals
- **Sell-side and independent equity research** - build a deck archive per company without downloading each PDF by hand
- **Corporate strategy and competitive intelligence teams** - read how peers frame their segments, capex and capital return
- **Finance AI and LLM teams** - slide-level text with source links for retrieval and training corpora
- **Data and quant teams** - turn recurring decks into a table keyed by ticker and fiscal period

***

### How the Earnings Deck Scraper Works

1. Choose a mode: **By Ticker** (the tickers you list), **By Index**, **By Sector**, or **Recent** (decks from the last 90 days).
2. Optionally narrow by deck type and fiscal year range.
3. The scraper finds each issuer's decks, newest first, downloads the PDFs and reads them slide by slide.
4. You get one structured record per deck, spread across issuers so a small `maxItems` is not used up by one company.

***

### Coverage

The scraper covers companies whose investor-relations site runs on the Q4 platform, which hosts the decks of a large share of US-listed companies. By Index, By Sector and Recent work over a curated set of 73 such issuers (large and mid-cap technology, communication, consumer, healthcare, financials, industrials, utilities and real estate names). By Ticker accepts any ticker: tickers outside the curated set are looked up at run time, and a ticker whose investor-relations site is not on this platform is reported in the run log as not found. Companies that host decks elsewhere (Apple, Microsoft, Tesla and others) are not covered.

***

### Input

```json
{
  "mode": "by_ticker",
  "tickers": ["NVDA", "UBER", "SNAP"],
  "deckTypes": ["earnings", "investor_day"],
  "yearFrom": 2025,
  "maxItems": 10
}
```

| Field       | Type    | Default                | Description |
|-------------|---------|------------------------|-------------------------------------------------------------------------------------------------|
| `mode`      | string  | `by_ticker`            | `by_ticker`, `by_index`, `by_sector` or `recent` (decks dated in the last 90 days). |
| `tickers`   | array   | `NVDA`, `UBER`, `SNAP` | Tickers for By Ticker mode. |
| `index`     | string  | `sp500`                | `sp500`, `russell1000` or `nasdaq100`, for By Index mode. |
| `sectors`   | array   | `healthcare`           | Sectors for By Sector mode: technology, communication, consumer, healthcare, financials, industrials, utilities, real_estate. |
| `deckTypes` | array   | all four               | `earnings`, `investor_day`, `analyst_day`, `conference`. |
| `yearFrom`  | integer | none                   | Only decks for this fiscal year or later. Fiscal years follow each company's own calendar. |
| `yearTo`    | integer | none                   | Only decks for this fiscal year or earlier. |
| `maxItems`  | integer | `10`                   | Maximum number of decks to return, newest first and spread across issuers. |

Earnings decks across two sectors:

```json
{
  "mode": "by_sector",
  "sectors": ["technology", "financials"],
  "deckTypes": ["earnings"],
  "maxItems": 100
}
```

***

### Earnings Deck Scraper Output Fields

```json
{
  "ticker": "CSCO",
  "company_name": "CISCO SYSTEMS, INC.",
  "exchange": "Nasdaq",
  "deck_type": "earnings",
  "fiscal_period": "Q4 2026",
  "publish_date": "2026-08-12",
  "publish_date_source": "cover_slide",
  "title": "CISCO SYSTEMS, INC. Q4 2026 Earnings Slides",
  "slide_count": 32,
  "image_only_slide_count": 3,
  "pdf_url": "https://s21.q4cdn.com/812015656/files/doc_earnings/2026/q4/presentation/Q4FY26-Cisco-Earnings-Slides.pdf",
  "ir_site": "investor.cisco.com",
  "extracted_kpi_table": {
    "revenue": { "slide": 18, "text": "Revenue $14,673 $15,841 $17,252", "values": ["$14,673", "$15,841", "$17,252"] },
    "gross_margin": { "slide": 18, "text": "Gross Margin 63.2% 63.6% 64.1%", "values": ["63.2%", "63.6%", "64.1%"] }
  },
  "financial_guidance": {
    "slides": [25, 26],
    "lines": ["Guidance for Q1 FY 2027", "Cisco estimates that GAAP EPS will be $1.08 to $1.10 for the first quarter of fiscal 2027."]
  },
  "segment_breakdown": [],
  "capex_disclosure": null,
  "share_repurchase_disclosure": { "slides": [21], "lines": ["Share Repurchases ($M) $1,502 $6,106"] },
  "dividend_disclosure": { "slides": [21], "lines": ["Dividend per Share $0.42 $1.66"] },
  "notable_quotes": [],
  "safe_harbor_present": true,
  "all_slide_text": ["Q4 Fiscal Year 2026\nAugust 12, 2026\nConference Call", "..."]
}
```

| Field                         | Type    | Description |
|-------------------------------|---------|---------------------------------------------------------------------------------------------------------------|
| `ticker`                      | string  | Stock ticker |
| `company_name`                | string  | Company name |
| `exchange`                    | string  | Listing exchange where known |
| `deck_type`                   | string  | `earnings`, `investor_day`, `analyst_day` or `conference` |
| `fiscal_period`               | string  | Company fiscal quarter or year, such as `Q2 2027` or `FY 2026` |
| `publish_date`                | string  | Deck date (ISO 8601): the cover-slide date when it matches the file date, otherwise the file's last-modified date |
| `publish_date_source`         | string  | `cover_slide` or `pdf_last_modified` |
| `title`                       | string  | Deck title |
| `slide_count`                 | integer | Number of slides |
| `image_only_slide_count`      | integer | Slides with no text layer (charts or images) |
| `pdf_url`                     | string  | Direct link to the PDF |
| `ir_site`                     | string  | The company's investor-relations site |
| `extracted_kpi_table`         | object  | Metric lines with slide number, line text and the numbers on it; best-effort |
| `financial_guidance`          | object  | Numeric lines from outlook and guidance slides, with slide numbers; best-effort |
| `segment_breakdown`           | array   | Numeric lines from segment, regional and product slides, as `slide N: line`; best-effort |
| `capex_disclosure`            | object  | Capital expenditure lines with slide numbers; best-effort |
| `share_repurchase_disclosure` | object  | Buyback lines with slide numbers; best-effort |
| `dividend_disclosure`         | object  | Dividend lines with slide numbers; best-effort |
| `notable_quotes`              | array   | Quoted passages attributed to a CEO, CFO, chair or president |
| `safe_harbor_present`         | boolean | Whether the deck carries a forward-looking-statements notice |
| `all_slide_text`              | array   | The text of every slide, one string per slide |

The extracted fields are read from the slide text, so they appear only where the deck has that slide: in a 37-deck test across 19 companies the key-metric table was found on 35, guidance on 21, capex on 15, buybacks on 13, dividends on 11, segment lines on 7 and executive quotes on 2. The slide text, deck date, fiscal period and PDF link are present on every record.

***

### FAQ

#### How do I get earnings decks for specific companies?

Leave the mode on By Ticker and list the tickers. Add `yearFrom` to skip older decks, and set `maxItems` to the number of decks you want. Results come back newest first, spread across the companies you listed.

#### Which companies are covered?

Companies whose investor-relations site is on the Q4 platform. By Index, By Sector and Recent use a curated set of 73 issuers; By Ticker also tries to find any other ticker you give it and logs the ones it cannot.

#### Why does a fiscal year not match the calendar year?

Fiscal periods follow each company's own calendar. NVIDIA's quarter ending July 2026 is Q2 of fiscal 2027, for example. `yearFrom` and `yearTo` filter on that fiscal year.

#### How accurate is the extracted data?

The metric, guidance, capex, buyback and dividend fields are read line by line from the slide text and are best-effort. Charts and images have no text, so their numbers are not extracted. Every record carries the full slide text and the PDF link so you can check or re-parse anything.

#### Do I need a login or API key?

No. These are decks companies publish for investors.

#### Can I schedule it?

Yes. Use Apify schedules with Recent mode to collect each quarter's new decks as they appear, and send the dataset to a webhook, a spreadsheet or your own database.

# Actor input Schema

## `sp_intended_usage` (type: `string`):

What will this data feed? E.g. lead lists, KYB checks, price tracking.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

We'll personally help with your use case. No spam.

## `mode` (type: `string`):

How to pick issuers. By Ticker uses the tickers you list; By Index and By Sector use the covered issuer set; Recent returns decks published in the last 90 days across it.

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

Stock tickers to fetch decks for (used by By Ticker mode), e.g. NVDA, UBER, SNAP.

## `index` (type: `string`):

Index to cover (used by By Index mode).

## `sectors` (type: `array`):

Sectors to cover (used by By Sector mode).

## `deckTypes` (type: `array`):

Which kinds of decks to keep. Leave all selected for everything.

## `yearFrom` (type: `integer`):

Only decks for this fiscal year or later. Leave blank for no lower bound.

## `yearTo` (type: `integer`):

Only decks for this fiscal year or earlier. Leave blank for no upper bound.

## `maxItems` (type: `integer`):

Maximum number of decks to return, newest first.

## Actor input object example

```json
{
  "sp_contact": "Share your email here...",
  "mode": "by_ticker",
  "tickers": [
    "NVDA",
    "UBER",
    "SNAP"
  ],
  "index": "sp500",
  "sectors": [
    "healthcare"
  ],
  "deckTypes": [
    "earnings",
    "investor_day",
    "analyst_day",
    "conference"
  ],
  "maxItems": 10
}
```

# Actor output Schema

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

No description

# 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 = {
    "sp_contact": "Share your email here...",
    "mode": "by_ticker",
    "tickers": [
        "NVDA",
        "UBER",
        "SNAP"
    ],
    "index": "sp500",
    "sectors": [
        "healthcare"
    ],
    "deckTypes": [
        "earnings",
        "investor_day",
        "analyst_day",
        "conference"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/q4cdn-investor-relations-earnings-deck-pdf-scraper").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 = {
    "sp_contact": "Share your email here...",
    "mode": "by_ticker",
    "tickers": [
        "NVDA",
        "UBER",
        "SNAP",
    ],
    "index": "sp500",
    "sectors": ["healthcare"],
    "deckTypes": [
        "earnings",
        "investor_day",
        "analyst_day",
        "conference",
    ],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/q4cdn-investor-relations-earnings-deck-pdf-scraper").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 '{
  "sp_contact": "Share your email here...",
  "mode": "by_ticker",
  "tickers": [
    "NVDA",
    "UBER",
    "SNAP"
  ],
  "index": "sp500",
  "sectors": [
    "healthcare"
  ],
  "deckTypes": [
    "earnings",
    "investor_day",
    "analyst_day",
    "conference"
  ],
  "maxItems": 10
}' |
apify call jungle_synthesizer/q4cdn-investor-relations-earnings-deck-pdf-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jungle_synthesizer/q4cdn-investor-relations-earnings-deck-pdf-scraper"
        }
    }
}
```

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/UvfqWhes2e5AgoFtl/builds/Fn0f77shwOreCvJgE/openapi.json
