# Nasdaq Earnings Calendar Tracker: Date & EPS Changes (`thatmike1/earnings-revisions`) Actor

Watch tickers on the Nasdaq earnings calendar: report day, timing and EPS forecast per company, with what changed since the last observation.

- **URL**: https://apify.com/thatmike1/earnings-revisions.md
- **Developed by:** [Michal Pšenčík](https://apify.com/thatmike1) (community)
- **Categories:** Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 earnings observations

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

## Nasdaq earnings calendar observations

Check an explicit ticker watchlist against Nasdaq's public earnings calendar. Each present, unambiguous match produces a full timestamped observation with report-day membership, timing label, EPS forecast, analyst count and available actual/prior-year context. An optional private watch compares the last delivered observation for the same symbol and fiscal ending month.

This is a sampled observation journal. Nasdaq supplies no revision history, update time, permanent event ID or confirmation flag. Dates are **source-calendar-unconfirmed**, inferred from membership in the requested calendar day. Coverage is limited to returned rows, includes some foreign issuers/ADRs, and is not established as all-market coverage.

### Input

```json
{
    "symbols": ["AXP", "SLB", "EAF", "HDB", "TRV", "GE", "NFLX", "META", "TSLA", "TXN", "IBM", "PG"],
    "daysForward": 7,
    "watchName": "daily-watch",
    "maxRows": 1000,
    "requestIntervalMs": 2000
}
```

Use 1-500 symbols containing ASCII letters, digits, dots or hyphens, at most 20 characters each. Symbols are trimmed, uppercased and deduplicated. No alias or exchange-suffix rewriting occurs. Set both `fromDate` and `toDate` to strict `YYYY-MM-DD` dates for an inclusive 1-14-day window; otherwise the run anchors once to today's New York calendar date and scans `daysForward` days (default 7, maximum 14).

Omit `watchName` or set it to null for stateless `untracked` rows. A name is 1-80 letters/digits/underscores/hyphens. Named state uses the caller's normal storage credentials and includes the caller account, watch name, sorted ticker set and schema versions in its namespace. Changing symbols or watch name starts separate history; changing dates retains the watch and checks comparison coverage. Run **one active writer per watch**. Writer/generation checks detect some conflicts; KVS is not an atomic distributed lock.

`maxRows` is 1-5,000, default 1,000, applied after the whole source window validates. Rows are ordered by report date, symbol and fiscal month. A small cap can repeatedly deliver the same prefix and starve later identities; raise it or narrow the watch. `requestIntervalMs` is 2,000-60,000 idle milliseconds after the preceding response. Unknown fields, changes-only mode, keys, cookies, proxies, browsers and custom URLs/headers are rejected.

### Output and comparisons

The default dataset contains observations only. Every row has exact `raw` source fields, canonical decimal strings or nulls, fiscal month (for example `2026-09`), request-day `reportDate`, response-completion `observedAt`, per-scan coverage, field warnings and a delivery ID. JSON/JSONL is the canonical journal, preserving nested `previous`, `changes`, `raw` and `coverage`. The flat CSV view intentionally omits those nested details and does not expand arrays into billed rows.

Observation types are `untracked`, `baseline`, `unchanged`, `changed`, `scope_entry` and `reappeared`. Baseline and unchanged checks contain the same complete source information and are billed. Changes distinguish forecast availability, actual EPS availability, analyst count and timing. Name, market cap, surprise percentage points and prior-year context do not independently trigger a change. Unknown timing is not an exact release time; unfamiliar timing codes produce a warning without a definite timing alert. Source dollar signs are preserved without asserting currency conversion.

A date-membership change requires a unique symbol/month identity and both old and new dates within both successful windows. Other window entries are noncomparable `scope_entry`. Missing rows never imply cancellation and produce no paid placeholder. Reappearance after recorded absence returns a gap without revision claims. A corrected ticker or fiscal month starts another identity. Month precision cannot identify a permanent fiscal event.

The free default key-value records `SUMMARY` and `OUTPUT` describe coverage, no-hits, ambiguities, caps, storage counts and failures. Failed source windows add no observations or observation-state advances. Ambiguous identities are free diagnostics; other identities can continue. Source/schema/state/delivery failures fail the run. Delivery caps and ambiguity produce a successful platform run with `runOutcome:partial`. Dataset readback confirms delivery before state advances. Delivery is **at least once**, without an atomic dataset/KVS transaction. On same-scan restart, stored rows count toward `maxRows` and SUMMARY even when the source has changed or no longer shows those rows. Pending state is reconciled only after a healthy full source recheck; a failed recheck retains the earlier stored count without adding rows or advancing pending state. `notDeliveredCapCount` counts current candidates lacking an exact stored receipt. A crash can repeat a comparison on a later run with a new scan ID, which is another paid observation.

History begins at the first delivered observation. It misses changes between runs, before observation began, outside queried windows, across identity corrections and after a reset. No backfilled knowledge timestamp or real source revision is claimed. Different days are fetched sequentially, not as an atomic market snapshot.

### Pricing

Exactly two automatic platform events: **$0.00005 per actor-start unit** and **$0.001 per stored observation**, including baseline, unchanged, scope-entry and reappeared checks. There is no revision premium. At proposed 256 MB a start has one unit; larger allocations can change start units. Empty and failed runs can incur the start fee but never paid error/missing/summary rows. A minimum spending cap of **$0.00105** affords a start and one observation. Three observations cost $0.00305; seven cost $0.00705. Post-run exports are platform read usage, not new observations. Console prices and hosted caps must be verified before publication.

### Bounds and source

Only `https://api.nasdaq.com/api/calendar/earnings?date=YYYY-MM-DD` is used: plain HTTP, fixed headers, no login, key, cookies, proxy or browser. One request in flight, at most one retry per day for transport failures/429/5xx, at least 5 seconds for retry, respecting the greater pacing/Retry-After delay. Retry-After over 60 seconds defers/stops. Refusals and challenges stop the source; there is no workaround or fallback.

Bounds: 14 days, 28 attempts, 20 seconds per attempt, 4 MiB decompressed/day, 2,000 source rows/day, 128 MiB accounted external traffic, 16 MiB normalized scan aggregation, 64 KiB/observation, 5,000 retained identities and 8 MiB/watch state. Work stops before the 2,400-second invocation deadline with reserved summary/shutdown time. Storage operations and internal transfer are bounded by fixed and proven-stored-row allowances. SDK/background and hosted billing attribution remain prepublication measurements. State is latest values only, with no automatic eviction; use a new watch or delete its caller-owned store to reset. Datasets are the user's journal and follow their Apify retention settings.

Nasdaq's public JSON is the sole source. No redistribution licence or Nasdaq endorsement is asserted. No personal-data enrichment, advice, trading signals, revenue estimates, webhook or external notification is included. Customers control their run inputs, watch state, dataset access and retention in Apify. Keep their run/storage access private as appropriate. The source may be unavailable from hosting IPs; deployment access, account isolation and actual 256 MB fit are release checks. Default symbols can legitimately have no matches, especially outside earnings season; an empty healthy scan is not a fabricated success row.

# Actor input Schema

## `symbols` (type: `array`):

1-500 explicit ticker symbols. Successful observations, including unchanged, are billed.

## `fromDate` (type: `string`):

Optional YYYY-MM-DD; supply both dates. Otherwise start today in America/New_York.

## `toDate` (type: `string`):

Inclusive YYYY-MM-DD; maximum window 14 days.

## `daysForward` (type: `integer`):

Inclusive calendar days when explicit dates are absent.

## `watchName` (type: `string`):

Optional 1-80 letters, digits, underscore or hyphen. Omit for stateless output. Use one active writer per watch.

## `maxRows` (type: `integer`):

Delivery cap after the complete window validates. No automatic continuation.

## `requestIntervalMs` (type: `integer`):

Minimum idle time after a response; requests are sequential.

## Actor input object example

```json
{
  "symbols": [
    "AXP",
    "SLB",
    "EAF",
    "HDB",
    "TRV",
    "GE",
    "NFLX",
    "META",
    "TSLA",
    "TXN",
    "IBM",
    "PG"
  ],
  "daysForward": 7,
  "maxRows": 1000,
  "requestIntervalMs": 2000
}
```

# Actor output Schema

## `observations` (type: `string`):

No description

## `csv` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `output` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("thatmike1/earnings-revisions").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("thatmike1/earnings-revisions").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 '{}' |
apify call thatmike1/earnings-revisions --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thatmike1/earnings-revisions"
        }
    }
}
```

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/ZJEwhc1p7mdzQGE49/builds/LdVZOJcKauL2d0LbF/openapi.json
