Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: AlphAI REST Calendar API
version: 1.52.0
description: 'Public REST API for AlphAI''s relevance-scored, ticker-linked financial news. All endpoints accept `Authorization: Bearer ak_live_…` (issued from your
`/account/api-keys`). Authenticated traffic is metered per account with two
layers — a per-minute burst cap and a per-day volume cap (Free 20/min +
100/day, Basic 60/min + 10,000/day, Pro 150/min + 100,000/day); a request
passes only if both are under budget. The Free tier is for evaluation /
personal non-commercial use; Basic is licensed for internal commercial use;
Pro adds redistribution of the enriched feed. Send all API traffic to
`api.alphai.io`; a key is required on every request. The API is server-side only. It sends no CORS headers, so a cross-origin
call from a browser page fails at the preflight: the `OPTIONS` request is
answered with `403` at the edge and never reaches the API. Keep the key on
your server and expose your own route to the browser; a key embedded in
page code is readable by every visitor and spends your quota. Every keyed response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining`
and `X-RateLimit-Reset`; these report the per-day volume layer (Reset =
epoch seconds of the next 00:00 UTC reset) so you can watch your daily budget
without provoking a 429. A per-minute burst surfaces only as a 429 with a
short `Retry-After`. A 429 body also names your tier, its caps and an
`upgrade` block. A request rejected with 429 does not itself spend quota. The headers reflect origin processing, so a response served from a shared
cache may omit them. On the MCP server (`mcp.alphai.io`) the same two layers meter **tool calls
only** — the connect handshake (`initialize`, `tools/list`, notifications,
keepalives, the SSE stream) is protocol traffic and does not consume your
quota. It carries a separate, far larger ceiling that exists only to stop a
client reconnecting in a loop; hitting it returns a 429 whose body reports
`"window": "transport"`, which means your client is reconnecting too often,
not that you are out of quota. MCP news tools accept `detail="compact"` for headline triage and polling:
`alphai_news_search`, `alphai_ticker_news`, `alphai_insider_news`,
`alphai_trending`, `alphai_actionable_now`, `alphai_macro` and
`alphai_pair_analysis`. Compact items keep identity, source, publication
and ingest times, tickers, category, relevance_score, top-level
actionability and information_novelty, story fields, ownership_form and
search_match. Summary, analysis, images and SEC detail blocks are omitted;
fetch `alphai_article(uid)` for those details. `detail="full"` is the
default and preserves the existing format, including the condensed recent
lists on pair_analysis. Selection, order, cursors, query interpretation
and macro releases are unchanged, so detail can change between pages. This parameter belongs to MCP tools only; REST parameters are unchanged. Interactive MCP clients use a separate OAuth approval flow. Check the
callback host or app scheme and full callback address before approving;
app names are self-declared, not verified by AlphAI. MCP access includes
news, market data and the saved watchlist, plus creating, changing and
disabling the user''s own alerts on Basic or Pro (including after an
upgrade). The OAuth scope `tools.read` is not a read-only restriction. Registered callbacks can be reviewed in Account → MCP connections. That account management surface requires website login, not an API key. Disconnect blocks all existing MCP OAuth access and refresh tokens for that
app connection, including its other sessions; work already in progress may
finish. Other connections and API keys are unaffected. Revoking either token
type through the separate MCP host''s `/oauth/revoke` has the same effect. Serialize refresh requests and save each replacement token: reuse ends the
connection.'
contact:
name: alphai support
email: support@alphai.io
url: https://alphai.io/contact
license:
name: Proprietary
servers:
- url: https://api.alphai.io
description: Production (API host — key required)
security:
- apiKey: []
tags:
- name: Calendar
description: Scheduled US macro releases (FOMC, CPI, jobs, GDP, PCE…).
paths:
/api/calendar/:
get:
tags:
- Calendar
summary: Scheduled US macro releases (economic calendar)
description: 'The official forward schedule of US macro releases: FOMC decisions
(with SEP and press-conference markers) and minutes, CPI, PPI, the
jobs report (nonfarm payrolls), GDP estimates (advance/second/third),
PCE, advance retail sales, weekly jobless claims and JOLTS — sourced
from the agencies'' own schedule pages (Fed, BLS, BEA, Census, DOL).
Each occurrence carries a stable `uid` (`US-CPI-2026-07`) that
survives reschedules: a moved release keeps its identity, updates
`scheduled_at` and reports `schedule_status`. `phase` says only
whether the scheduled moment has passed (`upcoming`/`elapsed`) — it
deliberately does not claim the agency actually published. Pair the
calendar with `/api/news/macro/` to read what a release meant once
it''s out.
The window is `[from_date, to_date)` — from inclusive, to exclusive;
date-only values mean UTC midnight; defaults are today (UTC) → +7
days; the span is capped at 400 days. No pagination: a full year of
every series is ~250 rows (hard cap 500), ordered by `scheduled_at`
ascending. Cancelled and postponed occurrences stay in the response
with their `schedule_status`.'
parameters:
- in: query
name: from_date
description: 'Window start, inclusive. `YYYY-MM-DD` (UTC midnight) or an ISO datetime (naive = UTC). Default: today, UTC midnight.'
schema:
type: string
example: '2026-08-07'
- in: query
name: to_date
description: Window end, exclusive. Same formats. Default `from_date` + 7 days; span capped at 400 days.
schema:
type: string
example: '2026-08-14'
- in: query
name: event_key
description: Narrow to specific series, comma-separated. Unknown keys return 400.
schema:
type: string
example: cpi,nfp,fomc_decision
- in: query
name: importance
description: Narrow by importance tier.
schema:
type: string
enum:
- high
- medium
- low
- in: query
name: country
description: v1 covers US releases only.
schema:
type: string
enum:
- US
default: US
responses:
'200':
description: Occurrences within the window, `scheduled_at` ascending.
content:
application/json:
schema:
$ref: '#/components/schemas/CalendarEvents'
'400':
description: Unknown parameter or value, a malformed date, `to_date` not after `from_date`, or a window over 400 days.
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
operationId: getApiCalendar
x-operation-id-source: derived
components:
schemas:
CalendarEvents:
type: object
properties:
events:
type: array
items:
$ref: '#/components/schemas/CalendarEvent'
NewsCategory:
type: string
description: '`market_movers` is for articles whose subject IS a notable price move ("AMD up 5% today"); `sector_analysis` is genuine sector-level analysis; `insider` covers SEC Form 4 insider transactions only. SEC 8-K filings categorize by their primary item: an earnings release (Item 2.02) is `earnings`, a completed acquisition or disposition (Item 2.01) is `mergers_acquisitions`, and the remaining events (material agreements, debt, executive changes, annual-meeting results, and since 2026-09-17 securities offerings, Regulation FD disclosures and other events under Items 7.01/8.01) are `corporate_actions`. A foreign private issuer''s SEC 6-K appears only when it is an earnings release (`source` "SEC EDGAR 6-K") and is always `earnings`.'
enum:
- earnings
- mergers_acquisitions
- regulation
- macro_economy
- sector_analysis
- market_movers
- technology
- commodities
- crypto
- ipo
- geopolitics
- insider
- corporate_actions
- other
Error:
type: object
properties:
message:
type: string
error:
type: string
detail:
type: string
extra:
type: object
description: 'Machine-readable context on capped responses: the 429 carries `tier`, `limit_per_minute`, `limit_per_day`, `retry_after_seconds`; the archive 403 carries `reason: archive_horizon`, `tier`, `archive_days`. Both include an `upgrade` object (higher tiers'' caps + `pricing_url`) for callers below Pro. A 400 caused by an unknown query parameter additionally carries `allowed_params` — the complete list this endpoint accepts, read straight off the endpoint''s own schema — plus `docs`, a link to the developer reference. Individual entries in `extra.fields` may carry a did-you-mean hint in their `msg`.'
CalendarEvent:
type: object
description: One scheduled occurrence of a US macro release. `uid` is a stable, opaque occurrence id — reschedules update the row in place, so the uid is safe to store and link. `phase` is computed against request time and only says whether the scheduled moment passed; check `schedule_status` first (a `cancelled` row's phase is meaningless).
properties:
uid:
type: string
example: US-CPI-2026-07
event_key:
type: string
enum:
- fomc_decision
- fomc_minutes
- cpi
- ppi
- nfp
- gdp
- pce
- retail_sales
- jobless_claims
- jolts
title:
type: string
example: CPI (Consumer Price Index)
reference_period:
type: string
description: 'What the release covers, machine-readable: a month (`2026-07`), a quarter (`2026-Q2`), or — for weekly claims — the reference week-ending Saturday (`2026-07-25`).'
example: 2026-07
release_stage:
type: string
nullable: true
description: GDP only — `advance`, `second` or `third`; null elsewhere.
scheduled_at:
type: string
format: date-time
description: Official release moment (UTC; 08:30 / 10:00 / 14:00 ET converted).
phase:
type: string
enum:
- upcoming
- elapsed
schedule_status:
type: string
enum:
- scheduled
- postponed
- cancelled
schedule_basis:
type: string
enum:
- official
- inferred
description: '`official`: the date is printed on the agency''s own schedule page. `inferred`: derived from the documented publication cadence — weekly jobless claims (DOL publishes no forward schedule) and FOMC minutes dates the Fed has not printed yet (three weeks after the meeting). Inferred dates flip to official once the agency lists them.'
importance:
type: string
enum:
- high
- medium
- low
category:
$ref: '#/components/schemas/NewsCategory'
country:
type: string
example: US
source_url:
type: string
format: uri
description: The agency's own schedule page for the series.
press_conference_at:
type: string
format: date-time
nullable: true
description: FOMC decisions only — the 14:30 ET press conference; null elsewhere.
has_sep:
type: boolean
description: FOMC decisions only — true when the meeting carries a Summary of Economic Projections (the "dot plot").
responses:
Unauthorized:
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
RateLimited:
description: 'Rate limit exceeded — either the per-minute burst cap or the per-day
volume cap. The `Retry-After` header is the earliest second a retry can
succeed, not a guess (a burst
block is short, ≤60s; a day-cap block is capped at 3600s — the true reset
is `X-RateLimit-Reset`). The `X-RateLimit-*` trio shows the daily volume
budget. The body''s `extra` names your tier, its `limit_per_minute` /
`limit_per_day`, `retry_after_seconds`, and — below Pro — an `upgrade`
block with the higher tiers'' caps and the pricing URL. A rejected
request does not itself consume quota, so retrying after `Retry-After`
costs you nothing extra.
'
headers:
Retry-After:
description: Seconds to wait before retrying (burst ≤60s; day cap ≤3600s).
schema:
type: integer
X-RateLimit-Limit:
description: The tier's per-day request volume.
schema:
type: integer
X-RateLimit-Remaining:
description: Requests left in today's volume budget.
schema:
type: integer
X-RateLimit-Reset:
description: Epoch seconds of the next 00:00 UTC reset.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
securitySchemes:
apiKey:
type: http
scheme: bearer
bearerFormat: ak_live_*
description: 'Token of the form `ak_live_<random>`. Issued from
`/account/api-keys` on the website. Send as `Authorization: Bearer …`.
'
x-provenance:
method: harvested
publisher: AlphaAI
source: https://api.alphai.io/api/schema/
note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
stamped by stamp-openapi-provenance.py (roadmap#793)