Transcripts & Corporate Events

Full-text S&P Capital IQ earnings-call transcripts and the complete Key Developments corporate-event ledger — the licensed, multi-decade archive that no competitor sells self-serve. Read what executives actually said, turn by turn with named speakers and roles, and pull a company's entire corporate history: M&A, guidance changes, executive changes, buybacks, litigation, offerings, activism and 100+ more event types back to 1990.

This is part of the Tengu vault — differentiated data we license and warehouse directly (1.75M transcript versions, ~24M speaker-turn components, 41.9M Key Developments events) rather than proxy from a public API. Everything below serves from FIRM's own lakehouse.

What's inside#

  • Earnings-call transcripts — 1.75M transcript versions from S&P Capital IQ, one clean row per call. Duplicate versions of the same call are collapsed to the best available copy (Proofed > Edited > Spellchecked), so you always get the most authoritative text.
  • Full transcript text with speakers — ~24M speaker-turn components rendered as an ordered script: each turn carries the speaker's name, their role (executive / analyst / operator) and the component type (prepared remarks / question / answer). Slice to just the prepared remarks or just the analyst Q&A.
  • Full-text search — search call headlines across every company, or search the spoken words inside one company's transcripts and get back per-call hit counts and a first-hit snippet.
  • Key Developments events — 41.9M dated corporate events, 1990–2026: M&A announcements/closings, corporate guidance (raised/lowered/new), executive & board changes, buybacks, bankruptcy, index adds/drops, offerings, investor activism, litigation and more. Each event carries a headline and a situation summary.
  • Event-type taxonomy — the full 105-type legend (id, human label, and the filter slug) so you can filter /events/{ticker} precisely.

Coverage caveats (stated honestly):

  • Full transcript text covers 2020-01-01 → 2025-12-31. Calls outside that window return their metadata (headline, date, event type) but no spoken words. Responses carry an explicit note to this effect.
  • Key Developments events cover 1990–2026.
  • Ticker resolution is US-Compustat-scoped. Tickers map exchange symbol → Compustat gvkey → Capital IQ companyid; a symbol Compustat doesn't cover returns an explicit ticker_not_resolved error rather than a wrong company.
  • These tables are large and archival — treat them as a deep, authoritative record, not a real-time wire.

Access#

3 credits/call. Pro plan ($499/mo) or higher. Every endpoint requires a valid API key. All reads serve from FIRM's warehouse via bounded Athena pushdowns; errors and empty results come back as explicit error / warning fields inside a 200 envelope (never a 500).

Endpoints#

MethodPathDescription
GET/api/v3/transcripts/{ticker}List a company's calls (newest first), one row per call. Query: since (YYYY-MM-DD, calls on/after), limit (1–100, default 25). Returns {ticker, company, companyid, gvkey, n, transcripts[], note, source}; each item has event_id, keydev_id, date, title, event_type, version, version_status.
GET/api/v3/transcripts/{ticker}/{event_id}Full transcript text as ordered speaker turns. event_id is the id from the list/search route. Query: components (all|presentation|qa, default all), max_turns (1–1500, default 800). Returns {ticker, event_id, transcript, components, n_turns, turns[], source}; each turn has order, section, component_type, speaker, speaker_role, text. Capped at ~2 MB (truncated: true when hit).
GET/api/v3/transcripts/searchFull-text search across transcripts. Query: q (required, 3–80 chars), ticker (optional, restrict to one company), since (YYYY-MM-DD), scope (headlines|text, default headlines), limit (1–50, default 20). scope=headlines searches call titles across all companies; scope=text searches the spoken words and requires ticker. Returns {query, scope, ticker, n, results[], source}.
GET/api/v3/events/{ticker}Key Developments corporate-event history (newest first). Query: type (comma-separated slugs or numeric ids from /events/types), since, until (YYYY-MM-DD window), limit (1–500, default 100). Returns {ticker, company, gvkey, n, events[], filters, source}; each event has keydev_id, type_id, type, type_slug, date, announced, headline, situation.
GET/api/v3/events/typesThe event-type taxonomy (105 types). Returns {n, types[], source} where each type is {id, label, slug}. Use the slug (or id) in the type filter of /events/{ticker}.

