The Zortix read API
Zortix extracts investment ideas from finance podcasts and attributes each one to the speaker, the episode, and the timestamp. This page documents the machine surface: two API tools and an MCP server built around the query only Zortix answers — “what has show X said about NVDA over time, and what changed?”
What this data is — and is not
A descriptive record of podcast discussion: attributed statements (each one sentence Zortix wrote to carry a show’s argument, not a transcript quote), air dates, timestamps, discussion-depth counts, and thesis lifecycles (first heard, dormant, revived, challenged). It is not advice, and it never contains a composite score, a price, a forecast, or a host track record — enforced by CI lints on every string the API authors, and stated publicly at what Zortix will never do.
Quickstart
The API answers without a key, behind shared per-IP rate limits. A self-serve free key (the Free-tier keys section below) lifts you into your own, larger bucket — existing keyless integrations keep working either way. Without a connector key on a Premium account, thesis_history carries the latest statement of each thesis.
curl "https://api.zortix.app/v1/agent/thesis-history?ticker=NVDA"thesis_history
Ordered attributed statements per durable thesis — show, episode, air date, timestamp, the extracted thesis line, permalink — plus lifecycle transitions and the published Callback edition where one exists. One quotable summary sentence first, then the structured list.
The earlier statements are Premium. With no key, a free-tier key or a connector key on a free account, each thesis carries its latest statement only, with historyLocked: true when earlier ones were withheld, and a historyLock message with the upgrade link. Whatever is measured against the withheld statements goes with them: transitions is empty and relation is null. The thesis metadata stays, firstHeardAt included. The show and since filters then admit or drop that latest statement. It is a 200, not a 402. A connector key on a Premium account, checked against the account on every call, returns the newest 50 statements per thesis, oldest first, with every transition and historyLock: null.
GET https://api.zortix.app/v1/agent/thesis-history
?ticker=NVDA # or thesisId=… for one thesis in depth
&show=Invest # optional: show-name filter (contains)
&since=2025-08-01 # optional: statements aired on/after{
"summary": "NVDA: the latest attributed statement on 1 thesis, aired 20 Jul 2026. Earlier statements are part of Zortix Premium.",
"theses": [
{
"thesisId": "…",
"title": "Datacenter capex compounds",
"state": "revived",
"firstHeardAt": "2025-03-12T…",
"lastMentionAt": "2026-07-20T…",
"tickers": ["NVDA"],
"statements": [
{
"date": "2026-07-20T…",
"show": "Invest Like the Best",
"episodeTitle": "…",
"timestamp": "45:10",
"quote": "…one sentence carrying the show's argument…",
"stance": "bullish",
"relation": null,
"ideaId": "…",
"url": "https://web.zortix.app/i/…"
}
],
"transitions": [],
"historyLocked": true,
"callback": { "edition": "2026-w30", "url": "https://zortix.app/callback/2026-w30" }
}
],
"historyLock": {
"message": "Earlier statements of a thesis, with their air dates and permalinks, are a Premium feature. The latest statement of each thesis stays available on the free plan; a connector key on a Premium account returns the full dated history.",
"upgradeUrl": "https://web.zortix.app/premium?utm_source=connector"
},
"attribution": {
"source": "Zortix",
"url": "https://zortix.app/t/NVDA",
"rule": "Attribute each statement to the named show and episode, and cite Zortix (zortix.app) as the index. Descriptive record of podcast discussion — not investment advice, and never a rating, forecast, or recommendation."
}
}An out-of-corpus query answers plainly — “No attributed discussion found in the Zortix corpus for this query.” — with the attribution block still attached. The API never pads and never invents a citation.
ticker_stance_timeline
Weekly stance mix (bullish/bearish/neutral idea counts) by show, plus stance-change events — a show arguing one side and later the opposite — with both dated statements linked so the change can be quoted, not characterised.
The stance-change events are Premium. Every caller gets the weekly counts; with no key, a free-tier key or a connector key on a free account, stanceChanges is empty and stanceChangesLock carries the message and the upgrade link, on every answer, whether or not the ticker has any. The example below is a Premium answer, where stanceChangesLock is null.
GET https://api.zortix.app/v1/agent/ticker-stance-timeline
?ticker=NVDA
&window=365 # days, 28–730, default 365{
"summary": "NVDA: weekly stance mix across 4 shows over 52 weeks; 3 stance-change events, each linked to both statements.",
"ticker": "NVDA",
"windowDays": 365,
"weeks": [
{
"weekStart": "2026-06-01T00:00:00.000Z",
"bullish": 3, "bearish": 1, "neutral": 2,
"byShow": [
{ "show": "Invest Like the Best", "bullish": 2, "bearish": 0, "neutral": 1 }
]
}
],
"stanceChanges": [
{
"show": "…", "from": "bullish", "to": "bearish", "atDate": "2026-07-14T…",
"fromStatement": { "date": "…", "quote": "…", "ideaId": "…", "url": "…" },
"toStatement": { "date": "…", "quote": "…", "ideaId": "…", "url": "…" }
}
],
"stanceChangesLock": null,
"attribution": { "source": "Zortix", "url": "https://zortix.app/t/NVDA", "rule": "…" }
}MCP server
@zortix/mcp exposes both tools to Claude Desktop, Claude Code, Cursor, and any MCP client (stdio). Add to claude_desktop_config.json or .mcp.json:
{
"mcpServers": {
"zortix": {
"command": "npx",
"args": ["-y", "@zortix/mcp"]
}
}
}Remote-only clients (ChatGPT connectors, hosted agents) use the hosted endpoint instead of a local process — same two tools, same attribution, Streamable HTTP:
{
"mcpServers": {
"zortix": {
"url": "https://api.zortix.app/v1/mcp"
}
}
}Liveness: GET https://api.zortix.app/v1/mcp/health. The endpoint is stateless — no sessions, one JSON answer per call — and sits behind the same kill switch as the REST surface.
Connector keys — an agent acting for your account
A connector key is the account-bound kind. It lets Muse, Grok, Grokbot, Claude or any MCP or OpenAPI client act for one Zortix account: the daily digest of followed shows, search across the corpus, one idea in full, follows, saved ideas and Ask Zortix with citations, under that account’s own plan limits. Twelve MCP tools on the hosted endpoint and the matching REST routes, one OpenAPI document, one refusal shape (a plan limit is a 402 with a one-sentence message and an upgrade link). Keys start with zk_live_, are created at Settings → Connectors, shown once, and revoked there. A key never mints another key.
GET https://api.zortix.app/v1/agent/openapi.json # the contract, login-free
GET https://api.zortix.app/v1/agent/digest # today's digest for the key's account
POST https://api.zortix.app/v1/mcp # Streamable HTTP, the same tools
Authorization: Bearer zk_live_… # one header, either surfaceThe human page with the install prompts is /connectors; the briefs an agent reads first are /connectors/muse.md and /connectors/grok.md. On a Premium account the same key also returns the earlier statements in thesis_history. The free-tier keys below stay for corpus-only use: the two open tools, no account.
Free-tier keys
The API answers without a key. A free key moves you out of the shared per-IP window into your own bucket (120/minute) and makes your usage attributable — which is what keeps the free tier open. Send it as x-zortix-api-key or a Bearer token; @zortix/mcp reads ZORTIX_API_KEY. Keys are shown once and stored hashed.
Attribution rules
Every response carries an attribution block, and using the data means honouring it:
“Attribute each statement to the named show and episode, and cite Zortix (zortix.app) as the index. Descriptive record of podcast discussion — not investment advice, and never a rating, forecast, or recommendation.”
- Name the show and episode whenever a statement is quoted.
- Cite Zortix (zortix.app) as the index, with a link where the medium allows.
- Do not present the data as advice, a rating, or a forecast — it is a record of what was said.
- Quote lengths in responses already respect per-show licence terms — ship them as served, never reconstruct longer excerpts.
Rate limits & availability
- Per-IP window on the agent endpoints: 30 requests/minute during the beta; a free key raises that to a per-key 120/minute on both the REST and hosted MCP surfaces.
- The agent surface has an operational kill switch. If it is off you get HTTP 503 with
{"error":"agent_api_disabled"}— back off and retry later rather than hammering. - An unknown ticker or empty result is a valid 200 answer with the no-discussion summary, not an error.
Embeds
The “Discussed on Zortix” widget puts a slice of the ledger on any page — dated, attributed, linking back to the source. Three variants: per-show (the show’s latest attributed ideas — renders once the show enables embedding from its claimed page), per-episode (one episode’s ideas with their moments on the tape, same gate), and per-ticker (open: the latest attributed discussion of one name across shows, for coverage and finance blogs). Every card carries “Not investment advice” and shows no stance, no prices, no arrows — headlines, dates, and attribution only.
Script tag — injects a self-sizing iframe:
<script async src="https://web.zortix.app/embed.js" data-show="odd-lots"></script>
<!-- variants: data-show="slug" · data-episode="id" · data-ticker="NVDA" -->Plain iframe (swap show/odd-lots for episode/{episode-id} or ticker/NVDA):
<iframe src="https://web.zortix.app/embed/show/odd-lots" width="100%" height="340"
style="border:0;max-width:680px" title="Discussed on Zortix" loading="lazy"></iframe>Static image, for show-notes platforms that strip scripts and iframes:
<a href="https://zortix.app/p/odd-lots">
<img src="https://web.zortix.app/embed/show/odd-lots/image" width="600" alt="Discussed on Zortix" />
</a>The data behind the widget is public JSON at GET https://api.zortix.app/v1/public/embed/show/{slug}, …/episode/{id}, and …/ticker/{symbol} — the same safe fields as the pages, throttled per embedding origin (generous; the widget itself is cached). Shows opt in and out of the show/episode variants from their claimed page; the gate fails closed on an opt-out. Copy-paste generators with these snippets pre-filled live on each opted-in show’s page and its claim session.
Changelog
- 2026-09-25 — Connector keys: account-bound, scoped, revocable
zk_live_keys for Muse, Grok and any MCP or OpenAPI client; twelve tools on/v1/mcpand the matching/v1/agentroutes; the OpenAPI document at/v1/agent/openapi.json; the briefs and install prompts at /connectors. - 2026-08-26 — Hosted MCP endpoint at
/v1/mcp(Streamable HTTP, stateless) with/v1/mcp/health; self-serve free-tier keys on this page; every link in a tool response now carriesutm_source=mcp. - 2026-08-23 — “Discussed on Zortix” embeds: per-show, per-episode and per-ticker variants; script, iframe and static-image forms; per-show opt-in from the claimed page.
- 2026-08-22 — Agent read API v0:
thesis_historyandticker_stance_timeline, mandatory attribution blocks, per-IP limits.@zortix/mcppackage.llms.txton this host. Public Then/Now strip and citation sentences on ticker pages.
Questions, keys, or a show partnership: hello@zortix.app · Machine-readable section map: /llms.txt