Official TypeScript/JavaScript SDK for the Pod Engine podcast intelligence API — search 4M+ podcasts, pull rich metadata, transcripts, charts, reviews, guest profiles and more, with full type safety.
- 🟦 Fully typed — every method's parameters and responses are generated from the API's OpenAPI spec, so your editor autocompletes the entire surface.
- 🧩 Ergonomic — resources are grouped by domain:
pe.podcasts.getPodcast(...),pe.charts.getLatestChart(...),pe.search.searchPodcasts(...). - 🪶 Lightweight — zero runtime dependencies. Uses the platform
fetch. - 🔁 Resilient — automatic retries with backoff for transient failures (429 / 5xx).
- 🗓️ Smart dates — ISO timestamps are hydrated into real
Dateobjects.
npm install @podengine/sdk
# or: pnpm add @podengine/sdk / yarn add @podengine/sdk / bun add @podengine/sdkRequires Node 18+ (or any runtime with a global fetch).
import { PodEngine } from '@podengine/sdk';
const pe = new PodEngine({ apiKey: process.env.PODENGINE_API_KEY! });
// Search podcasts
const { result } = await pe.search.searchPodcasts({
searchTerms: [
{
searchTerm: 'startups',
searchType: 'text',
searchTargets: ['podcast-title', 'podcast-description'],
searchTermOptions: { matchMode: 'optional' },
},
],
});
// Get the latest Apple chart
const chart = await pe.charts.getLatestChart({
chartType: 'apple',
country: 'us',
category: 'top podcasts',
});
// Fetch a podcast (by ID or slug) and its episodes
const { podcast } = await pe.podcasts.getPodcast({ podcastIdOrSlug: 'the-tim-ferriss-show' });
const episodes = await pe.podcasts.getPodcastEpisodes({ podcastIdOrSlug: podcast.id });Get an API key at https://www.podengine.ai/solutions/podcast-api.
Pass your API key when constructing the client. It is sent on every request.
const pe = new PodEngine({ apiKey: 'pe_live_...' });const pe = new PodEngine({
apiKey: process.env.PODENGINE_API_KEY!,
baseUrl: 'https://api.podengine.ai', // override for staging/self-host
source: 'my-app', // sent as the x-source header for attribution
timeout: 30_000, // per-request timeout in ms (default: none)
maxRetries: 2, // retries for 429/5xx/network (default: 2)
headers: { 'x-team': 'growth' }, // extra headers on every request
fetch: customFetch, // inject a custom fetch implementation
});Every method also accepts per-call options as a final argument:
const controller = new AbortController();
const chart = await pe.charts.getLatestChart(
{ chartType: 'apple', country: 'us', category: 'top podcasts' },
{ signal: controller.signal, timeout: 5_000, headers: { 'x-trace': '1' } }
);// Plain-text transcript
const { episodeTranscriptText } = await pe.episodes.getEpisodeTranscriptText({ episodeId });
console.log(episodeTranscriptText.text);
// Download a transcript file (returned as a Blob)
const file = await pe.episodes.downloadEpisodeTranscript({ episodeId, format: 'vtt' });
// Request a transcription if one doesn't exist yet
await pe.transcriptions.requestEpisodeTranscription({ episodeId });const categories = await pe.charts.getCategoriesByChartType({ chartType: 'apple' });
const chart = await pe.charts.getChart({
chartType: 'apple',
country: 'us',
category: 'top podcasts',
date: '2024-06-01',
});const profile = await pe.guestProfiles.createGuestProfile({
firstName: 'Ada',
lastName: 'Lovelace',
shortBio: 'Mathematician and writer.',
});
await pe.guestProfiles.updateGuestProfileSocialMediaLinks({
guestProfileId: profile.guestProfileId,
body: [{ socialMediaType: 'twitter', url: 'https://x.com/ada' }],
});All failures throw a PodEngineError subclass:
import { PodEngine, PodEngineApiError, PodEngineConnectionError } from '@podengine/sdk';
try {
await pe.podcasts.getPodcast({ podcastIdOrSlug: 'does-not-exist' });
} catch (err) {
if (err instanceof PodEngineApiError) {
console.error(err.status); // e.g. 404
console.error(err.message); // server-provided message
console.error(err.requestId); // x-request-id, if present
console.error(err.body); // raw parsed error body
} else if (err instanceof PodEngineConnectionError) {
console.error('Network/timeout:', err.message);
}
}Parameter and response types are exported for every operation, named <Operation>Params and
<Operation>Response:
import type { SearchPodcastsParams, GetLatestChartResponse } from '@podengine/sdk';
function buildQuery(): SearchPodcastsParams {
return {
pageSize: 25,
searchTerms: [
{
searchTerm: 'climate',
searchType: 'text',
searchTargets: ['podcast-title', 'podcast-description'],
searchTermOptions: { matchMode: 'optional' },
},
],
};
}The raw OpenAPI types are also available via import type { schema } from '@podengine/sdk', and
the spec itself ships in the package: import spec from 'podengine/openapi.json'.
pe.agent, pe.alerts, pe.autocomplete, pe.charts, pe.episodes, pe.guestProfiles,
pe.podcasts, pe.polling, pe.projects, pe.search, pe.stats, pe.teams,
pe.transcriptions, pe.usage.
See the full interactive reference at https://www.podengine.ai/api-docs.
Found a bug or want an endpoint added? Please open an issue — we read every one.
This SDK is generated from the Pod Engine API's OpenAPI spec, and this repository is an automatically-synced mirror, so direct pull requests to generated files are overwritten on the next sync. See CONTRIBUTING.md for how to get a change landed.