Examples#

Example 1: List a company's calls, then pull one transcript (bash + curl)#

Find Apple's most recent calls, then fetch the full Q&A section of one of them (3 credits per call).

Shell
1# 1. List the 5 most recent calls (3 credits)2curl -H "Authorization: Bearer $TENGU_API_KEY" \3  "https://firm.tengu.co/api/v3/transcripts/AAPL?limit=5"4 5# Response envelope:6# {7#   "ok": true,8#   "timestamp": "2026-07-19T14:22:00Z",9#   "ticker": "AAPL",10#   "company": "APPLE INC",11#   "companyid": 24937,12#   "gvkey": "001690",13#   "n": 5,14#   "transcripts": [15#     {16#       "event_id": 2864051,17#       "keydev_id": 998123456,18#       "date": "2025-10-30",19#       "title": "Apple Inc., Q4 2025 Earnings Call, Oct 30, 2025",20#       "event_type": "Earnings Calls",21#       "version": "Proofed Copy",22#       "version_status": "Final"23#     }24#     // ... 4 more25#   ],26#   "note": "full text coverage is 2020-01-01 → 2025-12-31; calls outside that window have metadata only.",27#   "source": "warehouse:bronze.ciq_transcript_meta"28# }29 30# 2. Pull just the analyst Q&A of that call using its event_id (3 credits)31curl -H "Authorization: Bearer $TENGU_API_KEY" \32  "https://firm.tengu.co/api/v3/transcripts/AAPL/2864051?components=qa&max_turns=400"33 34# Response envelope:35# {36#   "ok": true,37#   "timestamp": "2026-07-19T14:22:05Z",38#   "ticker": "AAPL",39#   "event_id": 2864051,40#   "transcript": {41#     "event_id": 2864051,42#     "keydev_id": 998123456,43#     "date": "2025-10-30",44#     "title": "Apple Inc., Q4 2025 Earnings Call, Oct 30, 2025",45#     "event_type": "Earnings Calls",46#     "version": "Proofed Copy",47#     "version_status": "Final"48#   },49#   "components": "qa",50#   "n_turns": 128,51#   "turns": [52#     {53#       "order": 42,54#       "section": "qa",55#       "component_type": "question",56#       "speaker": "Erik Woodring",57#       "speaker_role": "analyst",58#       "text": "Thanks for taking my question. Tim, on Services gross margin..."59#     },60#     {61#       "order": 43,62#       "section": "qa",63#       "component_type": "answer",64#       "speaker": "Timothy Cook",65#       "speaker_role": "executive",66#       "text": "Yeah, thanks Erik. On Services, we feel great about the momentum..."67#     }68#     // ... more turns69#   ],70#   "source": "warehouse:bronze.ciq_transcript_text"71# }

If a call falls outside the 2020–2025 text window, the transcript route returns the metadata plus "warning": "no_text_for_transcript". If the response hits the ~2 MB cap it sets "truncated": true; re-fetch the sections separately with components=presentation and components=qa.

Example 2: Full-text search across transcripts (Python)#

Search call headlines across every company, then search the spoken words inside one company's transcripts (3 credits per call).

Python
1import os, requests2 3HEADERS = {"Authorization": f"Bearer {os.environ['TENGU_API_KEY']}"}4BASE = "https://firm.tengu.co"5 6# 1. Headline search across ALL companies (default scope)7r = requests.get(8    f"{BASE}/api/v3/transcripts/search",9    params={"q": "artificial intelligence", "limit": 10},10    headers=HEADERS, timeout=30,11)12r.raise_for_status()13data = r.json()14print(f"{data['n']} calls with '{data['query']}' in the title")15for hit in data["results"]:16    print(f"  {hit['date']}  {hit['title']}  (event_id={hit['event_id']})")17 18# 2. Full-text search inside ONE company's transcripts (scope=text REQUIRES ticker)19r = requests.get(20    f"{BASE}/api/v3/transcripts/search",21    params={"q": "supply chain", "ticker": "TSLA", "scope": "text",22            "since": "2024-01-01", "limit": 10},23    headers=HEADERS, timeout=30,24)25r.raise_for_status()26data = r.json()27# Envelope:28# {29#   "ok": true,30#   "timestamp": "2026-07-19T14:23:00Z",31#   "query": "supply chain",32#   "scope": "text",33#   "ticker": "TSLA",34#   "n": 6,35#   "results": [36#     {37#       "event_id": 3120774,38#       "hits": 9,39#       "snippet": "...our supply chain has never been more resilient, and we expect..."40#     }41#     // ... more calls, most hits first42#   ],43#   "searched_recent_calls": 42,44#   "note": "full text coverage is 2020-01-01 → 2025-12-31; calls outside that window have metadata only.",45#   "source": "warehouse:bronze.ciq_transcript_text"46# }47for hit in data["results"]:48    print(f"  event_id={hit['event_id']}  {hit['hits']} hits — {hit['snippet']}")

