Calendar API
Earnings calendar API: report dates with session timing, fiscal quarter, confirmation status, consensus EPS and revenue estimates, and the reported EPS, revenue and surprise once a company reports.
Overview
The Calendar API exposes scheduled market events. It currently includes a discovery endpoint and an earnings calendar with report dates, session timing, fiscal quarters, confirmation status, consensus EPS and revenue estimates, and, once a company reports, its reported EPS and revenue with the surprise versus consensus.
Use cases:
- Build a pre-earnings watchlist: which of my tickers report in the next two weeks?
- Screen for catalysts in a date window (e.g. all confirmed reports between two dates)
- Feed earnings dates into a research agent so it knows when a thesis has a catalyst
- Cross-reference upcoming earnings with sentiment, insider, and institutional signals
- Separate before-open vs after-close reporters for session-aware planning
Scope: the schedule plus the headline result. The default lower bound is the beginning of the current week, so the response can include dates that have already passed. An earlier from bound can reach older rows that remain in the current snapshot. Once a company has reported, its row also carries the reported EPS and revenue and the surprise versus consensus; an upcoming row carries the estimates only. For the full analysis of a reported quarter use the Earnings Analysis API: GET /api/v1/earnings/recent lists recent reports, and GET /api/v1/stocks/{ticker}/earnings-summaries returns the quarter's headline, KPI highlights, guidance, and call summary. For standardized figures use GET /api/v1/stocks/fundamentals and GET /api/v1/stocks/{ticker}/kpis.
Access: Every call requires an API key. FREE-tier keys receive the first week of the requested window with isPreview: true. PRO keys receive all matching rows available in the current snapshot. With no date parameters, the public lower bound is the Monday of the current US Eastern week. Both tiers receive the same event fields. Anonymous calls return 401 api_key_required.
Working in Python? Five runnable scripts: Python earnings examples.
GET /api/v1/calendar
Discovery endpoint. Lists the calendars exposed by this family so an agent can find them without hardcoding paths.
Authentication: API key required. This call does not consume monthly quota (metadata only); the per-minute rate limit still applies.
Parameters: none.
Example Request:
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/calendar"
Example Response:
{
"calendars": [
{
"type": "earnings",
"path": "/api/v1/calendar/earnings",
"description": "Upcoming company earnings dates (forward window)"
}
]
}
GET /api/v1/calendar/earnings
Returns company earnings schedule rows that match the requested filters. Each entry carries the report date, session timing, fiscal quarter, confirmation status, and the consensus EPS and revenue estimates. Once the company has reported, the entry also carries the reported EPS and revenue and the surprise versus consensus.
By default the response covers the current week onward, measured from the Monday of the current US Eastern week rather than from today, so it can include dates earlier in the week that have already passed. To reach further back than the current week, pass an explicit from. Rows dated before today can carry the reported result (actualEps, actualRevenue, epsSurprisePct, revenueSurprisePct, and epsBasis saying whether that EPS is the GAAP or the adjusted figure); upcoming rows carry null in those fields.
Authentication: API key required. FREE tier returns the first week of the requested window with isPreview: true; PRO returns all matching rows available in the current snapshot. metadata.windowStart and metadata.windowEnd report the resolved response window, and metadata.count always equals data.earnings.length.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
ticker |
string | No | - | Filter to a single ticker (e.g. AAPL) |
week |
string | No | - | Shorthand date window. this is the Monday-to-Sunday week containing the current US Eastern (America/New_York) date; next is the seven days immediately after that week ends; last is the seven days immediately before it starts. The window rolls over at midnight Eastern. Used only when both from and to are absent |
from |
string | No | start of current week | Inclusive lower date bound, ISO YYYY-MM-DD. Pass an earlier date to reach older schedule rows still present in the current snapshot |
to |
string | No | - | Inclusive upper date bound, ISO YYYY-MM-DD. Setting to equal to from is a valid single-day query |
confirmed |
boolean | No | - | Two-sided. true returns only company-confirmed dates, false returns only the still-estimated ones. Omit it to get both |
time |
string | No | - | Filter by session: before_open, after_close, during_market, or unknown |
Example Request:
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/calendar/earnings?week=next&confirmed=true"
from sentisense import SentiSenseClient
client = SentiSenseClient(api_key="ss_live_YOUR_KEY")
cal = client.get_earnings_calendar(week="next")
for e in cal.earnings:
eps = f"est. ${e['estimatedEps']}" if e.get("estimatedEps") is not None else "no estimate"
print(f"{e['earningsDate']} {e['ticker']} ({e['earningsTime']}) {eps}")
Response Schema:
| Field | Type | Description |
|---|---|---|
isPreview |
boolean | true when limited to one week (FREE tier) |
previewReason |
string | "PRO_REQUIRED" or null |
totalCount |
int | On a preview, the number of matching events before the FREE one-week limit |
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 | { earnings: [...], metadata: {...} } |
Earnings event object:
| Field | Type | Description |
|---|---|---|
ticker |
string | Stock ticker symbol |
companyName |
string | Company name |
earningsDate |
string | Report date, ISO YYYY-MM-DD |
earningsTime |
string | before_open, after_close, during_market, or unknown. Never null or absent. unknown means no session claim applies, either because the timing is unpublished or because none is possible: some issuers release on a Saturday or Sunday ahead of a Monday call, and a weekend has no open or close for the report to sit against. A weekend earningsDate is legitimate data, not an error to filter out |
fiscalQuarter |
string | null | Fiscal quarter the report covers, in the company's own fiscal calendar (e.g. Q2 2026), or null when it cannot be determined, as for a recent listing |
confirmed |
boolean | Whether the company has confirmed the date (vs. estimated/projected) |
estimatedEps |
number | Consensus EPS estimate, nullable |
estimatedRevenue |
number | Consensus revenue estimate as an absolute amount (not thousands or millions), nullable |
actualEps |
number | Reported EPS, null until the company reports |
actualRevenue |
number | Reported revenue as an absolute amount, null until the company reports |
epsSurprisePct |
number | (actualEps - estimatedEps) / abs(estimatedEps) * 100, rounded to 2 decimals. Positive means the company beat the consensus. null when either side is missing or the estimate is 0 |
revenueSurprisePct |
number | The same formula on revenue. null when either side is missing or the estimate is 0 |
epsBasis |
string | null | What actualEps is, checked against the company's filed GAAP EPS for the quarter: "gaap" when it equals the diluted or basic GAAP figure to the half-cent, "adjusted" when it is more than five cents from both (the company's adjusted figure, or rarely a GAAP figure on another basis such as continuing operations), "unknown" when the quarter's statement is not filed yet, the gap sits inside that band, or the company files in a currency other than USD. null until the company reports |
Read the surprise with the reporting basis in mind: actualEps and actualRevenue are the figures the provider carries for that print, which is GAAP for some companies and the company's adjusted figure for others, while the estimate is the consensus. epsBasis tells you which: on the 2026-11-02 snapshot about 30% of reported rows were "gaap", just over half "adjusted" and the rest "unknown". For a company that files in another currency (ASML in EUR, SK hynix in KRW), the calendar's EPS and revenue figures are normally converted to USD, both the estimate and the reported result, so the surprise is like for like, while the company's filed GAAP EPS stays in its own currency; there is no same-currency figure to check against, so epsBasis is "unknown" on those rows. A quarter with a large one-off (a spectrum sale, a tax benefit, a write-down) reported on the GAAP basis can show a surprise of several thousand percent that is arithmetically right and economically meaningless, so a beat-or-miss display should cap or flag surprises beyond a few hundred percent rather than rank by them, and can show the basis next to the number. unknown is the honest answer for the first days after a print, before the quarter's statement is filed; rows are relabelled on later refreshes.
The four result fields and epsBasis populate on reported rows only: an upcoming row always carries null in actualEps, actualRevenue, epsSurprisePct, revenueSurprisePct and epsBasis, and every row carries all six keys. Dividing by the absolute estimate keeps the sign meaningful for loss-making companies: an EPS estimate of -0.40 and a reported -0.50 give epsSurprisePct: -25.0, a miss.
Session timing is filled in for reports in the current and next week; reports further out usually carry earningsTime: "unknown" until their timing is published.
Metadata object:
| Field | Type | Description |
|---|---|---|
generatedAt |
int | null | Snapshot build time in epoch seconds, or null if unavailable; it is not a content revision, so compare event rows to detect changes |
windowStart |
string | null | Inclusive lower bound of the resolved response window, ISO YYYY-MM-DD |
windowEnd |
string | null | Inclusive upper bound of the resolved response window, ISO YYYY-MM-DD |
count |
int | Number of events in this response |
source |
string | Always "sentisense" |
Example Response (PRO):
The values are illustrative. The first row has reported; the second is still upcoming, so its result fields are null.
{
"isPreview": false,
"previewReason": null,
"data": {
"earnings": [
{
"ticker": "MSFT",
"companyName": "Microsoft Corp.",
"earningsDate": "2026-04-29",
"earningsTime": "after_close",
"fiscalQuarter": "Q3 2026",
"confirmed": true,
"estimatedEps": 3.05,
"estimatedRevenue": 68420000000,
"actualEps": 3.21,
"actualRevenue": 70066000000,
"epsSurprisePct": 5.25,
"revenueSurprisePct": 2.41,
"epsBasis": "adjusted"
},
{
"ticker": "AAPL",
"companyName": "Apple Inc.",
"earningsDate": "2026-04-30",
"earningsTime": "after_close",
"fiscalQuarter": "Q2 2026",
"confirmed": true,
"estimatedEps": 1.62,
"estimatedRevenue": 94350000000,
"actualEps": null,
"actualRevenue": null,
"epsSurprisePct": null,
"revenueSurprisePct": null,
"epsBasis": null
}
],
"metadata": {
"generatedAt": 1777550400,
"windowStart": "2026-04-27",
"windowEnd": "2026-05-26",
"count": 2,
"source": "sentisense"
}
}
}
FREE tier: same shape with isPreview: true, previewReason: "PRO_REQUIRED", a totalCount of the full-window event count, and data.earnings limited to one week (the first week of the window you requested).
Errors:
These are the query-validation failures. Each returns 400 with{"error": "invalid_parameter", "message": "..."}:
| Condition | Message |
|---|---|
time is not one of the four session values |
time must be one of [...] |
week is not this, next or last |
week must be 'this', 'next' or 'last' |
from or to is not an ISO YYYY-MM-DD date |
from/to must be ISO dates (YYYY-MM-DD) |
to is earlier than from, with both supplied explicitly |
to must not be before from |
confirmed cannot be converted to a boolean |
Parameter 'confirmed' must be of type Boolean |
Authentication and rate limiting are separate from query validation. A request with no key returns401 before controller validation, and one past the per-minute limit returns 429 with aRetry-After header giving the seconds until the minute window resets (at most 60).
Additional behavior:
- Unknown query parameters are ignored, not rejected.
?typo=valuereturns the same
calendar as the request without it, so a misspelled filter silently does nothing rather
than narrowing the result or erroring. fromandtoaccept an empty value as absent, not as a malformed date. Sending?from=is the same as omitting it, and the default lower bound still applies.- A filter that matches no reports is a
200, with an emptyearningsarray andcount: 0. A ticker, date range, or filter combination with no matching row is not an error.
Coverage
The calendar covers the curated US equity universe, not the whole market. GET /api/v1/stocks
returns the current covered ticker list. Use that list when interpreting calendar results:
- A ticker present in
/api/v1/stockscan still have no matching calendar row in the current
snapshot, date window, or filter set. An empty result does not establish that no report is scheduled. - A ticker absent from
/api/v1/stocksis outside current coverage, so no calendar row is expected
for it in any window. If you need a ticker we do not cover, ask us and we will look at adding it.
Identifying events and detecting changes
Events have no id or revision counter. Use ticker to correlate rows across snapshots, then compare
the full rows. A later snapshot can change any schedule field or omit a row.metadata.generatedAt reports build time, not a content revision.
There is no cancellation or postponement status in an event. If a row disappears, the response does
not distinguish cancellation, postponement, expiry from the snapshot window, or a coverage change.
An unconfirmed date remains estimated regardless of how long it persists.
Refresh and caching
The calendar is rebuilt a few times a week, and dates change in between when companies announce.
No fixed schedule is guaranteed, so polling once a day is ample for a pre-earnings workflow and
polling faster will not surface dates sooner.
metadata.generatedAt is the build time carried by the current snapshot. It is not a content
revision, so treat a moved value as "worth re-reading" rather than an unchanged value as proof
that nothing changed.
Cache responses for as long as your application needs them. The constraint is redistribution, not
retention: see the API Terms of Service.
Related: Earnings Analysis API for the per-quarter analysis of reports already filed.
Comparing providers? See the best earnings calendar APIs in 2026.
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/calendar
Discover which calendars are available
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/calendar"GET/api/v1/calendar/earnings
Company earnings dates and schedule details
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/calendar/earnings"