Skip to main content
The episode archive is the complete history of transcribed podcast episodes, delivered as gzip-compressed JSON Lines files. Load it once to backfill your system, then follow the episode stream from where the archive leaves off. Each line is an episode as the stream delivers it with include=all, plus its entities and ads, so one piece of code can handle both.
The episode archive is available by arrangement: we enable it for your organization. Authenticate with your API key, as for the stream. A key from an organization without access is rejected with 403 episode_archive_not_enabled.

What’s in it

  • Every transcribed episode. An episode is in the archive once it has a transcript, with its segments, clips, entities and ads if it has them.
  • Filed by publication date. The archive is divided into days and months of UTC publication date. An episode published in March 2024 is in 2024-03, whenever we ingested it.
  • One episode per line, in publication order, as the stream’s episode object with include=all, including entities, the knowledge graph entities discussed, most salient first, each with its salience, occurrences, mention_lines (the number of every transcript line that names it or a form extraction recognized for it) and, when the entity is a known person or company, its entity.person or entity.company reference; and ads, the advertising spots detected, in playback order, with the sponsor’s company_id. Fields that the stream adds over time appear in the archive within its refresh cycle.
  • What describes the episode, not what changes. A record holds the episode’s own data: its transcript, segments, clips, the entities discussed with the transcript lines that mention each, and its ads. Values that change after the fact are left out: a person’s or company’s full profile, a sponsor company’s profile, and anything about the show beyond its title and image. An entity or speaker that is a known person or company carries a compact reference: its id, which is stable and is what to join on, and a few display fields (a person’s title, company and image_url, a company’s domain and ticker) that are a snapshot from when the record was built. Fetch current values when you sync, from GET /v1/people/{id}, GET /v1/companies/{id} and GET /v1/podcasts/{id}.
  • Every file is a complete snapshot of its period. When you download a day or month again, replace your copy of it. An episode missing from the new copy was removed or moved to another day.

Load the archive

  1. List what there is. The listing gives every month with its days, their episode counts and sizes, and a version for each.
  2. Download the months or days you want. Requests are independent, so download several in parallel.
  3. Follow the stream from stream_since. The archive holds every change recorded up to as_of. Open the stream from stream_since, just before it, so nothing falls between the two. Some episodes will arrive twice; deduplicate on the episode id, as the stream already requires.
as_of and stream_since are null until the archive’s first full build has completed.

Keep your copy current

The stream carries new episodes but not history: a back catalogue we import, a correction to an old transcript, or an episode we remove. Those reach you through the archive. Once a day, list it with updated_since set to the as_of of your previous sync, then download and replace each day it returns:
With updated_since, each month lists only the days whose content changed, while its totals still describe the whole month. A day listed with "episodes": 0 no longer has any episodes; delete your copy. A day’s version changes only when its content does.

Downloads

GET /v1/podcasts/episodes/archive/download?period=… takes a month (2026-09) or a day (2026-09-29) and returns application/gzip. A month is its days concatenated, which every gzip reader (zcat, Python’s gzip, Go’s compress/gzip) reads as one stream.
  • Resuming. A day supports Range requests, so curl -C - resumes it. A month does not. On an unreliable connection, download days.
  • Unchanged files. Every download carries an ETag and a Last-Modified. A full download’s ETag is the period’s version; a download narrowed with include has an ETag of its own. Send the ETag back in If-None-Match, or the Last-Modified time in If-Modified-Since, to get 304 Not Modified when nothing changed. A HEAD request returns the same headers without the body.
  • Less data. include keeps only the relations you name, from transcript, segments, clips, entities and ads; the default is all of them, unlike the stream, where it is none. Every other field is unchanged. A narrowed download is assembled as it is sent, so it is slower and has no Content-Length or Range.

Replay over Server-Sent Events

GET /v1/podcasts/episodes/archive/stream?period=… sends the same episodes as Server-Sent Events, for a consumer built around the stream that wants to load history through the same code. Each episode event carries a cursor and the episode. A complete event ends a full replay, so you can tell it from a dropped connection. To resume, reconnect with cursor set to the last one you processed. If the period was rebuilt in the meantime (the daily update, shortly after midnight UTC), the replay answers with an error event instead, because the rebuild may have added episodes before your cursor; start that period again without a cursor and deduplicate on id. include works as for downloads.
For loading the whole archive, downloads are several times faster: they are compressed and can run in parallel.

Shows

GET /v1/podcasts/archive/download returns every podcast we cover as one application/gzip file of JSON Lines, one show per line. It comes with the episode archive: an organization granted one is granted both. Each episode’s podcast.id is a show’s id here. Each line is the podcast exactly as GET /v1/podcasts/{id} returns it with every section requested (include=related,recommended_guests,recommended_sponsors,coverage): its description, publisher, popularity, bias and suitability, format, episode count, recurring speakers, topics, related shows, recommended guests and sponsors, and coverage. Each line also carries the show’s external_links, its presences on Apple Podcasts, Spotify, YouTube, its website and social profiles, with their attributes (followers, views and the like), as GET /v1/podcasts/{id}/external-links returns them.
  • Rebuilt twice a day. Values that change, popularity and audience metrics among them, are as of the current build, which Last-Modified dates. A build takes some minutes, and if one fails the previous file stays current, so check Last-Modified rather than assuming an age.
  • Cheap to poll. Send the ETag back as If-None-Match and you get 304 Not Modified until the next build. A download can be resumed with a Range request.
  • Replace, don’t merge. A show missing from a newer download has been removed.