Note: scope=text without a ticker returns 422 ticker_required_for_text_search — text search scans transcript bodies and must be scoped to a single company to stay inside the request budget. Pass any returned event_id to /api/v3/transcripts/{ticker}/{event_id} for the full text.

Example 3: Corporate events + the type taxonomy (bash + Python)#

Look up the event-type legend, then pull Microsoft's M&A and guidance events since 2023 (3 credits per call).

Shell
1# 1. Fetch the taxonomy so you know the filter slugs/ids (3 credits)2curl -H "Authorization: Bearer $TENGU_API_KEY" \3  "https://firm.tengu.co/api/v3/events/types"4 5# Response envelope (105 types):6# {7#   "ok": true,8#   "timestamp": "2026-07-19T14:24:00Z",9#   "n": 105,10#   "types": [11#     { "id": 1,  "label": "Seeking to Sell/Divest",           "slug": "seeking_to_sell_divest" },12#     { "id": 27, "label": "Corporate Guidance - Raised",       "slug": "corporate_guidance_raised" },13#     { "id": 48, "label": "Earnings Calls",                    "slug": "earnings_calls" },14#     { "id": 80, "label": "M&A Transaction Announcements",     "slug": "m_and_a_transaction_announcements" },15#     { "id": 101,"label": "Executive Changes - CEO",           "slug": "executive_changes_ceo" }16#     // ... 100 more17#   ],18#   "source": "warehouse:bronze.ciq_keydev (static legend, inspected 2026-07-17)"19# }
Python
1import os, requests2 3# 2. Microsoft M&A announcements + raised guidance since 20234r = requests.get(5    "https://firm.tengu.co/api/v3/events/MSFT",6    params={7        "type": "m_and_a_transaction_announcements,corporate_guidance_raised",  # or "80,27"8        "since": "2023-01-01",9        "limit": 25,10    },11    headers={"Authorization": f"Bearer {os.environ['TENGU_API_KEY']}"},12    timeout=30,13)14r.raise_for_status()15data = r.json()16# Envelope:17# {18#   "ok": true,19#   "timestamp": "2026-07-19T14:24:10Z",20#   "ticker": "MSFT",21#   "company": "MICROSOFT CORP",22#   "gvkey": "012141",23#   "n": 25,24#   "events": [25#     {26#       "keydev_id": 1044556677,27#       "type_id": 80,28#       "type": "M&A Transaction Announcements",29#       "type_slug": "m_and_a_transaction_announcements",30#       "date": "2023-10-13",31#       "announced": "2023-10-13",32#       "headline": "Microsoft Corporation completes acquisition of ...",33#       "situation": "Microsoft Corporation announced that it has ..."34#     }35#     // ... more events, newest first36#   ],37#   "filters": { "type_ids": [27, 80], "since": "2023-01-01", "until": null },38#   "source": "warehouse:bronze.ciq_keydev"39# }40for e in data["events"]:41    print(f"  {e['date']}  [{e['type']}]  {e['headline']}")

An unknown type slug/id returns 422 unknown_event_type with a hint to call /api/v3/events/types. A ticker Compustat doesn't cover returns "error": "ticker_not_resolved", and a valid ticker with no matching events returns "warning": "no_events_for_filters" — both inside a normal 200 envelope.