Simple & no-nonsense podcast search & directory API. Search all podcasts and episodes by people, places, or topics.
Bring your own key. This API needs your own Listen API: Podcast Search, Directory, and Insights API key - get one from the provider, add it once below, and the proxy injects it on every call. Your OmniStream plan covers the unified SDK, key storage, and proxy - the provider's own rate limits still apply to your key.
This is a community listing. If you own this API, you can request ownership.
npm install omnistream-sdkimport { OmniClient } from "omnistream-sdk";
const omni = new OmniClient({ token: process.env.OMNI_KEY! });
// One key reaches every API on the marketplace.
const data = await omni.call("listennotes/getBestPodcasts");One install, one key - the same client calls every API on the marketplace.
Get API Key on listennotes.com/api
You can get the id from `GET /genres`. If not specified, it'll be the overall best podcasts, which can be considered as a special genre.
Page number of those podcasts in this genre.
Filter best podcasts by country/region. Please note that podcasts that are "best" in a country/region may not be produced in that country/region. For example, a podcast from the US may be very popular in Canada. You can get the supported country codes (e.g., us, jp, gb...) from `GET /regions`. If not specified, you'll get "best podcasts" in United States.
Filter best podcasts by the publisher's country/region. This is to narrow down the results to include "best podcasts" produced in a specific country/region. You can get the supported country codes (e.g., us, jp, gb...) from `GET /regions`. If not specified, you'll get "best podcasts" produced in any country/region. If you want to get a country/region's "best podcasts" that are also produced in that country/region, then you need to specify both **region** and **publisher_region**, e.g., `region=jp` and `publisher_region=jp`.
Filter best podcasts by language. You can get a list of supported languages (e.g., English, Chinese, Japanese...) from `GET /languages`. If not specified, you'll get "best podcasts" in any language.
How do you want to sort these podcasts? If you'd like to sort by popularity, please use **listen_score**.
Whether or not to exclude podcasts with explicit language. 1 is yes, and 0 is no.
Fetch a list of best podcasts by genre
Fetch curated lists of podcasts
Fetch a curated list of podcasts by id
Batch fetch basic meta data for episodes
Fetch detailed meta data for an episode by id
/**
* ListenAPIPodcastSearchDirectoryandInsightsAPI - generated by OmniStream from Listen API: Podcast Search, Directory, and Insights API's OpenAPI spec.
* One typed method per endpoint. A single Omni key reaches the API.
*/
const DEFAULT_BASE = "https://grid.skinvaults.online/v1/proxy/listennotes";
export class ListenAPIPodcastSearchDirectoryandInsightsAPIError extends Error {
status: number;
code?: string;
constructor(status: number, code: string | undefined, message?: string) {
super(message || `ListenAPIPodcastSearchDirectoryandInsightsAPI error ${status}`);
this.name = "ListenAPIPodcastSearchDirectoryandInsightsAPIError";
this.status = status;
this.code = code;
}
}
export interface ListenAPIPodcastSearchDirectoryandInsightsAPIOptions {
baseUrl?: string;
fetch?: typeof fetch;
timeoutMs?: number;
}
export class ListenAPIPodcastSearchDirectoryandInsightsAPI {
/** @param token Your OmniStream key (one key for every API). */
constructor(private token: string, private opts: ListenAPIPodcastSearchDirectoryandInsightsAPIOptions = {}) {
if (!token) throw new Error("ListenAPIPodcastSearchDirectoryandInsightsAPI: token is required");
}
rateLimit: { remainingMinute?: number; remainingDay?: number } | null = null;
private async _request(method: string, path: string, { params, body }: { params?: Record<string, unknown>; body?: unknown } = {}): Promise<any> {
const f = this.opts.fetch ?? globalThis.fetch;
const url = new URL((this.opts.baseUrl ?? DEFAULT_BASE).replace(/\/+$/, "") + path);
if (params) for (const [k, v] of Object.entries(params)) if (v != null) url.searchParams.set(k, String(v));
const headers: Record<string, string> = { "x-omni-key": this.token };
if (body !== undefined) headers["content-type"] = "application/json";
const res = await f(url, { method, headers, body: body !== undefined ? JSON.stringify(body) : undefined });
this.rateLimit = {
remainingMinute: Number(res.headers.get("x-ratelimit-remaining-minute")) || undefined,
remainingDay: Number(res.headers.get("x-ratelimit-remaining-day")) || undefined,
};
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new ListenAPIPodcastSearchDirectoryandInsightsAPIError(res.status, data?.error?.code, data?.error?.message);
return data.data ?? data;
}
/** Fetch a list of best podcasts by genre */
getBestPodcasts(params: { "X-ListenAPI-Key": string; "genre_id"?: string; "page"?: number; "region"?: string; "publisher_region"?: string; "language"?: string; "sort"?: string; "safe_mode"?: number }): Promise<any> {
return this._request("GET", "/best_podcasts", { params });
}
/** Fetch curated lists of podcasts */
getCuratedPodcasts(params: { "X-ListenAPI-Key": string; "page"?: number }): Promise<any> {
return this._request("GET", "/curated_podcasts", { params });
}
/** Fetch a curated list of podcasts by id */
getCuratedPodcastById(params: { "X-ListenAPI-Key": string; "id": string }): Promise<any> {
return this._request("GET", "/curated_podcasts/{id}", { params });
}
/** Batch fetch basic meta data for episodes */
getEpisodesInBatch(params: { "X-ListenAPI-Key": string }): Promise<any> {
return this._request("POST", "/episodes", { params });
}
/** Fetch detailed meta data for an episode by id */
getEpisodeById(params: { "X-ListenAPI-Key": string; "id": string; "show_transcript"?: number }): Promise<any> {
return this._request("GET", "/episodes/{id}", { params });
}
/** Fetch recommendations for an episode */
getEpisodeRecommendations(params: { "X-ListenAPI-Key": string; "id": string; "safe_mode"?: number }): Promise<any> {
return this._request("GET", "/episodes/{id}/recommendations", { params });
}
/** Fetch a list of podcast genres */
getGenres(params: { "X-ListenAPI-Key": string; "top_level_only"?: number }): Promise<any> {
return this._request("GET", "/genres", { params });
}
/** Fetch a random podcast episode */
justListen(params: { "X-ListenAPI-Key": string }): Promise<any> {
return this._request("GET", "/just_listen", { params });
}
/** Fetch a list of supported languages for podcasts */
getLanguages(params: { "X-ListenAPI-Key": string }): Promise<any> {
return this._request("GET", "/languages", { params });
}
/** Fetch a list of your playlists. */
getPlaylists(params: { "X-ListenAPI-Key": string; "sort"?: string; "page"?: number }): Promise<any> {
return this._request("GET", "/playlists", { params });
}
/** Fetch a playlist's info and items (i.e., episodes or podcasts). */
getPlaylistById(params: { "X-ListenAPI-Key": string; "id": string; "type"?: string; "last_timestamp_ms"?: number; "sort"?: string }): Promise<any> {
return this._request("GET", "/playlists/{id}", { params });
}
/** Batch fetch basic meta data for podcasts */
getPodcastsInBatch(params: { "X-ListenAPI-Key": string }): Promise<any> {
return this._request("POST", "/podcasts", { params });
}
/** Submit a podcast to Listen Notes database */
submitPodcast(params: { "X-ListenAPI-Key": string }): Promise<any> {
return this._request("POST", "/podcasts/submit", { params });
}
/** Fetch detailed meta data and episodes for a podcast by id */
getPodcastById(params: { "X-ListenAPI-Key": string; "id": string; "next_episode_pub_date"?: number; "sort"?: string }): Promise<any> {
return this._request("GET", "/podcasts/{id}", { params });
}
/** Request to delete a podcast */
deletePodcastById(params: { "X-ListenAPI-Key": string; "id": string; "reason"?: string }): Promise<any> {
return this._request("DELETE", "/podcasts/{id}", { params });
}
/** Fetch audience demographics for a podcast */
getPodcastAudience(params: { "X-ListenAPI-Key": string; "id": string }): Promise<any> {
return this._request("GET", "/podcasts/{id}/audience", { params });
}
/** Fetch recommendations for a podcast */
getPodcastRecommendations(params: { "X-ListenAPI-Key": string; "id": string; "safe_mode"?: number }): Promise<any> {
return this._request("GET", "/podcasts/{id}/recommendations", { params });
}
/** Fetch a list of supported countries/regions for best podcasts */
getRegions(params: { "X-ListenAPI-Key": string }): Promise<any> {
return this._request("GET", "/regions", { params });
}
/** Fetch related search terms */
getRelatedSearches(params: { "X-ListenAPI-Key": string; "q": string }): Promise<any> {
return this._request("GET", "/related_searches", { params });
}
/** Full-text search */
search(params: { "X-ListenAPI-Key": string; "q": string; "sort_by_date"?: number; "type"?: string; "offset"?: number; "len_min"?: number; "len_max"?: number; "episode_count_min"?: number; "episode_count_max"?: number; "update_freq_min"?: number; "update_freq_max"?: number; "genre_ids"?: string; "published_before"?: number; "published_after"?: number; "only_in"?: string; "language"?: string; "region"?: string; "ocid"?: string; "ncid"?: string; "safe_mode"?: number; "unique_podcasts"?: number }): Promise<any> {
return this._request("GET", "/search", { params });
}
/** Spell check on a search term */
spellcheck(params: { "X-ListenAPI-Key": string; "q": string }): Promise<any> {
return this._request("GET", "/spellcheck", { params });
}
/** Fetch trending search terms */
getTrendingSearches(params: { "X-ListenAPI-Key": string }): Promise<any> {
return this._request("GET", "/trending_searches", { params });
}
/** Typeahead search */
typeahead(params: { "X-ListenAPI-Key": string; "q": string; "show_podcasts"?: number; "show_genres"?: number; "safe_mode"?: number }): Promise<any> {
return this._request("GET", "/typeahead", { params });
}
}
export default ListenAPIPodcastSearchDirectoryandInsightsAPI;
No reviews yet. Be the first to rate this API.
Yes. Listen API: Podcast Search, Directory, and Insights API uses apiKey authentication, so you bring your own key from the provider. You store it once on OmniStream and the proxy injects it into every call, so your code only ever sends your Omni key.
Simple & no-nonsense podcast search & directory API. Search all podcasts and episodes by people, places, or topics. It exposes 23 endpoints over GET, POST, DELETE, including GET /best_podcasts, GET /curated_podcasts, GET /curated_podcasts/{id}.
Install the OmniStream SDK for your language and call Listen API: Podcast Search, Directory, and Insights API through it. The client is generated from this API's OpenAPI spec, so parameters and responses are fully typed, and the same client also calls every other API in the marketplace.
You can start on the free plan. OmniStream charges for the unified SDK, key storage and proxy rather than for Listen API: Podcast Search, Directory, and Insights API itself, and Listen API: Podcast Search, Directory, and Insights API's own rate limits still apply to your provider key.
Giphy: Search, translate, trending, and random GIFs and stickers from the GIPHY library.
Fetch recommendations for an episode
Fetch a list of podcast genres
Fetch a random podcast episode
Fetch a list of supported languages for podcasts
Fetch a list of your playlists.
Fetch a playlist's info and items (i.e., episodes or podcasts).
Batch fetch basic meta data for podcasts
Submit a podcast to Listen Notes database
Fetch detailed meta data and episodes for a podcast by id
Request to delete a podcast
Fetch audience demographics for a podcast
Fetch recommendations for a podcast
Fetch a list of supported countries/regions for best podcasts
Fetch related search terms
Full-text search
Spell check on a search term
Fetch trending search terms
Typeahead search