# PodcastAPI.com Complete Agent Reference > Operation-complete guidance for integrating the Listen Notes Podcast API. Generated from the live API contract and the official PodcastAPI Agent Skill. ## Source Snapshot - Source date: 2026-06-18 - API version: 2.0 - OpenAPI SHA-256: 5ddece371e57e82c - PodcastAPI/skills commit: d26f5ad3bef5bd65f7b467b028f1311e58bf8bd9 - Operations documented: 26 - Live OpenAPI: https://listen-api.listennotes.com/api/v2/openapi.yaml - Live docs: https://www.listennotes.com/api/docs/ - Tutorial index reviewed: 2026-06-23, https://www.listennotes.com/api/tutorials/ ## Quickstart Store the key in a server-side environment variable named `LISTEN_API_KEY` and send it in `X-ListenAPI-Key`: ```bash curl -G \ -H "X-ListenAPI-Key: $LISTEN_API_KEY" \ "https://listen-api.listennotes.com/api/v2/search" \ --data-urlencode "q=climate technology" \ --data-urlencode "type=podcast" ``` For transport tests with fixed fake data, use `https://listen-api-test.listennotes.com/api/v2` without a key. Never treat mock results as real search results. ## Other Listen Notes Product Offerings If the Podcast API does not fit your need, explore other product offerings from Listen Notes, Inc. for the web-based podcast search engine and dataset batch exports to CSV files. - Complete product agent reference: https://www.listennotes.com/llms-full.txt - Suggested prompt: `Read from https://www.listennotes.com/llms-full.txt so I can ask questions about other product offerings from Listen Notes, Inc.` # Tutorial Task Index Use this index to route common product questions to the right endpoint, then verify exact parameters and plan availability in the operation reference below. | Task | Primary API path | Practical guidance | Source | | --- | --- | --- | --- | | Test without an API key | Mock base URL | Use `https://listen-api-test.listennotes.com/api/v2`; results are fixed fake data and do not validate search relevance, filters, or freshness. | [Mock tutorial](https://www.listennotes.help/article/48-how-to-test-the-podcast-api-without-an-api-key) | | Get latest or all episodes | `GET /podcasts/{id}`, `POST /podcasts` | One podcast: page with `next_episode_pub_date` and choose `sort`. Many podcasts: batch up to 10 IDs and set `show_latest_episodes=1`. | [Episodes tutorial](https://www.listennotes.help/article/39-how-to-get-latest-or-all-episodes-of-a-podcast) | | Import or export OPML | `POST /podcasts` | Parse OPML with XML tooling, batch RSS URLs in `rsses`, and generate OPML from returned podcast names and RSS URLs. | [OPML tutorial](https://www.listennotes.help/article/43-how-to-implement-import-opml-and-export-opml-in-a-podcast-app) | | Build a playlist | `POST /episodes`, `GET /playlists/{id}` | Either store episode IDs locally and hydrate with `POST /episodes`, or use Listen Later playlists as the curated source of truth. | [Playlist tutorial](https://www.listennotes.help/article/45-how-to-build-a-playlist-for-episodes-in-a-podcast-app) | | Refresh subscribed podcasts | `POST /podcasts`, `GET /podcasts/{id}` | Store per-user last seen publication dates, batch-check `latest_pub_date_ms`, and fetch changed episode pages only when needed. | [Subscription refresh tutorial](https://www.listennotes.help/article/40-how-to-fetch-new-episodes-for-subscribed-podcasts-using-podcast-api) | | Search episodes inside specific podcasts | `GET /search` | Use `type=episode` and `ocid` as up to 5 comma-delimited Listen Notes podcast IDs from `podcast_id` or `id` fields. | [Scoped episode search tutorial](https://www.listennotes.help/article/41-how-to-search-episodes-for-specific-podcasts-using-podcast-api) | | Resolve Apple, Spotify, RSS, or Listen Notes IDs | `POST /podcasts` | Batch up to 10 identifiers via `itunes_ids`, `spotify_ids`, `rsses`, or `ids`; optionally request latest episodes. | [External ID tutorial](https://www.listennotes.help/article/42-how-to-fetch-metadata-e-g-rss-episodes-of-podcasts-by-apple-podcasts-ids-itunes-ids-or-spotify-ids) | | Monitor API usage | Response headers, `HEAD` | Read usage and quota headers case-insensitively; current docs say `HEAD` checks are not counted as usage. | [Usage tutorial](https://www.listennotes.help/article/44-how-to-check-how-many-requests-ive-used-in-this-billing-cycle) | | Use multiple API tokens | Dashboard/API docs | Create multiple apps/tokens under one account for dev, staging, and production instead of making extra accounts. | [API keys tutorial](https://www.listennotes.help/article/53-how-to-get-one-or-multiple-api-keys-of-listen-notes-podcast-api) | | Add coworkers | Dashboard | Use the API dashboard TEAM tab so coworkers can sign in with their own accounts and access shared API settings without copying secrets through chat or source control. | [Tutorial index](https://www.listennotes.com/api/tutorials/) | | Get sub-genres | `GET /genres` | Use `parent_id` for hierarchy and `top_level_only=1` when only root genres are needed. | [Genre tutorial](https://www.listennotes.help/article/46-how-to-get-sub-genres-for-a-particular-podcast-genre-using-podcast-api) | | Improve podcast-name search | `GET /search`, `GET /typeahead` | Search podcast results with `only_in=title,author`; quote the query for a verbatim attempt; use typeahead with podcast suggestions for autocomplete. | [Name-search tutorial](https://www.listennotes.help/article/47-how-to-get-more-accurate-search-results-when-searching-podcast-names-using-podcast-api) | | Find podcast, episode, or playlist IDs | API responses, ListenNotes.com | Prefer structured response IDs. Human users can use the "Use API to fetch this" link on entity pages. | [ID tutorial](https://www.listennotes.help/article/89-how-to-get-podcast-episode-playlist-ids-on-listen-notes) | | Use webhooks | Dashboard, `POST /podcasts/submit`, `DELETE /podcasts/{id}` | Configure the WEBHOOKS dashboard tab for supported podcaster workflows; callbacks should accept POST and return `200`. | [Webhook tutorial](https://www.listennotes.help/article/49-how-to-use-webhooks-of-podcast-api) | | Create audio or video clips | Episode `audio` URL | Fetch the audio URL from episode metadata, support redirects, then use a media processor such as FFmpeg when rights allow. | [Clip tutorial](https://www.listennotes.help/article/19-how-to-create-audio-or-video-clips-for-a-specific-podcast-episode-using-podcast-api) | | Let human curators handpick content | `GET /playlists/{id}` | Let curators maintain a Listen Later playlist in the website UI; code consumes it as `type=episode_list` or `type=podcast_list` with pagination. | [Human curation tutorial](https://www.listennotes.help/article/34-whats-the-easiest-way-for-our-human-content-curators-to-handpick-specific-podcasts-episodes-into-our-app-using-podcast-api) | | Get transcripts | `GET /episodes/{id}` | Use `show_transcript=1` when available, but expect less than 1% coverage; for arbitrary episodes, retrieve audio and integrate a separate speech-to-text service. | [Transcript tutorial](https://www.listennotes.help/article/35-how-to-get-transcripts-of-any-podcast-episodes-using-podcast-api) | | Build search experiences | Search endpoints | Use typeahead for fast suggestions, spellcheck for corrections, related searches for broader terms, trending for recent search terms, and full search for results. | [Search tutorial](https://www.listennotes.help/article/38-use-podcast-search-apis) | | Embed a player | `listennotes_url` | Append `embed/` to the episode or podcast `listennotes_url` and render that URL in an iframe; no API key is required. | [Embed tutorial](https://www.listennotes.help/article/36-do-you-provide-a-pre-built-embedded-podcast-player-that-i-can-put-on-my-website) | | Get popular podcasts | `GET /best_podcasts` | Use `sort=listen_score` with optional `genre_id`, `region`, `publisher_region`, and `language` filters. | [Popular podcasts tutorial](https://www.listennotes.help/article/37-how-to-get-popular-podcasts-by-country-category-using-podcast-api) | # API Reference ## Directory API ### GET /best_podcasts **Fetch a list of best podcasts by genre** · Operation ID: `getBestPodcasts` Get a list of curated best podcasts by genre, which are curated by Listen Notes staffs based on various signals from the Internet, e.g., top charts on other podcast platforms, recommendations from mainstream media, user activities on listennotes.com... You can get the genre ids from `GET /genres` endpoint. This endpoint returns same data as https://www.listennotes.com/best-podcasts/ **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `genre_id` | query | no | `string` | 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` | query | no | `integer` | Page number of those podcasts in this genre. | | `region` | query | no | `string` | 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. | | `publisher_region` | query | no | `string` | 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`. | | `language` | query | no | `string` | 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. | | `sort` | query | no | `enum(recent_added_first \| oldest_added_first \| recent_published_first \| oldest_published_first \| listen_score)` | How do you want to sort these podcasts? If you'd like to sort by popularity, please use **listen_score**. | | `safe_mode` | query | no | `enum(0 \| 1)` | Whether or not to exclude podcasts with explicit language. 1 is yes, and 0 is no. | **Responses** - **200** — OK - `BestPodcastsResponse` (object) - `has_previous` (required, boolean) - `name` (required, string) — This genre's name. - `listennotes_url` (required, BestPodcastsLNUrlField) - `BestPodcastsLNUrlField` (string) — Url of the list of best podcasts on [ListenNotes.com](https://www.ListenNotes.com). - `previous_page_number` (required, integer) - `page_number` (required, integer) - `has_next` (required, boolean) - `next_page_number` (required, integer) - `parent_id` (required, integer) — The id of parent genre. - `id` (required, integer) — The id of this genre - `total` (required, integer) - `podcasts` (required, array) - Items: `PodcastSimple` - `PodcastSimple` (object) - `is_claimed` (optional, IsClaimedField) - `IsClaimedField` (boolean) — Whether this podcast is claimed by its producer on [ListenNotes.com](https://www.ListenNotes.com). - `type` (optional, PodcastTypeField) - `PodcastTypeField` (enum(episodic | serial)) — The type of this podcast - episodic or serial. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `website` (optional, WebsiteField) - `WebsiteField` (string) — Website url of this podcast. - `total_episodes` (optional, TotalEpisodesField) - `TotalEpisodesField` (integer) — Total number of episodes in this podcast. - `audio_length_sec` (optional, AvgAudioLengthSecField) - `AvgAudioLengthSecField` (integer) — Average audio length of all episodes of this podcast. In seconds. - `update_frequency_hours` (optional, UpdateFrequencyHoursField) - `UpdateFrequencyHoursField` (integer) — How frequently does this podcast release a new episode? In hours. For example, if the value is 166, then it's every 166 hours (or weekly). - `earliest_pub_date_ms` (optional, EarliestPubDateMsField) - `EarliestPubDateMsField` (integer) — The published date of the oldest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `rss` (optional, RssField) - `RssField` (string) — RSS url of this podcast. This field is available only in the PRO/ENTERPRISE plan. - `latest_episode_id` (optional, LatestEpisodeIdField) - `LatestEpisodeIdField` (string) — The id of the most recently published episode of this podcast, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `latest_pub_date_ms` (optional, LatestPubDateMsField) - `LatestPubDateMsField` (integer) — The published date of the latest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `language` (optional, LanguageField) - `LanguageField` (string) — The language of this podcast. You can get all supported languages from `GET /languages`. - `description` (optional, PodcastDescriptionField) - `PodcastDescriptionField` (string) — Html of this episode's full description - `email` (optional, EmailField) - `EmailField` (string) — The email of this podcast's producer. This field is available only in the PRO/ENTERPRISE plan. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `country` (optional, CountryField) - `CountryField` (string) — The country where this podcast is produced. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `itunes_id` (optional, iTunesIdField) - `iTunesIdField` (integer) — iTunes id for this podcast. - `looking_for` (optional, PodcastLookingForField) - `PodcastLookingForField` (object) - `cohosts` (optional, boolean) — Whether this podcast is looking for cohosts. - `cross_promotion` (optional, boolean) — Whether this podcast is looking for cross promotion opportunities with other podcasts. - `sponsors` (optional, boolean) — Whether this podcast is looking for sponsors. - `guests` (optional, boolean) — Whether this podcast is looking for guests. - `extra` (optional, PodcastExtraField) - `PodcastExtraField` (object) - `youtube_url` (optional, string) — YouTube url affiliated with this podcast - `facebook_handle` (optional, string) — Facebook username affiliated with this podcast - `instagram_handle` (optional, string) — Instagram username affiliated with this podcast - `twitter_handle` (optional, string) — Twitter username affiliated with this podcast - `wechat_handle` (optional, string) — WeChat username affiliated with this podcast - `patreon_handle` (optional, string) — Patreon username affiliated with this podcast - `amazon_music_url` (optional, string) — Amazon Music url for this podcast - `linkedin_url` (optional, string) — LinkedIn url affiliated with this podcast - `spotify_url` (optional, string) — Spotify url for this podcast - `url1` (optional, string) — Url affiliated with this podcast - `url2` (optional, string) — Url affiliated with this podcast - `url3` (optional, string) — Url affiliated with this podcast - `genre_ids` (optional, GenreIdsField) - `GenreIdsField` (array) - Items: `integer` - `integer` — Genre ids. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - `has_guest_interviews` (optional, HasGuestInterviewsField) - `HasGuestInterviewsField` (boolean) — Whether this podcast has guest interviews. - `has_sponsors` (optional, HasSponsorsField) - `HasSponsorsField` (boolean) — Whether this podcast has sponsors. - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /curated_podcasts **Fetch curated lists of podcasts** · Operation ID: `getCuratedPodcasts` A bunch of curated lists from online media. For each list, you'll get basic info of up to 5 podcasts. To get detailed meta data of all podcasts in a specific list, you need to use `GET /curated_podcasts/{id}`. We add new curated lists to the database on a daily basis. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `page` | query | no | `integer` | Page number of curated lists. | **Responses** - **200** — OK - `GetCuratedPodcastsResponse` (object) - `has_previous` (required, boolean) - `previous_page_number` (required, integer) - `page_number` (required, integer) - `next_page_number` (required, integer) - `has_next` (required, boolean) - `total` (required, integer) - `curated_lists` (required, array) - Items: `CuratedListSimple` - `CuratedListSimple` (object) - `id` (optional, CuratedIdField) - `CuratedIdField` (string) — Curated list id, which can be used to further fetch detailed curated list metadata via `GET /curated_podcasts/{id}`. - `description` (optional, CuratedDescriptionField) - `CuratedDescriptionField` (string) — This curated list's description. - `source_url` (optional, CuratedSourceUrlField) - `CuratedSourceUrlField` (string) — Url of the source of this curated list. - `source_domain` (optional, CuratedSourceDomainField) - `CuratedSourceDomainField` (string) — The domain name of the source of this curated list. - `pub_date_ms` (optional, CuratedPubDateMsField) - `CuratedPubDateMsField` (integer) — Published date of this curated list. It is an Epoch Unix timestamp in milliseconds. - `listennotes_url` (optional, CuratedLNUrlField) - `CuratedLNUrlField` (string) — The url of this curated list on [ListenNotes.com](https://www.ListenNotes.com). - `title` (optional, CuratedNameField) - `CuratedNameField` (string) — Curated list name. - `total` (optional, CuratedTotalPodcastsField) - `CuratedTotalPodcastsField` (integer) — The total number of podcasts in this curated list. - `podcasts` (optional, array) — Minimum meta data of up to 5 podcasts in this curated list. - Items: `PodcastMinimum` - `PodcastMinimum` (object) - `image` (optional, ImageField) - `thumbnail` (optional, ThumbnailField) - `title` (optional, PodcastNameField) - `listennotes_url` (optional, PodcastLNUrlField) - `id` (optional, PodcastIdField) - `publisher` (optional, PublisherField) - `listen_score` (optional, ListenScoreField) - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /curated_podcasts/{id} **Fetch a curated list of podcasts by id** · Operation ID: `getCuratedPodcastById` Get detailed meta data of all podcasts in a specific curated list. This endpoint returns same data as https://www.listennotes.com/curated-podcasts/ **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `id` | path | yes | `string` | id for a specific curated list of podcasts. You can get the id from the response of `GET /search?type=curated` or `GET /curated_podcasts`. | **Responses** - **200** — OK - `CuratedListFull` (object) - `id` (optional, CuratedIdField) - `CuratedIdField` (string) — Curated list id, which can be used to further fetch detailed curated list metadata via `GET /curated_podcasts/{id}`. - `description` (optional, CuratedDescriptionField) - `CuratedDescriptionField` (string) — This curated list's description. - `source_url` (optional, CuratedSourceUrlField) - `CuratedSourceUrlField` (string) — Url of the source of this curated list. - `source_domain` (optional, CuratedSourceDomainField) - `CuratedSourceDomainField` (string) — The domain name of the source of this curated list. - `pub_date_ms` (optional, CuratedPubDateMsField) - `CuratedPubDateMsField` (integer) — Published date of this curated list. It is an Epoch Unix timestamp in milliseconds. - `listennotes_url` (optional, CuratedLNUrlField) - `CuratedLNUrlField` (string) — The url of this curated list on [ListenNotes.com](https://www.ListenNotes.com). - `title` (optional, CuratedNameField) - `CuratedNameField` (string) — Curated list name. - `total` (optional, CuratedTotalPodcastsField) - `CuratedTotalPodcastsField` (integer) — The total number of podcasts in this curated list. - `podcasts` (optional, array) — Complete meta data of all podcasts in this curated list. - Items: `PodcastSimple` - `PodcastSimple` (object) - `is_claimed` (optional, IsClaimedField) - `IsClaimedField` (boolean) — Whether this podcast is claimed by its producer on [ListenNotes.com](https://www.ListenNotes.com). - `type` (optional, PodcastTypeField) - `PodcastTypeField` (enum(episodic | serial)) — The type of this podcast - episodic or serial. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `website` (optional, WebsiteField) - `WebsiteField` (string) — Website url of this podcast. - `total_episodes` (optional, TotalEpisodesField) - `TotalEpisodesField` (integer) — Total number of episodes in this podcast. - `audio_length_sec` (optional, AvgAudioLengthSecField) - `AvgAudioLengthSecField` (integer) — Average audio length of all episodes of this podcast. In seconds. - `update_frequency_hours` (optional, UpdateFrequencyHoursField) - `UpdateFrequencyHoursField` (integer) — How frequently does this podcast release a new episode? In hours. For example, if the value is 166, then it's every 166 hours (or weekly). - `earliest_pub_date_ms` (optional, EarliestPubDateMsField) - `EarliestPubDateMsField` (integer) — The published date of the oldest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `rss` (optional, RssField) - `RssField` (string) — RSS url of this podcast. This field is available only in the PRO/ENTERPRISE plan. - `latest_episode_id` (optional, LatestEpisodeIdField) - `LatestEpisodeIdField` (string) — The id of the most recently published episode of this podcast, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `latest_pub_date_ms` (optional, LatestPubDateMsField) - `LatestPubDateMsField` (integer) — The published date of the latest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `language` (optional, LanguageField) - `LanguageField` (string) — The language of this podcast. You can get all supported languages from `GET /languages`. - `description` (optional, PodcastDescriptionField) - `PodcastDescriptionField` (string) — Html of this episode's full description - `email` (optional, EmailField) - `EmailField` (string) — The email of this podcast's producer. This field is available only in the PRO/ENTERPRISE plan. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `country` (optional, CountryField) - `CountryField` (string) — The country where this podcast is produced. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `itunes_id` (optional, iTunesIdField) - `iTunesIdField` (integer) — iTunes id for this podcast. - `looking_for` (optional, PodcastLookingForField) - `PodcastLookingForField` (object) - `cohosts` (optional, boolean) — Whether this podcast is looking for cohosts. - `cross_promotion` (optional, boolean) — Whether this podcast is looking for cross promotion opportunities with other podcasts. - `sponsors` (optional, boolean) — Whether this podcast is looking for sponsors. - `guests` (optional, boolean) — Whether this podcast is looking for guests. - `extra` (optional, PodcastExtraField) - `PodcastExtraField` (object) - `youtube_url` (optional, string) — YouTube url affiliated with this podcast - `facebook_handle` (optional, string) — Facebook username affiliated with this podcast - `instagram_handle` (optional, string) — Instagram username affiliated with this podcast - `twitter_handle` (optional, string) — Twitter username affiliated with this podcast - `wechat_handle` (optional, string) — WeChat username affiliated with this podcast - `patreon_handle` (optional, string) — Patreon username affiliated with this podcast - `amazon_music_url` (optional, string) — Amazon Music url for this podcast - `linkedin_url` (optional, string) — LinkedIn url affiliated with this podcast - `spotify_url` (optional, string) — Spotify url for this podcast - `url1` (optional, string) — Url affiliated with this podcast - `url2` (optional, string) — Url affiliated with this podcast - `url3` (optional, string) — Url affiliated with this podcast - `genre_ids` (optional, GenreIdsField) - `GenreIdsField` (array) - Items: `integer` - `integer` — Genre ids. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - `has_guest_interviews` (optional, HasGuestInterviewsField) - `HasGuestInterviewsField` (boolean) — Whether this podcast has guest interviews. - `has_sponsors` (optional, HasSponsorsField) - `HasSponsorsField` (boolean) — Whether this podcast has sponsors. - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### POST /episodes **Batch fetch basic meta data for episodes** · Operation ID: `getEpisodesInBatch` Batch fetch basic meta data for up to 10 episodes. This endpoint could be used to implement custom playlists for individual episodes. For detailed meta data of an individual episode, you need to use `GET /episodes/{id}`. This endpoint is available only in the PRO/ENTERPRISE plan. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | **Request body (required)** - `GetEpisodesInBatchForm` (object) - `ids` (required, string) — Comma-separated list of episode ids. **Responses** - **200** — OK - `GetEpisodesInBatchResponse` (object) - `episodes` (required, array) - Items: `EpisodeSimple` - `EpisodeSimple` (object) - `maybe_audio_invalid` (optional, MaybeAudioInvalidField) - `MaybeAudioInvalidField` (boolean) — Whether or not this episode's audio is invalid. Podcasters may delete the original audio. - `pub_date_ms` (optional, EpisodePubDateMsField) - `EpisodePubDateMsField` (integer) — Published date for this episode. It is an Epoch Unix timestamp in milliseconds. - `audio` (optional, AudioField) - `AudioField` (string) — Audio url of this episode, which can be played directly. - `listennotes_edit_url` (optional, EpisodeLNEditUrlField) - `EpisodeLNEditUrlField` (string) — Edit url of this episode where you can update the audio url if you find the audio is broken. - `image` (optional, EpisodeImageField) - `EpisodeImageField` (string) — Image url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork image. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, EpisodeThumbnailField) - `EpisodeThumbnailField` (string) — Thumbnail image (300x300) url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork thumbnail image. - `description` (optional, EpisodeDescriptionField) - `EpisodeDescriptionField` (string) — Html of this episode's full description - `title` (optional, EpisodeNameField) - `EpisodeNameField` (string) — Episode name. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `listennotes_url` (optional, EpisodeLNUrlField) - `EpisodeLNUrlField` (string) — The url of this episode on [ListenNotes.com](https://www.ListenNotes.com). - `audio_length_sec` (optional, AudioLengthSecField) - `AudioLengthSecField` (integer) — Audio length of this episode. In seconds. - `id` (optional, EpisodeIdField) - `EpisodeIdField` (string) — Episode id, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `link` (optional, LinkField) - `LinkField` (string) — Web link of this episode. - `podcast` (optional, PodcastMinimum) - `PodcastMinimum` (object) - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /episodes/{id} **Fetch detailed meta data for an episode by id** · Operation ID: `getEpisodeById` Fetch detailed meta data for a specific episode. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `id` | path | yes | `string` | id for a specific episode. You can get episode id from using other endpoints, e.g., `GET /search`... | | `show_transcript` | query | no | `integer` | To include the transcript of this episode or not? If it is 1, then include the transcript in the **transcript** field. The default value is 0 - we don't include transcript by default, because 1) it would make the response data very big, thus slow response time; 2) less than 1% of episodes have transcripts. The transcript field is available only in the PRO/ENTERPRISE plan. | **Responses** - **200** — OK - `EpisodeFull` (object) - `maybe_audio_invalid` (optional, MaybeAudioInvalidField) - `MaybeAudioInvalidField` (boolean) — Whether or not this episode's audio is invalid. Podcasters may delete the original audio. - `pub_date_ms` (optional, EpisodePubDateMsField) - `EpisodePubDateMsField` (integer) — Published date for this episode. It is an Epoch Unix timestamp in milliseconds. - `audio` (optional, AudioField) - `AudioField` (string) — Audio url of this episode, which can be played directly. - `listennotes_edit_url` (optional, EpisodeLNEditUrlField) - `EpisodeLNEditUrlField` (string) — Edit url of this episode where you can update the audio url if you find the audio is broken. - `image` (optional, EpisodeImageField) - `EpisodeImageField` (string) — Image url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork image. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, EpisodeThumbnailField) - `EpisodeThumbnailField` (string) — Thumbnail image (300x300) url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork thumbnail image. - `description` (optional, EpisodeDescriptionField) - `EpisodeDescriptionField` (string) — Html of this episode's full description - `title` (optional, EpisodeNameField) - `EpisodeNameField` (string) — Episode name. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `listennotes_url` (optional, EpisodeLNUrlField) - `EpisodeLNUrlField` (string) — The url of this episode on [ListenNotes.com](https://www.ListenNotes.com). - `audio_length_sec` (optional, AudioLengthSecField) - `AudioLengthSecField` (integer) — Audio length of this episode. In seconds. - `id` (optional, EpisodeIdField) - `EpisodeIdField` (string) — Episode id, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `podcast` (optional, PodcastSimple) - `PodcastSimple` (object) - `is_claimed` (optional, IsClaimedField) - `IsClaimedField` (boolean) — Whether this podcast is claimed by its producer on [ListenNotes.com](https://www.ListenNotes.com). - `type` (optional, PodcastTypeField) - `PodcastTypeField` (enum(episodic | serial)) — The type of this podcast - episodic or serial. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `website` (optional, WebsiteField) - `WebsiteField` (string) — Website url of this podcast. - `total_episodes` (optional, TotalEpisodesField) - `TotalEpisodesField` (integer) — Total number of episodes in this podcast. - `audio_length_sec` (optional, AvgAudioLengthSecField) - `AvgAudioLengthSecField` (integer) — Average audio length of all episodes of this podcast. In seconds. - `update_frequency_hours` (optional, UpdateFrequencyHoursField) - `UpdateFrequencyHoursField` (integer) — How frequently does this podcast release a new episode? In hours. For example, if the value is 166, then it's every 166 hours (or weekly). - `earliest_pub_date_ms` (optional, EarliestPubDateMsField) - `EarliestPubDateMsField` (integer) — The published date of the oldest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `rss` (optional, RssField) - `RssField` (string) — RSS url of this podcast. This field is available only in the PRO/ENTERPRISE plan. - `latest_episode_id` (optional, LatestEpisodeIdField) - `LatestEpisodeIdField` (string) — The id of the most recently published episode of this podcast, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `latest_pub_date_ms` (optional, LatestPubDateMsField) - `LatestPubDateMsField` (integer) — The published date of the latest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `language` (optional, LanguageField) - `LanguageField` (string) — The language of this podcast. You can get all supported languages from `GET /languages`. - `description` (optional, PodcastDescriptionField) - `PodcastDescriptionField` (string) — Html of this episode's full description - `email` (optional, EmailField) - `EmailField` (string) — The email of this podcast's producer. This field is available only in the PRO/ENTERPRISE plan. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `country` (optional, CountryField) - `CountryField` (string) — The country where this podcast is produced. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `itunes_id` (optional, iTunesIdField) - `iTunesIdField` (integer) — iTunes id for this podcast. - `looking_for` (optional, PodcastLookingForField) - `PodcastLookingForField` (object) - `cohosts` (optional, boolean) — Whether this podcast is looking for cohosts. - `cross_promotion` (optional, boolean) — Whether this podcast is looking for cross promotion opportunities with other podcasts. - `sponsors` (optional, boolean) — Whether this podcast is looking for sponsors. - `guests` (optional, boolean) — Whether this podcast is looking for guests. - `extra` (optional, PodcastExtraField) - `PodcastExtraField` (object) - `youtube_url` (optional, string) — YouTube url affiliated with this podcast - `facebook_handle` (optional, string) — Facebook username affiliated with this podcast - `instagram_handle` (optional, string) — Instagram username affiliated with this podcast - `twitter_handle` (optional, string) — Twitter username affiliated with this podcast - `wechat_handle` (optional, string) — WeChat username affiliated with this podcast - `patreon_handle` (optional, string) — Patreon username affiliated with this podcast - `amazon_music_url` (optional, string) — Amazon Music url for this podcast - `linkedin_url` (optional, string) — LinkedIn url affiliated with this podcast - `spotify_url` (optional, string) — Spotify url for this podcast - `url1` (optional, string) — Url affiliated with this podcast - `url2` (optional, string) — Url affiliated with this podcast - `url3` (optional, string) — Url affiliated with this podcast - `genre_ids` (optional, GenreIdsField) - `GenreIdsField` (array) - Items: `integer` - `integer` — Genre ids. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - `has_guest_interviews` (optional, HasGuestInterviewsField) - `HasGuestInterviewsField` (boolean) — Whether this podcast has guest interviews. - `has_sponsors` (optional, HasSponsorsField) - `HasSponsorsField` (boolean) — Whether this podcast has sponsors. - `link` (optional, LinkField) - `LinkField` (string) — Web link of this episode. - `transcript` (optional, TranscriptField) - `TranscriptField` (string) — The transcript of this episode, in plain text (with the newline character \n). If there's not transcript, it is null. This field is available only in the PRO/ENTERPRISE plan. - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /episodes/{id}/recommendations **Fetch recommendations for an episode** · Operation ID: `getEpisodeRecommendations` Fetch up to 8 episode recommendations based on the given episode id. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `id` | path | yes | `string` | Episode id. | | `safe_mode` | query | no | `enum(0 \| 1)` | Whether or not to exclude podcasts with explicit language. 1 is yes, and 0 is no. | **Responses** - **200** — OK - `GetEpisodeRecommendationsResponse` (object) - `recommendations` (required, array) - Items: `EpisodeSimple` - `EpisodeSimple` (object) - `maybe_audio_invalid` (optional, MaybeAudioInvalidField) - `MaybeAudioInvalidField` (boolean) — Whether or not this episode's audio is invalid. Podcasters may delete the original audio. - `pub_date_ms` (optional, EpisodePubDateMsField) - `EpisodePubDateMsField` (integer) — Published date for this episode. It is an Epoch Unix timestamp in milliseconds. - `audio` (optional, AudioField) - `AudioField` (string) — Audio url of this episode, which can be played directly. - `listennotes_edit_url` (optional, EpisodeLNEditUrlField) - `EpisodeLNEditUrlField` (string) — Edit url of this episode where you can update the audio url if you find the audio is broken. - `image` (optional, EpisodeImageField) - `EpisodeImageField` (string) — Image url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork image. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, EpisodeThumbnailField) - `EpisodeThumbnailField` (string) — Thumbnail image (300x300) url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork thumbnail image. - `description` (optional, EpisodeDescriptionField) - `EpisodeDescriptionField` (string) — Html of this episode's full description - `title` (optional, EpisodeNameField) - `EpisodeNameField` (string) — Episode name. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `listennotes_url` (optional, EpisodeLNUrlField) - `EpisodeLNUrlField` (string) — The url of this episode on [ListenNotes.com](https://www.ListenNotes.com). - `audio_length_sec` (optional, AudioLengthSecField) - `AudioLengthSecField` (integer) — Audio length of this episode. In seconds. - `id` (optional, EpisodeIdField) - `EpisodeIdField` (string) — Episode id, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `link` (optional, LinkField) - `LinkField` (string) — Web link of this episode. - `podcast` (optional, PodcastMinimum) - `PodcastMinimum` (object) - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /genres **Fetch a list of podcast genres** · Operation ID: `getGenres` Get a list of podcast genres that are supported in Listen Notes. The genre id can be passed to other endpoints as a parameter to get podcasts in a specific genre, e.g., `GET /best_podcasts`, `GET /search`... You may want to cache the list of genres on the client side. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `top_level_only` | query | no | `enum(0 \| 1)` | Just show top level genres? If 1, yes, just show top level genres. If 0, no, show all genres. | **Responses** - **200** — OK - `GetGenresResponse` (object) - `genres` (required, array) - Items: `Genre` - `Genre` (object) - `id` (optional, integer) — Genre id - `name` (optional, string) — Genre name. - `parent_id` (optional, integer) — Parent genre id. - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /just_listen **Fetch a random podcast episode** · Operation ID: `justListen` Recently published episodes are more likely to be fetched. Good luck! **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | **Responses** - **200** — OK - `EpisodeSimple` (object) - `maybe_audio_invalid` (optional, MaybeAudioInvalidField) - `MaybeAudioInvalidField` (boolean) — Whether or not this episode's audio is invalid. Podcasters may delete the original audio. - `pub_date_ms` (optional, EpisodePubDateMsField) - `EpisodePubDateMsField` (integer) — Published date for this episode. It is an Epoch Unix timestamp in milliseconds. - `audio` (optional, AudioField) - `AudioField` (string) — Audio url of this episode, which can be played directly. - `listennotes_edit_url` (optional, EpisodeLNEditUrlField) - `EpisodeLNEditUrlField` (string) — Edit url of this episode where you can update the audio url if you find the audio is broken. - `image` (optional, EpisodeImageField) - `EpisodeImageField` (string) — Image url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork image. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, EpisodeThumbnailField) - `EpisodeThumbnailField` (string) — Thumbnail image (300x300) url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork thumbnail image. - `description` (optional, EpisodeDescriptionField) - `EpisodeDescriptionField` (string) — Html of this episode's full description - `title` (optional, EpisodeNameField) - `EpisodeNameField` (string) — Episode name. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `listennotes_url` (optional, EpisodeLNUrlField) - `EpisodeLNUrlField` (string) — The url of this episode on [ListenNotes.com](https://www.ListenNotes.com). - `audio_length_sec` (optional, AudioLengthSecField) - `AudioLengthSecField` (integer) — Audio length of this episode. In seconds. - `id` (optional, EpisodeIdField) - `EpisodeIdField` (string) — Episode id, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `link` (optional, LinkField) - `LinkField` (string) — Web link of this episode. - `podcast` (optional, PodcastMinimum) - `PodcastMinimum` (object) - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /languages **Fetch a list of supported languages for podcasts** · Operation ID: `getLanguages` Get a list of languages that are supported in Listen Notes database. You can use the language string as query parameter in `GET /search`. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | **Responses** - **200** — OK - `GetLanguagesResponse` (object) - `languages` (required, array) - Items: `string` - `string` - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### POST /podcasts **Batch fetch basic meta data for podcasts** · Operation ID: `getPodcastsInBatch` Batch fetch basic meta data for up to 10 podcasts. This endpoint could be used to build something like OPML import, allowing users to import a bunch of podcasts via rss urls. For detailed meta data (including episodes) of an individual podcast, you need to use `GET /podcasts/{id}`. This endpoint is available only in the PRO/ENTERPRISE plan. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | **Request body** - `GetPodcastsInBatchForm` (object) - `ids` (optional, string) — Comma-separated list of podcast ids. - `rsses` (optional, string) — Comma-separated rss urls. - `itunes_ids` (optional, string) — Comma-separated Apple Podcasts (iTunes) ids, e.g., 659155419 - `spotify_ids` (optional, string) — Comma-separated Spotify ids, e.g., 3DDfEsKDIDrTlnPOiG4ZF4 - `show_latest_episodes` (optional, enum(0 | 1)) — Whether or not to fetch up to 15 latest episodes from these podcasts, sorted by pub_date. 1 is yes, and 0 is no. - `next_episode_pub_date` (optional, integer) — For latest episodes pagination. It's the value of **next_episode_pub_date** from the response of last request. If not specified, just return latest 15 episodes. It is an Epoch Unix timestamp in milliseconds. **Responses** - **200** — OK - `GetPodcastsInBatchResponse` (object) - `podcasts` (required, array) - Items: `PodcastSimple` - `PodcastSimple` (object) - `is_claimed` (optional, IsClaimedField) - `IsClaimedField` (boolean) — Whether this podcast is claimed by its producer on [ListenNotes.com](https://www.ListenNotes.com). - `type` (optional, PodcastTypeField) - `PodcastTypeField` (enum(episodic | serial)) — The type of this podcast - episodic or serial. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `website` (optional, WebsiteField) - `WebsiteField` (string) — Website url of this podcast. - `total_episodes` (optional, TotalEpisodesField) - `TotalEpisodesField` (integer) — Total number of episodes in this podcast. - `audio_length_sec` (optional, AvgAudioLengthSecField) - `AvgAudioLengthSecField` (integer) — Average audio length of all episodes of this podcast. In seconds. - `update_frequency_hours` (optional, UpdateFrequencyHoursField) - `UpdateFrequencyHoursField` (integer) — How frequently does this podcast release a new episode? In hours. For example, if the value is 166, then it's every 166 hours (or weekly). - `earliest_pub_date_ms` (optional, EarliestPubDateMsField) - `EarliestPubDateMsField` (integer) — The published date of the oldest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `rss` (optional, RssField) - `RssField` (string) — RSS url of this podcast. This field is available only in the PRO/ENTERPRISE plan. - `latest_episode_id` (optional, LatestEpisodeIdField) - `LatestEpisodeIdField` (string) — The id of the most recently published episode of this podcast, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `latest_pub_date_ms` (optional, LatestPubDateMsField) - `LatestPubDateMsField` (integer) — The published date of the latest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `language` (optional, LanguageField) - `LanguageField` (string) — The language of this podcast. You can get all supported languages from `GET /languages`. - `description` (optional, PodcastDescriptionField) - `PodcastDescriptionField` (string) — Html of this episode's full description - `email` (optional, EmailField) - `EmailField` (string) — The email of this podcast's producer. This field is available only in the PRO/ENTERPRISE plan. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `country` (optional, CountryField) - `CountryField` (string) — The country where this podcast is produced. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `itunes_id` (optional, iTunesIdField) - `iTunesIdField` (integer) — iTunes id for this podcast. - `looking_for` (optional, PodcastLookingForField) - `PodcastLookingForField` (object) - `cohosts` (optional, boolean) — Whether this podcast is looking for cohosts. - `cross_promotion` (optional, boolean) — Whether this podcast is looking for cross promotion opportunities with other podcasts. - `sponsors` (optional, boolean) — Whether this podcast is looking for sponsors. - `guests` (optional, boolean) — Whether this podcast is looking for guests. - `extra` (optional, PodcastExtraField) - `PodcastExtraField` (object) - `youtube_url` (optional, string) — YouTube url affiliated with this podcast - `facebook_handle` (optional, string) — Facebook username affiliated with this podcast - `instagram_handle` (optional, string) — Instagram username affiliated with this podcast - `twitter_handle` (optional, string) — Twitter username affiliated with this podcast - `wechat_handle` (optional, string) — WeChat username affiliated with this podcast - `patreon_handle` (optional, string) — Patreon username affiliated with this podcast - `amazon_music_url` (optional, string) — Amazon Music url for this podcast - `linkedin_url` (optional, string) — LinkedIn url affiliated with this podcast - `spotify_url` (optional, string) — Spotify url for this podcast - `url1` (optional, string) — Url affiliated with this podcast - `url2` (optional, string) — Url affiliated with this podcast - `url3` (optional, string) — Url affiliated with this podcast - `genre_ids` (optional, GenreIdsField) - `GenreIdsField` (array) - Items: `integer` - `integer` — Genre ids. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - `has_guest_interviews` (optional, HasGuestInterviewsField) - `HasGuestInterviewsField` (boolean) — Whether this podcast has guest interviews. - `has_sponsors` (optional, HasSponsorsField) - `HasSponsorsField` (boolean) — Whether this podcast has sponsors. - `latest_episodes` (optional, array) — Up to 10 latest episodes from these podcasts, sorted by **pub_date**. This field shows up only when **show_latest_episodes** is 1. - Items: `EpisodeSimple` - `EpisodeSimple` (object) - `maybe_audio_invalid` (optional, MaybeAudioInvalidField) - `MaybeAudioInvalidField` (boolean) — Whether or not this episode's audio is invalid. Podcasters may delete the original audio. - `pub_date_ms` (optional, EpisodePubDateMsField) - `EpisodePubDateMsField` (integer) — Published date for this episode. It is an Epoch Unix timestamp in milliseconds. - `audio` (optional, AudioField) - `AudioField` (string) — Audio url of this episode, which can be played directly. - `listennotes_edit_url` (optional, EpisodeLNEditUrlField) - `EpisodeLNEditUrlField` (string) — Edit url of this episode where you can update the audio url if you find the audio is broken. - `image` (optional, EpisodeImageField) - `EpisodeImageField` (string) — Image url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork image. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, EpisodeThumbnailField) - `EpisodeThumbnailField` (string) — Thumbnail image (300x300) url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork thumbnail image. - `description` (optional, EpisodeDescriptionField) - `EpisodeDescriptionField` (string) — Html of this episode's full description - `title` (optional, EpisodeNameField) - `EpisodeNameField` (string) — Episode name. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `listennotes_url` (optional, EpisodeLNUrlField) - `EpisodeLNUrlField` (string) — The url of this episode on [ListenNotes.com](https://www.ListenNotes.com). - `audio_length_sec` (optional, AudioLengthSecField) - `AudioLengthSecField` (integer) — Audio length of this episode. In seconds. - `id` (optional, EpisodeIdField) - `EpisodeIdField` (string) — Episode id, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `link` (optional, LinkField) - `LinkField` (string) — Web link of this episode. - `podcast` (optional, PodcastMinimum) - `PodcastMinimum` (object) - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /podcasts/{id} **Fetch detailed meta data and episodes for a podcast by id** · Operation ID: `getPodcastById` Fetch detailed meta data and episodes for a specific podcast (up to 10 episodes each time). You can use the **next_episode_pub_date** parameter to do pagination and fetch more episodes. During pagination with **next_episode_pub_date**, an empty **episodes** array in the response signals that no more episodes are available. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `id` | path | yes | `string` | Podcast id. You can get podcast id from using other endpoints, e.g., `GET /search`, `GET /best_podcasts`... | | `next_episode_pub_date` | query | no | `integer` | For episodes pagination. It's the value of **next_episode_pub_date** from the response of last request. If not specified, just return latest 10 episodes or oldest 10 episodes, depending on the value of the **sort** parameter. It is an Epoch Unix timestamp in milliseconds. During pagination with **next_episode_pub_date**, an empty **episodes** array in the response signals that no more episodes are available. | | `sort` | query | no | `enum(recent_first \| oldest_first)` | How do you want to sort the episodes of this podcast? | **Responses** - **200** — OK - `PodcastFull` (object) - `episodes` (optional, array) - Items: `EpisodeMinimum` - `EpisodeMinimum` (object) - `maybe_audio_invalid` (optional, MaybeAudioInvalidField) - `MaybeAudioInvalidField` (boolean) — Whether or not this episode's audio is invalid. Podcasters may delete the original audio. - `pub_date_ms` (optional, EpisodePubDateMsField) - `EpisodePubDateMsField` (integer) — Published date for this episode. It is an Epoch Unix timestamp in milliseconds. - `audio` (optional, AudioField) - `AudioField` (string) — Audio url of this episode, which can be played directly. - `listennotes_edit_url` (optional, EpisodeLNEditUrlField) - `EpisodeLNEditUrlField` (string) — Edit url of this episode where you can update the audio url if you find the audio is broken. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `description` (optional, EpisodeDescriptionField) - `EpisodeDescriptionField` (string) — Html of this episode's full description - `title` (optional, EpisodeNameField) - `EpisodeNameField` (string) — Episode name. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `listennotes_url` (optional, EpisodeLNUrlField) - `EpisodeLNUrlField` (string) — The url of this episode on [ListenNotes.com](https://www.ListenNotes.com). - `audio_length_sec` (optional, AudioLengthSecField) - `AudioLengthSecField` (integer) — Audio length of this episode. In seconds. - `id` (optional, EpisodeIdField) - `EpisodeIdField` (string) — Episode id, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `link` (optional, LinkField) - `LinkField` (string) — Web link of this episode. - `is_claimed` (optional, IsClaimedField) - `IsClaimedField` (boolean) — Whether this podcast is claimed by its producer on [ListenNotes.com](https://www.ListenNotes.com). - `type` (optional, PodcastTypeField) - `PodcastTypeField` (enum(episodic | serial)) — The type of this podcast - episodic or serial. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `website` (optional, WebsiteField) - `WebsiteField` (string) — Website url of this podcast. - `total_episodes` (optional, TotalEpisodesField) - `TotalEpisodesField` (integer) — Total number of episodes in this podcast. - `audio_length_sec` (optional, AvgAudioLengthSecField) - `AvgAudioLengthSecField` (integer) — Average audio length of all episodes of this podcast. In seconds. - `update_frequency_hours` (optional, UpdateFrequencyHoursField) - `UpdateFrequencyHoursField` (integer) — How frequently does this podcast release a new episode? In hours. For example, if the value is 166, then it's every 166 hours (or weekly). - `earliest_pub_date_ms` (optional, EarliestPubDateMsField) - `EarliestPubDateMsField` (integer) — The published date of the oldest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `rss` (optional, RssField) - `RssField` (string) — RSS url of this podcast. This field is available only in the PRO/ENTERPRISE plan. - `latest_episode_id` (optional, LatestEpisodeIdField) - `LatestEpisodeIdField` (string) — The id of the most recently published episode of this podcast, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `latest_pub_date_ms` (optional, LatestPubDateMsField) - `LatestPubDateMsField` (integer) — The published date of the latest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `language` (optional, LanguageField) - `LanguageField` (string) — The language of this podcast. You can get all supported languages from `GET /languages`. - `description` (optional, PodcastDescriptionField) - `PodcastDescriptionField` (string) — Html of this episode's full description - `email` (optional, EmailField) - `EmailField` (string) — The email of this podcast's producer. This field is available only in the PRO/ENTERPRISE plan. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `country` (optional, CountryField) - `CountryField` (string) — The country where this podcast is produced. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `itunes_id` (optional, iTunesIdField) - `iTunesIdField` (integer) — iTunes id for this podcast. - `looking_for` (optional, PodcastLookingForField) - `PodcastLookingForField` (object) - `cohosts` (optional, boolean) — Whether this podcast is looking for cohosts. - `cross_promotion` (optional, boolean) — Whether this podcast is looking for cross promotion opportunities with other podcasts. - `sponsors` (optional, boolean) — Whether this podcast is looking for sponsors. - `guests` (optional, boolean) — Whether this podcast is looking for guests. - `extra` (optional, PodcastExtraField) - `PodcastExtraField` (object) - `youtube_url` (optional, string) — YouTube url affiliated with this podcast - `facebook_handle` (optional, string) — Facebook username affiliated with this podcast - `instagram_handle` (optional, string) — Instagram username affiliated with this podcast - `twitter_handle` (optional, string) — Twitter username affiliated with this podcast - `wechat_handle` (optional, string) — WeChat username affiliated with this podcast - `patreon_handle` (optional, string) — Patreon username affiliated with this podcast - `amazon_music_url` (optional, string) — Amazon Music url for this podcast - `linkedin_url` (optional, string) — LinkedIn url affiliated with this podcast - `spotify_url` (optional, string) — Spotify url for this podcast - `url1` (optional, string) — Url affiliated with this podcast - `url2` (optional, string) — Url affiliated with this podcast - `url3` (optional, string) — Url affiliated with this podcast - `genre_ids` (optional, GenreIdsField) - `GenreIdsField` (array) - Items: `integer` - `integer` — Genre ids. - `next_episode_pub_date` (optional, NextEpisodePubDateField) - `NextEpisodePubDateField` (integer) — Passed to the **next_episode_pub_date** parameter of `GET /podcasts/{id}` to paginate through episodes of that podcast. It is an Epoch Unix timestamp in milliseconds. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - `has_guest_interviews` (optional, HasGuestInterviewsField) - `HasGuestInterviewsField` (boolean) — Whether this podcast has guest interviews. - `has_sponsors` (optional, HasSponsorsField) - `HasSponsorsField` (boolean) — Whether this podcast has sponsors. - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /podcasts/{id}/recommendations **Fetch recommendations for a podcast** · Operation ID: `getPodcastRecommendations` Fetch up to 8 podcast recommendations based on the given podcast id. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `id` | path | yes | `string` | Podcast id. | | `safe_mode` | query | no | `enum(0 \| 1)` | Whether or not to exclude podcasts with explicit language. 1 is yes, and 0 is no. | **Responses** - **200** — OK - `GetPodcastRecommendationsResponse` (object) - `recommendations` (required, array) - Items: `PodcastSimple` - `PodcastSimple` (object) - `is_claimed` (optional, IsClaimedField) - `IsClaimedField` (boolean) — Whether this podcast is claimed by its producer on [ListenNotes.com](https://www.ListenNotes.com). - `type` (optional, PodcastTypeField) - `PodcastTypeField` (enum(episodic | serial)) — The type of this podcast - episodic or serial. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `website` (optional, WebsiteField) - `WebsiteField` (string) — Website url of this podcast. - `total_episodes` (optional, TotalEpisodesField) - `TotalEpisodesField` (integer) — Total number of episodes in this podcast. - `audio_length_sec` (optional, AvgAudioLengthSecField) - `AvgAudioLengthSecField` (integer) — Average audio length of all episodes of this podcast. In seconds. - `update_frequency_hours` (optional, UpdateFrequencyHoursField) - `UpdateFrequencyHoursField` (integer) — How frequently does this podcast release a new episode? In hours. For example, if the value is 166, then it's every 166 hours (or weekly). - `earliest_pub_date_ms` (optional, EarliestPubDateMsField) - `EarliestPubDateMsField` (integer) — The published date of the oldest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `rss` (optional, RssField) - `RssField` (string) — RSS url of this podcast. This field is available only in the PRO/ENTERPRISE plan. - `latest_episode_id` (optional, LatestEpisodeIdField) - `LatestEpisodeIdField` (string) — The id of the most recently published episode of this podcast, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `latest_pub_date_ms` (optional, LatestPubDateMsField) - `LatestPubDateMsField` (integer) — The published date of the latest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `language` (optional, LanguageField) - `LanguageField` (string) — The language of this podcast. You can get all supported languages from `GET /languages`. - `description` (optional, PodcastDescriptionField) - `PodcastDescriptionField` (string) — Html of this episode's full description - `email` (optional, EmailField) - `EmailField` (string) — The email of this podcast's producer. This field is available only in the PRO/ENTERPRISE plan. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `country` (optional, CountryField) - `CountryField` (string) — The country where this podcast is produced. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `itunes_id` (optional, iTunesIdField) - `iTunesIdField` (integer) — iTunes id for this podcast. - `looking_for` (optional, PodcastLookingForField) - `PodcastLookingForField` (object) - `cohosts` (optional, boolean) — Whether this podcast is looking for cohosts. - `cross_promotion` (optional, boolean) — Whether this podcast is looking for cross promotion opportunities with other podcasts. - `sponsors` (optional, boolean) — Whether this podcast is looking for sponsors. - `guests` (optional, boolean) — Whether this podcast is looking for guests. - `extra` (optional, PodcastExtraField) - `PodcastExtraField` (object) - `youtube_url` (optional, string) — YouTube url affiliated with this podcast - `facebook_handle` (optional, string) — Facebook username affiliated with this podcast - `instagram_handle` (optional, string) — Instagram username affiliated with this podcast - `twitter_handle` (optional, string) — Twitter username affiliated with this podcast - `wechat_handle` (optional, string) — WeChat username affiliated with this podcast - `patreon_handle` (optional, string) — Patreon username affiliated with this podcast - `amazon_music_url` (optional, string) — Amazon Music url for this podcast - `linkedin_url` (optional, string) — LinkedIn url affiliated with this podcast - `spotify_url` (optional, string) — Spotify url for this podcast - `url1` (optional, string) — Url affiliated with this podcast - `url2` (optional, string) — Url affiliated with this podcast - `url3` (optional, string) — Url affiliated with this podcast - `genre_ids` (optional, GenreIdsField) - `GenreIdsField` (array) - Items: `integer` - `integer` — Genre ids. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - `has_guest_interviews` (optional, HasGuestInterviewsField) - `HasGuestInterviewsField` (boolean) — Whether this podcast has guest interviews. - `has_sponsors` (optional, HasSponsorsField) - `HasSponsorsField` (boolean) — Whether this podcast has sponsors. - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /regions **Fetch a list of supported countries/regions for best podcasts** · Operation ID: `getRegions` It returns a dictionary of country codes (e.g., us, gb...) & country names (United States, United Kingdom...). The country code is used in the query parameter **region** of `GET /best_podcasts`. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | **Responses** - **200** — OK - `GetRegionsResponse` (object) - `regions` (required, object) - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ## Insights API ### GET /podcasts/{id}/audience **Fetch audience demographics for a podcast** · Operation ID: `getPodcastAudience` Fetch audience demographics for a podcast - 1) directly measured on the Listen Notes platform; 2) only supports audience breakdown by regions for now; 3) not every podcast has data. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `id` | path | yes | `string` | Podcast id. | **Responses** - **200** — OK - `PodcastAudienceResponse` (object) - `by_regions` (optional, array) - Items: `object` - `region` (optional, string) — 2-letter country code of a region. - `ratio` (optional, string) — percentage of audience from this specific region - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /podcasts/domains/{domain_name} **Fetch podcasts by a publisher's domain name** · Operation ID: `getPodcastsByDomainName` Fetch podcasts by a publisher's domain name, e.g., nytimes.com, wondery.com, npr.org... Each request will return up to 10 podcasts. You can use the `page` parameter to paginate. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `domain_name` | path | yes | `string` | A publisher's domain name, e.g., nytimes.com, wondery.com, npr.org... | | `page` | query | no | `integer` | Page number of the podcasts from this domain name | **Responses** - **200** — OK - `PodcastDomainResponse` (object) - `page_number` (optional, integer) - `has_next` (optional, boolean) - `next_page_number` (optional, integer) - `has_previous` (optional, boolean) - `previous_page_number` (optional, integer) - `podcasts` (optional, array) - Items: `PodcastSimple` - `PodcastSimple` (object) - `is_claimed` (optional, IsClaimedField) - `IsClaimedField` (boolean) — Whether this podcast is claimed by its producer on [ListenNotes.com](https://www.ListenNotes.com). - `type` (optional, PodcastTypeField) - `PodcastTypeField` (enum(episodic | serial)) — The type of this podcast - episodic or serial. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `website` (optional, WebsiteField) - `WebsiteField` (string) — Website url of this podcast. - `total_episodes` (optional, TotalEpisodesField) - `TotalEpisodesField` (integer) — Total number of episodes in this podcast. - `audio_length_sec` (optional, AvgAudioLengthSecField) - `AvgAudioLengthSecField` (integer) — Average audio length of all episodes of this podcast. In seconds. - `update_frequency_hours` (optional, UpdateFrequencyHoursField) - `UpdateFrequencyHoursField` (integer) — How frequently does this podcast release a new episode? In hours. For example, if the value is 166, then it's every 166 hours (or weekly). - `earliest_pub_date_ms` (optional, EarliestPubDateMsField) - `EarliestPubDateMsField` (integer) — The published date of the oldest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `rss` (optional, RssField) - `RssField` (string) — RSS url of this podcast. This field is available only in the PRO/ENTERPRISE plan. - `latest_episode_id` (optional, LatestEpisodeIdField) - `LatestEpisodeIdField` (string) — The id of the most recently published episode of this podcast, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `latest_pub_date_ms` (optional, LatestPubDateMsField) - `LatestPubDateMsField` (integer) — The published date of the latest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `language` (optional, LanguageField) - `LanguageField` (string) — The language of this podcast. You can get all supported languages from `GET /languages`. - `description` (optional, PodcastDescriptionField) - `PodcastDescriptionField` (string) — Html of this episode's full description - `email` (optional, EmailField) - `EmailField` (string) — The email of this podcast's producer. This field is available only in the PRO/ENTERPRISE plan. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `country` (optional, CountryField) - `CountryField` (string) — The country where this podcast is produced. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `itunes_id` (optional, iTunesIdField) - `iTunesIdField` (integer) — iTunes id for this podcast. - `looking_for` (optional, PodcastLookingForField) - `PodcastLookingForField` (object) - `cohosts` (optional, boolean) — Whether this podcast is looking for cohosts. - `cross_promotion` (optional, boolean) — Whether this podcast is looking for cross promotion opportunities with other podcasts. - `sponsors` (optional, boolean) — Whether this podcast is looking for sponsors. - `guests` (optional, boolean) — Whether this podcast is looking for guests. - `extra` (optional, PodcastExtraField) - `PodcastExtraField` (object) - `youtube_url` (optional, string) — YouTube url affiliated with this podcast - `facebook_handle` (optional, string) — Facebook username affiliated with this podcast - `instagram_handle` (optional, string) — Instagram username affiliated with this podcast - `twitter_handle` (optional, string) — Twitter username affiliated with this podcast - `wechat_handle` (optional, string) — WeChat username affiliated with this podcast - `patreon_handle` (optional, string) — Patreon username affiliated with this podcast - `amazon_music_url` (optional, string) — Amazon Music url for this podcast - `linkedin_url` (optional, string) — LinkedIn url affiliated with this podcast - `spotify_url` (optional, string) — Spotify url for this podcast - `url1` (optional, string) — Url affiliated with this podcast - `url2` (optional, string) — Url affiliated with this podcast - `url3` (optional, string) — Url affiliated with this podcast - `genre_ids` (optional, GenreIdsField) - `GenreIdsField` (array) - Items: `integer` - `integer` — Genre ids. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - `has_guest_interviews` (optional, HasGuestInterviewsField) - `HasGuestInterviewsField` (boolean) — Whether this podcast has guest interviews. - `has_sponsors` (optional, HasSponsorsField) - `HasSponsorsField` (boolean) — Whether this podcast has sponsors. - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ## Playlist API ### GET /playlists **Fetch a list of your playlists.** · Operation ID: `getPlaylists` This endpoint returns same data as listennotes.com/listen under your account. You can use the **page** parameter to do pagination and fetch more playlists. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `sort` | query | no | `enum(recent_added_first \| oldest_added_first \| name_a_to_z \| name_z_to_a)` | How do you want to sort playlists? | | `page` | query | no | `integer` | Page number of playlists. | **Responses** - **200** — OK - `PlaylistsResponse` (object) - `previous_page_number` (optional, integer) - `page_number` (optional, integer) - `has_next` (optional, boolean) - `has_previous` (optional, boolean) - `next_page_number` (optional, integer) - `total` (optional, integer) - `playlists` (optional, array) - Items: `object` - `episode_count` (optional, integer) — The number of episodes (including custom audio) in this playlist. - `podcast_count` (optional, integer) — The number of podcasts in this playlist. - `total_audio_length_sec` (optional, integer) — Total audio length of all episodes in this playlist, in seconds. - `id` (optional, PlaylistIdField) - `PlaylistIdField` (string) — A 11-character playlist id, which can be used to further fetch detailed playlist metadata via `GET /playlists/{id}`. - `name` (optional, PlaylistNameField) - `PlaylistNameField` (string) — Playlist name. - `description` (optional, PlaylistDescriptionField) - `PlaylistDescriptionField` (string) — Playlist description. - `image` (optional, PlaylistImageField) - `PlaylistImageField` (string) — High resolution image url of the playlist. - `thumbnail` (optional, PlaylistThumbnailField) - `PlaylistThumbnailField` (string) — Low resolution image url of the playlist. - `listennotes_url` (optional, PlaylistListennotesUrlField) - `PlaylistListennotesUrlField` (string) — The url of this playlist on ListenNotes.com. - `visibility` (optional, PlaylistVisibilityField) - `PlaylistVisibilityField` (enum(public | unlisted | private)) — Visibility of this playlist. - `last_timestamp_ms` (optional, PlaylistLastTimestampMsField) - `PlaylistLastTimestampMsField` (integer) — Passed to the **last_timestamp_ms** parameter of `GET /playlists/{id}` to paginate through items of that playlist. It is an Epoch Unix timestamp in milliseconds. - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /playlists/{id} **Fetch a playlist's info and items (i.e., episodes or podcasts).** · Operation ID: `getPlaylistById` A playlist can be an episode list (i.e., all items are episodes) or a podcast list (i.e., all items are podcasts), which is essentially the same as those created via listennotes.com/listen/. This endpoint fetches a list of items (i.e., episodes or podcasts) in the playlist. You can use the **last_pub_date_ms** parameter to do pagination and fetch more items. A playlist can be **public** (discoverable on ListenNotes.com), **unlisted** (accessible to anyone who knows the playlist id), or **private** (accessible to its owner). You can fetch all playlists created by you, and **public** / **unlisted** playlists created by others. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `id` | path | yes | `string` | Playlist id (always 11 characters, e.g., m1pe7z60bsw). You can get the podcast id from the url of a playlist, e.g., m1pe7z60bsw is the playlist id of listennotes.com/listen/podcasts-about-podcasting-m1pe7z60bsw | | `type` | query | no | `enum(episode_list \| podcast_list)` | The type of this playlist, which should be either **episode_list** or **podcast_list**. | | `last_timestamp_ms` | query | no | `integer` | For playlist items pagination. It's the value of **last_timestamp_ms** from the response of last request. If it's 0 or not specified, just return the latest or the oldest 20 items, depending on the value of the **sort** parameter. It is an Epoch Unix timestamp in milliseconds. | | `sort` | query | no | `enum(recent_added_first \| oldest_added_first \| recent_published_first \| oldest_published_first)` | How do you want to sort playlist items? | **Responses** - **200** — OK - `PlaylistResponse` (object) - `id` (optional, PlaylistIdField) - `PlaylistIdField` (string) — A 11-character playlist id, which can be used to further fetch detailed playlist metadata via `GET /playlists/{id}`. - `name` (optional, PlaylistNameField) - `PlaylistNameField` (string) — Playlist name. - `description` (optional, PlaylistDescriptionField) - `PlaylistDescriptionField` (string) — Playlist description. - `image` (optional, PlaylistImageField) - `PlaylistImageField` (string) — High resolution image url of the playlist. - `thumbnail` (optional, PlaylistThumbnailField) - `PlaylistThumbnailField` (string) — Low resolution image url of the playlist. - `listennotes_url` (optional, PlaylistListennotesUrlField) - `PlaylistListennotesUrlField` (string) — The url of this playlist on ListenNotes.com. - `visibility` (optional, PlaylistVisibilityField) - `PlaylistVisibilityField` (enum(public | unlisted | private)) — Visibility of this playlist. - `last_timestamp_ms` (optional, PlaylistLastTimestampMsField) - `PlaylistLastTimestampMsField` (integer) — Passed to the **last_timestamp_ms** parameter of `GET /playlists/{id}` to paginate through items of that playlist. It is an Epoch Unix timestamp in milliseconds. - `total` (optional, integer) — Total number of items in this playlist. - `total_audio_length_sec` (optional, integer) — Total audio length of all episodes in this playlist, in seconds. It will have a valid value only when type is **episode_list**. In other words, it will be 0 if type is **podcast_list**. - `type` (optional, enum(episode_list | podcast_list)) — The type of this playlist, which should be either **episode_list** or **podcast_list**. - `items` (optional, array) — A list of playlist items. - Items: `PlaylistItem` - `PlaylistItem` (object) — An item in a playlist - `id` (optional, integer) — Playlist item id. - `type` (optional, enum(episode | custom_audio | podcast)) — The type of this playlist item. If a playlist is **episode_list**, then an item could be either **episode** or **custom_audio**. If it's **podcast_list**, then an item can only be **podcast**. - `notes` (optional, string) — Notes for this item. - `added_at_ms` (optional, integer) — Timestamp when this item is added. It is an Epoch Unix timestamp in milliseconds. - `data` (optional, any) - oneOf: - `EpisodeSimple` - `EpisodeSimple` (object) - `maybe_audio_invalid` (optional, MaybeAudioInvalidField) - `pub_date_ms` (optional, EpisodePubDateMsField) - `audio` (optional, AudioField) - `listennotes_edit_url` (optional, EpisodeLNEditUrlField) - `image` (optional, EpisodeImageField) - `thumbnail` (optional, EpisodeThumbnailField) - `description` (optional, EpisodeDescriptionField) - `title` (optional, EpisodeNameField) - `explicit_content` (optional, ExplicitField) - `listennotes_url` (optional, EpisodeLNUrlField) - `audio_length_sec` (optional, AudioLengthSecField) - `id` (optional, EpisodeIdField) - `link` (optional, LinkField) - `podcast` (optional, PodcastMinimum) - `PodcastSimple` - `PodcastSimple` (object) - `is_claimed` (optional, IsClaimedField) - `type` (optional, PodcastTypeField) - `explicit_content` (optional, ExplicitField) - `website` (optional, WebsiteField) - `total_episodes` (optional, TotalEpisodesField) - `audio_length_sec` (optional, AvgAudioLengthSecField) - `update_frequency_hours` (optional, UpdateFrequencyHoursField) - `earliest_pub_date_ms` (optional, EarliestPubDateMsField) - `rss` (optional, RssField) - `latest_episode_id` (optional, LatestEpisodeIdField) - `latest_pub_date_ms` (optional, LatestPubDateMsField) - `title` (optional, PodcastNameField) - `language` (optional, LanguageField) - `description` (optional, PodcastDescriptionField) - `email` (optional, EmailField) - `image` (optional, ImageField) - `thumbnail` (optional, ThumbnailField) - `listennotes_url` (optional, PodcastLNUrlField) - `id` (optional, PodcastIdField) - `country` (optional, CountryField) - `publisher` (optional, PublisherField) - `itunes_id` (optional, iTunesIdField) - `looking_for` (optional, PodcastLookingForField) - `extra` (optional, PodcastExtraField) - `genre_ids` (optional, GenreIdsField) - `listen_score` (optional, ListenScoreField) - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `has_guest_interviews` (optional, HasGuestInterviewsField) - `has_sponsors` (optional, HasSponsorsField) - `CustomAudio` - `CustomAudio` (object) — A custom audio in a playlist, which is a type of playlist item. - `title` (optional, string) — Custom audio title. - `audio` (optional, string) — Audio url, which can be played directly. - `audio_length_sec` (optional, integer) — Audio length in seconds. - `image` (optional, string) — High resolution image url of this custom audio. - `thumbnail` (optional, string) — Low resolution image url of this custom audio. - `pub_date_ms` (optional, integer) — Published date of this custom audio. For now, it's the same as **added_at_ms** of this playlist item. It is an Epoch Unix timestamp in milliseconds. - `DeletedItem` - `DeletedItem` (object) — A deleted episode or podcast. An episode or a podcast could be deleted from our podcast database. Possible reasons: 1) Podcast producers sometimes delete their old episodes. 2) Copyright issues. - `id` (optional, string) — Episode id or podcast id. - `title` (optional, string) — Episode title or podcast title. - `status` (optional, string) — The status of this episode or podcast. For now, the only possible value is **deleted**. - `error` (optional, string) — Why this episode or podcast is deleted? - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ## Podcaster API ### DELETE /podcasts/{id} **Request to delete a podcast** · Operation ID: `deletePodcastById` Podcast hosting services can use this endpoint to streamline the process of podcast deletion on behave of their users (podcasters). We will review the deletion request within 12 hours. If the podcast is already deleted, the "status" field in the response will be "deleted". Otherwise, the status field will be "in review". If you want to get a notification once the podcast is deleted, you can configure a webhook url in the dashboard: listennotes.com/api/dashboard/#webhooks **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `id` | path | yes | `string` | Podcast id. You can get podcast id from using other endpoints, e.g., `GET /search`, `GET /best_podcasts`... | | `reason` | query | no | `string` | The reason why this podcast should be deleted, e.g., copyright violation, the podcaster wants to delete it... You can put "testing" here to indicate that you are testing this endpoint, so we will not actually delete the podcast. | **Responses** - **200** — OK - `DeletePodcastResponse` (object) - `status` (required, enum(deleted | in review)) — The status of this podcast deletion request. - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### POST /podcasts/{id}/rss **Refresh RSS feed of a podcast** · Operation ID: `refreshRss` Refresh a podcast's RSS feed. Each podcast is limited to one refresh per hour. Refresh durations range from a few seconds to several minutes, contingent on the RSS feed size and server responsiveness. This endpoint is available only in the PRO/ENTERPRISE plan. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `id` | path | yes | `string` | Podcast id. You can get podcast id from using other endpoints, e.g., `GET /search`, `GET /best_podcasts`... | **Responses** - **200** — OK - `RefreshRssResponse` (object) - `status` (required, enum(refreshing | refreshed)) — The status of the rss refreshing request. - `last_refreshed_at_ms` (optional, integer) — The timestamp when the rss was last refreshed. It is an Epoch Unix timestamp in milliseconds. - **401** — Wrong api key, or your account is suspended. - **404** — Endpoint not exist, or podcast / episode not exist. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### POST /podcasts/submit **Submit a podcast to Listen Notes database** · Operation ID: `submitPodcast` Podcast hosting services can use this endpoint to help your users directly submit a new podcast to Listen Notes database. If the podcast doesn't exist in the database, "status" in the response will be "in review", and we'll review it within 12 hours. If the podcast exists, "status" in the response will be "found". If this submission is rejected, "status" in the response will be "rejected". You can use `POST /podcasts` to check if multiple podcasts exist in the database. If you want to get a notification once the podcast is accepted, you can either specify the "email" parameter or configure a webhook url in the dashboard: listennotes.com/api/dashboard/#webhooks **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | **Request body (required)** - `SubmitPodcastForm` (object) - `rss` (required, string) — A valid podcast rss url. - `email` (optional, string) — A valid email address. If **email** is specified, then we'll notify this email address once the podcast is accepted. **Responses** - **200** — OK - `SubmitPodcastResponse` (object) - `status` (required, enum(found | in review | rejected)) — The status of this submission. - `podcast` (required, PodcastMinimum) - `PodcastMinimum` (object) - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `title` (optional, PodcastNameField) - `PodcastNameField` (string) — Podcast name. - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `publisher` (optional, PublisherField) - `PublisherField` (string) — Podcast publisher name. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - **400** — Something wrong on your end (Client side errors), e.g., missing required parameters. - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ## Search API ### GET /related_searches **Fetch related search terms** · Operation ID: `getRelatedSearches` Suggest related search terms. The results are more comprehensive than from `GET /typeahead`. This endpoint is available only in the PRO/ENTERPRISE plan. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `q` | query | yes | `string` | Search term, e.g., person, place, topic... | **Responses** - **200** — OK - `RelatedSearchesResponse` (object) - `terms` (required, array) — Related search terms - Items: `string` - `string` - **400** — Something wrong on your end (Client side errors), e.g., missing required parameters. - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /search **Full-text search** · Operation ID: `search` Full-text search on episodes, podcasts, or curated lists of podcasts. Use the `offset` parameter to paginate through search results. The FREE plan allows to see up to 30 search results (or `offset` < 30) per query. The PRO plan allows to see up to 300 search results (or `offset` < 300) per query. The ENTERPRISE plan allows to see up to 10,000 search results (or `offset` < 10000) per query. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `q` | query | yes | `string` | Search term, e.g., person, place, topic... You can use double quotes to do verbatim match, e.g., "game of thrones". Otherwise, it's fuzzy search. | | `sort_by_date` | query | no | `enum(0 \| 1)` | Sort by date or not? If 0, then sort by relevance. If 1, then sort by date. | | `type` | query | no | `enum(episode \| podcast \| curated)` | What type of contents do you want to search for? | | `offset` | query | no | `integer` | Offset for search results, for pagination. You'll use **next_offset** from response for this parameter. | | `len_min` | query | no | `integer` | Minimum audio length in minutes. Applicable only when **type** parameter is **episode** or **podcast**. If **type** parameter is **episode**, it's for audio length of an episode. If **type** parameter is **podcast**, it's for average audio length of all episodes in a podcast. | | `len_max` | query | no | `integer` | Maximum audio length in minutes. Applicable only when **type** parameter is **episode** or **podcast**. If **type** parameter is **episode**, it's for audio length of an episode. If **type** parameter is **podcast**, it's for average audio length of all episodes in a podcast. | | `episode_count_min` | query | no | `integer` | Minimum number of episodes. Applicable only when type parameter is **podcast**. | | `episode_count_max` | query | no | `integer` | Maximum number of episodes. Applicable only when type parameter is **podcast**. | | `update_freq_min` | query | no | `integer` | Minimum update frequency in hours (how frequently does a podcast release a new episode). For example, if you want to find "weekly" podcasts, then you can set **update_freq_min**=144 hours (or 6 days) and **update_freq_max**=192 hours (or 8 days). Applicable only when type parameter is **podcast**. | | `update_freq_max` | query | no | `integer` | Maximum update frequency in hours (how frequently does a podcast release a new episode). For example, if you want to find "weekly" podcasts, then you can set **update_freq_min**=144 hours (or 6 days) and **update_freq_max**=192 hours (or 8 days). Applicable only when type parameter is **podcast**. | | `genre_ids` | query | no | `string` | A comma-delimited string of a list of genre ids. If not specified, then all genres are included. You can find the id and the name of all genres from `GET /genres`. It works only when **type** is *episode* or *podcast*. | | `published_before` | query | no | `integer` | Only show episodes/podcasts/curated lists published before this Epoch Unix timestamp (in milliseconds). If **published_before** & **published_after** are used at the same time, **published_before** should be bigger than **published_after**. | | `published_after` | query | no | `integer` | Only show episodes/podcasts/curated lists published after this Epoch Unix timestamp (in milliseconds). If **published_before** & **published_after** are used at the same time, **published_before** should be bigger than **published_after**. | | `only_in` | query | no | `string` | A comma-delimited string to search only in specific fields. Allowed values are title, description, author, and audio. If not specified, then search every fields. | | `language` | query | no | `string` | Limit search results to a specific language. If not specified, it'll be any language. You can get a list of supported languages from `GET /languages`. It works only when **type** is *episode* or *podcast*. | | `region` | query | no | `string` | Limit search results to a specific region (e.g., us, gb, in...). If not specified, it'll be any region. You can get the supported country codes from `GET /regions`. It works only when **type** is *episode* or *podcast*. | | `ocid` | query | no | `string` | A comma-delimited string of podcast ids (up to 5 podcasts) - you can get a podcast id from the **podcast_id** field in response. This parameter is to limit search results from only a few specific podcasts. It works only when **type** is *episode*. | | `ncid` | query | no | `string` | A comma-delimited string of podcast ids (up to 5 podcasts) - you can get a podcast id from the **podcast_id** field in response. This parameter is to exclude search results of a few specific podcasts. It works only when **type** is *episode*. | | `safe_mode` | query | no | `enum(0 \| 1)` | Whether or not to exclude podcasts/episodes with explicit language. 1 is yes and 0 is no. It works only when **type** is *episode* or *podcast*. | | `unique_podcasts` | query | no | `enum(0 \| 1)` | Whether or not to keep only one episode per podcast in search results. 1 is yes and 0 is no. It works only when **type** is *episode*. | | `interviews_only` | query | no | `enum(0 \| 1)` | Whether or not to keep only podcasts that have guest interviews in search results. 1 is yes and 0 is no. It works only when **type** is *podcast*. This parameter is available only in the PRO/ENTERPRISE plan. | | `sponsored_only` | query | no | `enum(0 \| 1)` | Whether or not to keep only podcasts that have sponsors in search results. 1 is yes and 0 is no. It works only when **type** is *podcast*. This parameter is available only in the PRO/ENTERPRISE plan. | | `page_size` | query | no | `integer` | The maximum number of search results per page. A valid value should be an integer between 1 and 10 (inclusive). | **Responses** - **200** — OK - `SearchResponse` (object) - `next_offset` (optional, integer) — Pass this value to the **offset** parameter to do pagination of search results. - `took` (optional, number) — The time it took to fetch these search results. In seconds. - `total` (optional, integer) — The total number of search results. - `count` (optional, integer) — The number of search results in this page. - `results` (optional, array) — A list of search results. - Items: `any` - oneOf: - `EpisodeSearchResult` - `EpisodeSearchResult` (object) — When **type** is *episode*. - `audio` (optional, AudioField) - `AudioField` (string) — Audio url of this episode, which can be played directly. - `audio_length_sec` (optional, AudioLengthSecField) - `AudioLengthSecField` (integer) — Audio length of this episode. In seconds. - `rss` (optional, RssField) - `RssField` (string) — RSS url of this podcast. This field is available only in the PRO/ENTERPRISE plan. - `description_highlighted` (optional, string) — Highlighted segment of this episode's description - `description_original` (optional, string) — Plain text of this episode's description - `title_highlighted` (optional, string) — Highlighted segment of this episode's title - `title_original` (optional, string) — Plain text of this episode' title - `transcripts_highlighted` (optional, array) — Up to 2 highlighted segments of the audio transcript of this episode. - Items: `string` - `image` (optional, EpisodeImageField) - `EpisodeImageField` (string) — Image url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork image. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, EpisodeThumbnailField) - `EpisodeThumbnailField` (string) — Thumbnail image (300x300) url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork thumbnail image. - `itunes_id` (optional, iTunesIdField) - `iTunesIdField` (integer) — iTunes id for this podcast. - `pub_date_ms` (optional, EpisodePubDateMsField) - `EpisodePubDateMsField` (integer) — Published date for this episode. It is an Epoch Unix timestamp in milliseconds. - `id` (optional, EpisodeIdField) - `EpisodeIdField` (string) — Episode id, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `listennotes_url` (optional, EpisodeLNUrlField) - `EpisodeLNUrlField` (string) — The url of this episode on [ListenNotes.com](https://www.ListenNotes.com). - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `link` (optional, LinkField) - `LinkField` (string) — Web link of this episode. - `podcast` (optional, object) — The podcast that this episode belongs to. - `id` (optional, PodcastIdField) - `genre_ids` (optional, GenreIdsField) - `listennotes_url` (optional, PodcastLNUrlField) - `title_highlighted` (optional, PodcastTitleHighlightedField) - `title_original` (optional, PodcastTitleOriginalField) - `publisher_highlighted` (optional, PublisherHighlightedField) - `publisher_original` (optional, PublisherOriginalField) - `image` (optional, ImageField) - `thumbnail` (optional, ThumbnailField) - `listen_score` (optional, ListenScoreField) - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `PodcastSearchResult` - `PodcastSearchResult` (object) — When **type** is *podcast*. - `rss` (optional, RssField) - `RssField` (string) — RSS url of this podcast. This field is available only in the PRO/ENTERPRISE plan. - `description_highlighted` (optional, string) — Highlighted segment of podcast description - `description_original` (optional, string) — Plain text of podcast description - `title_highlighted` (optional, PodcastTitleHighlightedField) - `PodcastTitleHighlightedField` (string) — Highlighted segment of podcast name. - `title_original` (optional, PodcastTitleOriginalField) - `PodcastTitleOriginalField` (string) — Plain text of podcast name. - `publisher_highlighted` (optional, PublisherHighlightedField) - `PublisherHighlightedField` (string) — Highlighted segment of this podcast's publisher name. - `publisher_original` (optional, PublisherOriginalField) - `PublisherOriginalField` (string) — Plain text of this podcast's publisher name. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `itunes_id` (optional, iTunesIdField) - `iTunesIdField` (integer) — iTunes id for this podcast. - `latest_episode_id` (optional, LatestEpisodeIdField) - `LatestEpisodeIdField` (string) — The id of the most recently published episode of this podcast, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `latest_pub_date_ms` (optional, LatestPubDateMsField) - `LatestPubDateMsField` (integer) — The published date of the latest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `earliest_pub_date_ms` (optional, EarliestPubDateMsField) - `EarliestPubDateMsField` (integer) — The published date of the oldest episode of this podcast. It is an Epoch Unix timestamp in milliseconds. - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `genre_ids` (optional, GenreIdsField) - `GenreIdsField` (array) - Items: `integer` - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `total_episodes` (optional, TotalEpisodesField) - `TotalEpisodesField` (integer) — Total number of episodes in this podcast. - `audio_length_sec` (optional, AvgAudioLengthSecField) - `AvgAudioLengthSecField` (integer) — Average audio length of all episodes of this podcast. In seconds. - `update_frequency_hours` (optional, UpdateFrequencyHoursField) - `UpdateFrequencyHoursField` (integer) — How frequently does this podcast release a new episode? In hours. For example, if the value is 166, then it's every 166 hours (or weekly). - `email` (optional, EmailField) - `EmailField` (string) — The email of this podcast's producer. This field is available only in the PRO/ENTERPRISE plan. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `website` (optional, WebsiteField) - `WebsiteField` (string) — Website url of this podcast. - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - `has_guest_interviews` (optional, HasGuestInterviewsField) - `HasGuestInterviewsField` (boolean) — Whether this podcast has guest interviews. - `has_sponsors` (optional, HasSponsorsField) - `HasSponsorsField` (boolean) — Whether this podcast has sponsors. - `CuratedListSearchResult` - `CuratedListSearchResult` (object) — When **type** is *curated*. - `id` (optional, CuratedIdField) - `CuratedIdField` (string) — Curated list id, which can be used to further fetch detailed curated list metadata via `GET /curated_podcasts/{id}`. - `pub_date_ms` (optional, CuratedPubDateMsField) - `CuratedPubDateMsField` (integer) — Published date of this curated list. It is an Epoch Unix timestamp in milliseconds. - `description_highlighted` (optional, string) — Highlighted segment of this curated list's description - `description_original` (optional, string) — Plain text of this curated list's description - `title_highlighted` (optional, string) — Highlighted segment of this curated list's title - `title_original` (optional, string) — Plain text of this curated list's title - `listennotes_url` (optional, CuratedLNUrlField) - `CuratedLNUrlField` (string) — The url of this curated list on [ListenNotes.com](https://www.ListenNotes.com). - `source_url` (optional, CuratedSourceUrlField) - `CuratedSourceUrlField` (string) — Url of the source of this curated list. - `source_domain` (optional, CuratedSourceDomainField) - `CuratedSourceDomainField` (string) — The domain name of the source of this curated list. - `total` (optional, CuratedTotalPodcastsField) - `CuratedTotalPodcastsField` (integer) — The total number of podcasts in this curated list. - `podcasts` (optional, array) — Up to 5 podcasts in this curated list. - Items: `PodcastMinimum` - **400** — Something wrong on your end (Client side errors), e.g., missing required parameters. - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /search_episode_titles **Find individual episodes by searching for their titles** · Operation ID: `searchEpisodeTitles` Conduct targeted searches for individual episodes by title and refine results using the podcast id such as Listen Notes Podcast ID, Apple Podcasts ID, Spotify ID, or RSS feed URL. This endpoint is specially designed to streamline the import of specific episodes from platforms like Apple Podcasts and Spotify into your application. Compared to the GET /search endpoint, which performs full-text searches across multiple fields, this endpoint focuses solely on episode titles for enhanced accuracy and performance. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `q` | query | yes | `string` | An episode's title, e.g., Jerusalem Demsas on The Dispossessed. You can use double quotes to do verbatim match, e.g., "Jerusalem Demsas on The Dispossessed". Otherwise, it's fuzzy search. | | `podcast_id` | query | no | `string` | Refine search results by specifying a podcast through its unique ID. The format of the podcast ID is governed by the podcast_id_type parameter. For listennotes_id, the podcast ID will look like 'cda18f20f1be4ac7b3cce7d0eb168fff'. For itunes_id, it will be a numerical value like '983795625'. For spotify_id, expect a format like '0Z1234tGXD2hVhjFrrhJ7g'. For rss, the podcast ID will be the RSS URL, e.g., 'https://cowenconvos.libsyn.com/rss'. | | `podcast_id_type` | query | no | `enum(listennotes_id \| itunes_id \| spotify_id \| rss)` | The type of podcast id. Valid values are **listennotes_id**, **itunes_id**, **spotify_id**, and **rss**. Note: **itunes_id** is for Apple Podcasts. | **Responses** - **200** — OK - `next_offset` (optional, integer) — Pass this value to the **offset** parameter to do pagination of search results. - `took` (optional, number) — The time it took to fetch these search results. In seconds. - `total` (optional, integer) — The total number of search results. - `count` (optional, integer) — The number of search results in this page. - `results` (optional, array) — A list of search results. - Items: `EpisodeSearchResult` - `EpisodeSearchResult` (object) — When **type** is *episode*. - `audio` (optional, AudioField) - `AudioField` (string) — Audio url of this episode, which can be played directly. - `audio_length_sec` (optional, AudioLengthSecField) - `AudioLengthSecField` (integer) — Audio length of this episode. In seconds. - `rss` (optional, RssField) - `RssField` (string) — RSS url of this podcast. This field is available only in the PRO/ENTERPRISE plan. - `description_highlighted` (optional, string) — Highlighted segment of this episode's description - `description_original` (optional, string) — Plain text of this episode's description - `title_highlighted` (optional, string) — Highlighted segment of this episode's title - `title_original` (optional, string) — Plain text of this episode' title - `transcripts_highlighted` (optional, array) — Up to 2 highlighted segments of the audio transcript of this episode. - Items: `string` - `string` - `image` (optional, EpisodeImageField) - `EpisodeImageField` (string) — Image url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork image. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, EpisodeThumbnailField) - `EpisodeThumbnailField` (string) — Thumbnail image (300x300) url for this episode. If an episode doesn't have its own image, then this field would be the url of the podcast artwork thumbnail image. - `itunes_id` (optional, iTunesIdField) - `iTunesIdField` (integer) — iTunes id for this podcast. - `pub_date_ms` (optional, EpisodePubDateMsField) - `EpisodePubDateMsField` (integer) — Published date for this episode. It is an Epoch Unix timestamp in milliseconds. - `id` (optional, EpisodeIdField) - `EpisodeIdField` (string) — Episode id, which can be used to further fetch detailed episode metadata via `GET /episodes/{id}`. - `listennotes_url` (optional, EpisodeLNUrlField) - `EpisodeLNUrlField` (string) — The url of this episode on [ListenNotes.com](https://www.ListenNotes.com). - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `link` (optional, LinkField) - `LinkField` (string) — Web link of this episode. - `podcast` (optional, object) — The podcast that this episode belongs to. - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - `genre_ids` (optional, GenreIdsField) - `GenreIdsField` (array) - Items: `integer` - `integer` — Genre ids. - `listennotes_url` (optional, PodcastLNUrlField) - `PodcastLNUrlField` (string) — The url of this podcast on [ListenNotes.com](https://www.ListenNotes.com). - `title_highlighted` (optional, PodcastTitleHighlightedField) - `PodcastTitleHighlightedField` (string) — Highlighted segment of podcast name. - `title_original` (optional, PodcastTitleOriginalField) - `PodcastTitleOriginalField` (string) — Plain text of podcast name. - `publisher_highlighted` (optional, PublisherHighlightedField) - `PublisherHighlightedField` (string) — Highlighted segment of this podcast's publisher name. - `publisher_original` (optional, PublisherOriginalField) - `PublisherOriginalField` (string) — Plain text of this podcast's publisher name. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `listen_score` (optional, ListenScoreField) - `ListenScoreField` (integer) — The estimated popularity score of a podcast compared to all other rss-based public podcasts in the world on a scale from 0 to 100. If the score is not available, it'll be null. Learn more at listennotes.com/listen-score - `listen_score_global_rank` (optional, ListenScoreGlobalRankField) - `ListenScoreGlobalRankField` (string) — The estimated popularity ranking of a podcast compared to all other rss-based public podcasts in the world. For example, if the value is 0.5%, then this podcast is one of the top 0.5% most popular shows out of all podcasts globally, ranked by Listen Score. If the ranking is not available, it'll be null. Learn more at listennotes.com/listen-score - **400** — Something wrong on your end (Client side errors), e.g., missing required parameters. - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /spellcheck **Spell check on a search term** · Operation ID: `spellcheck` Suggest a list of words that correct the spelling errors of a search term. This endpoint is available only in the PRO/ENTERPRISE plan. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `q` | query | yes | `string` | Search term, e.g., person, place, topic... | **Responses** - **200** — OK - `SpellCheckResponse` (object) - `tokens` (required, array) — The word in the text query string that is not spelled correctly - Items: `object` - `offset` (optional, integer) — The zero-based offset from the beginning of the text query string to the word that is misspelled - `token` (optional, string) — The misspelled word - `suggestion` (optional, string) — A word that corrects the spelling error - `corrected_text_html` (required, string) — The corrected text for the entire search term (multiple words/tokens), where misspelled tokens are replaced with the correct texts and html tags - **400** — Something wrong on your end (Client side errors), e.g., missing required parameters. - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /trending_searches **Fetch trending search terms** · Operation ID: `getTrendingSearches` Fetch up to 10 most recent trending search terms on the Listen Notes platform. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | **Responses** - **200** — OK - `TrendingSearchesResponse` (object) - `terms` (required, array) — Trending search terms - Items: `string` - `string` - **400** — Something wrong on your end (Client side errors), e.g., missing required parameters. - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). ### GET /typeahead **Typeahead search** · Operation ID: `typeahead` Suggest search terms, podcast genres, and podcasts. **Parameters** | Name | In | Required | Type | Description | | --- | --- | --- | --- | --- | | `X-ListenAPI-Key` | header | yes | `string` | Get API Key on listennotes.com/api | | `q` | query | yes | `string` | Search term, e.g., person, place, topic... You can use double quotes to do verbatim match, e.g., "game of thrones". Otherwise, it's fuzzy search. | | `show_podcasts` | query | no | `enum(0 \| 1)` | Autosuggest podcasts. This only searches podcast title and publisher and returns very limited info of 5 podcasts. 1 is yes, 0 is no. It's a bit slow to autosuggest podcasts, so we turn it off by default. If show_podcasts=1, you can also pass iTunes id (e.g., 474722933) to the q parameter to fetch podcast meta data. | | `show_genres` | query | no | `enum(0 \| 1)` | Whether or not to autosuggest genres. 1 is yes, 0 is no. | | `safe_mode` | query | no | `enum(0 \| 1)` | Whether or not to exclude podcasts/episodes with explicit language. 1 is yes and 0 is no. It works only when **show_podcasts** is *1*. | **Responses** - **200** — OK - `TypeaheadResponse` (object) - `terms` (required, array) — Search term suggestions. - Items: `string` - `string` - `genres` (optional, array) — Genre suggestions. It'll show up when the **show_genres** parameter is *1*. - Items: `Genre` - `Genre` (object) - `id` (optional, integer) — Genre id - `name` (optional, string) — Genre name. - `parent_id` (optional, integer) — Parent genre id. - `podcasts` (optional, array) — Podcast suggestions. It'll show up when the **show_podcasts** parameter is 1. - Items: `PodcastTypeaheadResult` - `PodcastTypeaheadResult` (object) - `publisher_highlighted` (optional, PublisherHighlightedField) - `PublisherHighlightedField` (string) — Highlighted segment of this podcast's publisher name. - `publisher_original` (optional, PublisherOriginalField) - `PublisherOriginalField` (string) — Plain text of this podcast's publisher name. - `explicit_content` (optional, ExplicitField) - `ExplicitField` (boolean) — Whether this podcast contains explicit language. - `image` (optional, ImageField) - `ImageField` (string) — Image url for this podcast's artwork. If you are using PRO/ENTERPRISE plan, then it's a high resolution image (1400x1400). If you are using FREE plan, then it's the same as **thumbnail**, low resolution image (300x300). - `thumbnail` (optional, ThumbnailField) - `ThumbnailField` (string) — Thumbnail image url for this podcast's artwork (300x300). - `title_highlighted` (optional, PodcastTitleHighlightedField) - `PodcastTitleHighlightedField` (string) — Highlighted segment of podcast name. - `title_original` (optional, PodcastTitleOriginalField) - `PodcastTitleOriginalField` (string) — Plain text of podcast name. - `id` (optional, PodcastIdField) - `PodcastIdField` (string) — Podcast id, which can be used to further fetch detailed podcast metadata via `GET /podcasts/{id}`. - **400** — Something wrong on your end (Client side errors), e.g., missing required parameters. - **401** — Wrong api key, or your account is suspended. - **429** — For FREE plan, exceeding the quota limit; or for all plans, sending too many requests too fast and exceeding the rate limit. - **5XX** — Something wrong on our end (Unexpected server errors). # Integration and Product Guidance ## Skill source: SKILL.md # Podcast API Use the Listen Notes Podcast API without guessing endpoints, exposing credentials, or treating mock data as real data. ## Sources Of Truth - Use the live [OpenAPI YAML](https://listen-api.listennotes.com/api/v2/openapi.yaml) for exact methods, parameters, request bodies, response schemas, and endpoint restrictions. - Use the [tutorial index](https://www.listennotes.com/api/tutorials/) for supported application workflows. - Use the live [API FAQ](https://www.listennotes.com/api/faq/), [billing FAQ](https://www.listennotes.com/api/billing-faq/), [pricing](https://www.listennotes.com/api/pricing/), and [terms](https://www.listennotes.com/api/terms/) for policies and facts that may change. Do not copy a remembered schema into an implementation. Verify the relevant OpenAPI operation when network access is available. If it is unavailable, use the bundled endpoint map, state the limitation, and avoid inventing fields. ## Workflow 1. Inspect the target repository before changing it. - Identify the language, framework, server-side boundary, HTTP client, environment-variable convention, and test setup. - Reuse an installed official SDK or the project's existing HTTP client. Otherwise prefer the language's native HTTP facilities instead of adding a dependency. 2. Select the operation. - Read [endpoint-selection.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/endpoint-selection.md). - Load only the use-case reference relevant to the request. - Confirm the operation in the live OpenAPI document, including plan restrictions and pagination fields. 3. Design the security boundary. - Read `LISTEN_API_KEY` only in server-side code or a serverless function. - Send it as `X-ListenAPI-Key` to the production API. - Never place it in browser or mobile bundles, public environment variables, source control, URLs, fixtures, logs, or error messages. - If the current architecture cannot protect the key, add a server-side proxy before integrating the API. 4. Implement in the project's style. - Keep the production base URL configurable and default it to `https://listen-api.listennotes.com/api/v2`. - Encode query parameters and request bodies with structured APIs. - Validate inputs at the application's boundary and handle non-2xx responses explicitly. - Follow [integration-rules.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/integration-rules.md) for pagination, usage headers, caching, attribution, and error handling. 5. Test without spending quota. - Follow [testing.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/testing.md). - Use `https://listen-api-test.listennotes.com/api/v2` without an API key only for HTTP transport and response-shape tests. - Use local mocks or fixtures for parameter behavior, error paths, and pagination logic. 6. Verify the result. - Confirm no secret crosses a client boundary or appears in generated output. - Confirm the selected endpoint and every field used still exist in OpenAPI. - Confirm pagination terminates and does not issue unbounded requests. - Confirm UI using API data satisfies the applicable attribution rules. Do not make a production request unless the user explicitly asks and has arranged a credential. Never print or inspect the credential value. ## Reference Routing - Endpoint choice and current API surface: [endpoint-selection.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/endpoint-selection.md) - Authentication, errors, pagination, caching, and attribution: [integration-rules.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/integration-rules.md) - Mock server and test strategy: [testing.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/testing.md) - Search, typeahead, genres, charts, and discovery: [search-and-discovery.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/search-and-discovery.md) - Podcast lookup, episode sync, subscriptions, OPML, and webhooks: [library-and-sync.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/library-and-sync.md) - Playlists, curation, audio, embeds, and transcripts: [playlists-and-media.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/playlists-and-media.md) - API keys, usage monitoring, and account operations: [account-and-usage.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/account-and-usage.md) - Product, policy, support, rate-limit, and data questions: [api-faq.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/api-faq.md) - Plans, quotas, charges, cancellation, and payments: [billing-faq.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/billing-faq.md) ## Answering Questions Answer stable technical behavior from the appropriate reference and link to the live source. Re-check the live page before quoting a price, quota, plan entitlement, rate limit, support commitment, or legal/policy requirement. Distinguish API behavior from business policy, and direct account-specific billing issues to `hello@listennotes.com`. ## Skill source: references/account-and-usage.md # Account And Usage Workflows ## API Keys Sign up the FREE plan at the [API pricing page](https://www.listennotes.com/api/pricing/). Once you are approved, you can obtain keys through the [API dashboard](https://www.listennotes.com/api/dashboard/#apps) or the [API Docs page](https://www.listennotes.com/api/docs/). For multiple credentials, create multiple apps/tokens under the same account rather than creating extra accounts. Never ask the user to paste a key into chat or commit it to a repository. Use a distinct secret per environment when the dashboard supports it. Rotate a compromised key at the dashboard and update the secret store without changing application code. Source: [API keys tutorial](https://www.listennotes.help/article/53-how-to-get-one-or-multiple-api-keys-of-listen-notes-podcast-api). ## Usage Monitoring Read `X-ListenAPI-Usage` from API responses and compare it with the plan/quota information returned by documented headers or the dashboard. Header names are case-insensitive. The current tutorial says `HEAD` requests can retrieve usage headers without counting toward usage. Verify the behavior in the live documentation before adding a monitoring job, and schedule checks conservatively. Source: [usage tutorial](https://www.listennotes.help/article/44-how-to-check-how-many-requests-ive-used-in-this-billing-cycle). ## Mock Access Use the mock base URL without a key for development and response-shape checks. It is not an anonymous production tier and does not return real search results. Follow [testing.md](https://github.com/PodcastAPI/skills/blob/main/skills/podcast-api/references/testing.md) for its limits. Source: [mock-server tutorial](https://www.listennotes.help/article/48-how-to-test-the-podcast-api-without-an-api-key). ## Account-Specific Help Do not infer an account's plan, invoice, usage, or token state from generic documentation. Direct the user to the API dashboard or `hello@listennotes.com` for account-specific support. ## Skill source: references/api-faq.md # API FAQ Use the live [API FAQ](https://www.listennotes.com/api/faq/) and [terms](https://www.listennotes.com/api/terms/) for current wording. The following is a concise routing guide, not a replacement for those pages or legal advice. ## Product And Support - Listen API provides podcast and episode search, structured metadata, discovery, playlists, and related operations that general catalog APIs may not provide. - Listen Notes states that the API is actively supported and also powers ListenNotes.com. - PRO and Enterprise customers receive prioritized email support at `hello@listennotes.com`; current support terms can change. - The service reports serving customers at large request volumes, but do not promise capacity or an SLA beyond the user's contract. ## Data Freshness And Corrections - Missing podcasts can be submitted to Listen Notes. - Incorrect or stale metadata can be reported to `hello@listennotes.com` or corrected through available self-service tools. - Do not promise immediate feed updates. Freshness depends on crawl timing and feed health. - Use the documented RSS-refresh operation only for its intended workflow and plan. ## Caching And Attribution - Current FREE/PRO policy allows client-side caching but restricts server-side storage of API responses. - The FAQ currently allows server-side storage of podcast/episode IDs and publication dates, plus storage or processing of podcast audio files. - Enterprise agreements can permit broader server-side storage. - Current FREE/PRO terms require `Powered by Listen Notes` attribution on at least one screen or page displaying API data; Enterprise terms can differ. - Violating quota or caching restrictions can lead to suspension. Re-check the terms before implementing caching, indexing, data warehousing, or attribution. ## Rate Limits And Privacy - Rate limits vary by plan, endpoint, and account history. Handle `429` rather than hardcoding requests-per-second assumptions. - Listen Notes says API request logs include the calling device's IP address, user agent, endpoint, and parameters. - Send calls from the developer's backend so end-user clients do not receive the API key. ## Audio, Removal, And No-Code - Audio URLs may use a Listen Notes redirect so the destination can remain current while preserving podcast analytics. - The FAQ states that applications may stream podcast audio, subject to applicable terms and laws. - Content-removal requests can be directed through the documented deletion operation or to `hello@listennotes.com`. - No-code platforms can call the API only if they provide a genuinely secret server-side REST integration. A browser-visible connector is not safe for the key. ## SDKs Official libraries exist for several languages, but their coverage and maintenance can change. Reuse an installed official SDK when it fits the project; otherwise use direct REST calls verified against OpenAPI. Find current SDK links on the [tutorial index](https://www.listennotes.com/api/tutorials/). ## Skill source: references/billing-faq.md # Billing FAQ Use the live [billing FAQ](https://www.listennotes.com/api/billing-faq/) and [pricing page](https://www.listennotes.com/api/pricing/) before quoting any amount, included quota, deposit, overage rate, or Enterprise threshold. Do not hardcode those volatile values in generated applications or answers. ## Stable Guidance - A FREE plan is available without a credit card according to the current FAQ. - Successful API endpoint responses with HTTP `200` count as API requests. Error responses, `HEAD` requests, image loads, audio playback, and webhook deliveries currently do not count. - Exceeding FREE quota results in suspension or `429` responses until the billing cycle resets. Paid-plan overage behavior follows current pricing and contract terms. - Changing between FREE and PRO does not require a new key unless the key is reset. - PRO billing is monthly. Downgrades can cause immediate prorated billing under the current policy. - Cancellation means remaining on FREE, downgrading PRO to FREE, or contacting support for Enterprise, as applicable. - Payment details are handled by payment processors rather than stored directly by Listen Notes. - Refund, failed-payment, deposit, zero-usage, and Enterprise terms are policy-sensitive; quote only after checking the live FAQ. ## Migration From V1 For a v1/RapidAPI migration, verify the latest migration instructions. The current FAQ describes changing the base host/version, using the v2 key in `X-ListenAPI-Key`, and contacting support when backward-compatible response behavior is needed. Do not assume v1 rate-limit headers exist in v2. ## Answering Billing Questions 1. Separate generic policy from the user's account-specific state. 2. Check the live billing FAQ and pricing calculator on the day of the answer. 3. State the plan and date associated with any quoted number. 4. Direct invoice, refund, failed-payment, unexpected-charge, and contract questions to `hello@listennotes.com`. ## Skill source: references/endpoint-selection.md # Endpoint Selection Use this map to find a likely operation, then verify its exact contract in the live [OpenAPI YAML](https://listen-api.listennotes.com/api/v2/openapi.yaml). Do not infer request or response fields from this summary. ## Search | Task | Operation | Use when | | --- | --- | --- | | Full-text search | `GET /search` | Search episodes, podcasts, or curated lists with filters and relevance/date sorting. | | Episode-title lookup | `GET /search_episode_titles` | Match an individual episode title, optionally scoped by a Listen Notes, Apple Podcasts, Spotify, or RSS identifier. | | Search episodes in known podcasts | `GET /search` with `type=episode` and `ocid` | Limit episode search results to up to 5 known Listen Notes podcast IDs. | | Search suggestions | `GET /typeahead` | Provide low-latency query, genre, or podcast suggestions while typing. | | Related queries | `GET /related_searches` | Suggest broader related terms when accuracy matters more than typeahead latency. | | Spelling correction | `GET /spellcheck` | Correct a misspelled search phrase. | | Trending queries | `GET /trending_searches` | Show recent trending searches on Listen Notes. | ## Directory And Discovery | Task | Operation | Use when | | --- | --- | --- | | Podcast details and episodes | `GET /podcasts/{id}` | Fetch one podcast and page through its episodes. | | Episode details | `GET /episodes/{id}` | Fetch one episode; use `show_transcript=1` only when transcript coverage and plan support fit the product. | | Batch episode lookup | `POST /episodes` | Fetch metadata for multiple known episode IDs. | | Batch podcast lookup | `POST /podcasts` | Resolve multiple Listen Notes, Apple Podcasts, Spotify, or RSS identifiers and optionally fetch latest episodes. | | Popular podcasts | `GET /best_podcasts` | Browse podcasts by genre, region, language, publisher region, or popularity. | | Podcast recommendations | `GET /podcasts/{id}/recommendations` | Find podcasts similar to a known podcast. | | Episode recommendations | `GET /episodes/{id}/recommendations` | Find episodes similar to a known episode. | | Random episode | `GET /just_listen` | Return one random episode for discovery. | | Genre taxonomy | `GET /genres` | Fetch genres and parent-child relationships. | | Supported regions | `GET /regions` | Populate valid regions for best-podcast queries. | | Supported languages | `GET /languages` | Populate valid podcast-language filters. | | Curated list details | `GET /curated_podcasts/{id}` | Fetch one editorially curated podcast list. | | Curated list index | `GET /curated_podcasts` | Browse curated podcast lists. | | Publisher-domain lookup | `GET /podcasts/domains/{domain_name}` | Find podcasts associated with a publisher's domain. | ## Playlists | Task | Operation | Use when | | --- | --- | --- | | Playlist details and items | `GET /playlists/{id}` | Consume a Listen Later playlist as an episode or podcast list. | | Account playlists | `GET /playlists` | List playlists belonging to the authenticated account. | ## Podcaster And Insights | Task | Operation | Use when | | --- | --- | --- | | Submit podcast | `POST /podcasts/submit` | Ask Listen Notes to add a podcast feed. | | Request podcast deletion | `DELETE /podcasts/{id}` | Ask Listen Notes to remove a podcast. | | Refresh RSS | `POST /podcasts/{id}/rss` | Ask Listen Notes to refresh a known feed. | | Audience demographics | `GET /podcasts/{id}/audience` | Fetch available podcast audience insights. | Endpoint availability and result limits vary by plan. Read the operation description before promising that a feature is available. ## Skill source: references/integration-rules.md # Integration Rules ## Authentication And Boundaries - Production base URL: `https://listen-api.listennotes.com/api/v2` - Mock base URL: `https://listen-api-test.listennotes.com/api/v2` - Server-side environment variable: `LISTEN_API_KEY` - Production request header: `X-ListenAPI-Key: ` Send production requests from a trusted server, serverless function, or backend-for-frontend. A browser or distributed mobile binary cannot keep an API key secret. Do not solve that architecture problem with obfuscation, a public environment variable, or permissive proxying. Reuse the project's configuration and HTTP abstractions. Add timeouts and cancellation where supported. Encode URLs and bodies through the HTTP library, and avoid logging authorization headers or full upstream error objects. ## Responses And Errors Use the live [OpenAPI document](https://listen-api.listennotes.com/api/v2/openapi.yaml) for operation-specific responses. Handle these common classes: - `200`: parse the documented JSON body and optionally capture usage headers. - `400`: reject or correct invalid application inputs; do not retry unchanged requests. - `401`: treat the credential as missing or invalid without echoing it. - `404`: return a domain-appropriate not-found result when documented for the operation. - `429`: stop immediate retries, respect application retry policy, and surface quota or rate-limit context safely. - `5xx` and network failures: use bounded retries with backoff only for idempotent requests, or when the application deliberately makes a non-idempotent operation retry-safe. Do not assume every endpoint returns every status. Preserve enough upstream context for diagnosis without exposing secrets. ## Pagination Follow response-provided cursors instead of calculating them yourself. | Operation | Request field | Continue with | Stop when | | --- | --- | --- | --- | | `GET /search` | `offset` | response `next_offset` | the requested limit is reached or no usable next page remains | | `GET /best_podcasts` | `page` | response `next_page_number` | no next page remains | | `GET /podcasts/{id}` | `next_episode_pub_date` | response `next_episode_pub_date` | `episodes` is empty or the requested limit is reached | | `GET /curated_podcasts` | `page` | response `next_page_number` | no next page remains | | `GET /playlists/{id}` | `last_timestamp_ms` | response `last_timestamp_ms` | no items or usable cursor remains | | `GET /playlists` | `page` | response pagination value documented in OpenAPI | no next page remains | | `GET /podcasts/domains/{domain_name}` | `page` | response `next_page_number` | no next page remains | Add a maximum page or item bound unless the user explicitly needs exhaustive traversal. Guard against repeated cursors to prevent infinite loops. Preserve the endpoint's sort order while paging. ## Usage Headers Read headers case-insensitively. The API documents headers including: - `X-ListenAPI-FreeQuota` - `X-ListenAPI-Usage` - `X-ListenAPI-NextBillingDate` - `X-ListenAPI-Latency-Seconds` Use usage headers for monitoring or warnings, not as authorization. A `HEAD` request can inspect headers without counting as usage according to the current tutorial and billing FAQ; verify that behavior before building automation around it. ## Caching, Storage, And Attribution For current FREE and PRO terms, client-side response caching is allowed, but server-side response storage is restricted. The FAQ currently permits permanent server-side storage of podcast or episode IDs and publication dates, and permits storing or processing podcast audio files. Enterprise terms can allow broader server-side storage. Applications displaying API data under FREE or PRO terms must currently show a `Powered by Listen Notes` logo on at least one screen or page that uses the data. Enterprise terms may differ. Treat these as policy summaries, not legal advice. Re-check the live [API FAQ](https://www.listennotes.com/api/faq/) and [terms](https://www.listennotes.com/api/terms/) before designing storage, caching, indexing, or attribution behavior. ## Skill source: references/library-and-sync.md # Library And Sync Workflows ## One Podcast And Its Episodes Use `GET /podcasts/{id}` to fetch a podcast and its episodes. The initial response contains a bounded episode page. Continue with the returned `next_episode_pub_date`; stop when the `episodes` array is empty, the cursor repeats, or the application's item bound is reached. Select recent-first or oldest-first ordering explicitly when order matters. Source: [latest or all episodes tutorial](https://www.listennotes.help/article/39-how-to-get-latest-or-all-episodes-of-a-podcast). ## Multiple Podcasts And Subscription Refresh Use `POST /podcasts` for batches of known podcast identifiers and optionally request latest episodes as documented by OpenAPI. Observe the current batch-size limit. For subscription refresh: 1. Store the permitted podcast ID and latest known publication date for each subscription. 2. Batch-fetch podcast metadata. 3. Compare the returned latest publication date with the stored value. 4. Fetch episode pages only for podcasts that changed, or use the batch endpoint's latest-episode option when the product needs a smaller combined feed. Do not poll without a schedule or request bound. Source: [subscription refresh tutorial](https://www.listennotes.help/article/40-how-to-fetch-new-episodes-for-subscribed-podcasts-using-podcast-api). ## External IDs And OPML Use `POST /podcasts` to resolve batches of Listen Notes IDs, Apple Podcasts IDs, Spotify IDs, or RSS URLs using the exact request field documented for each identifier type. For OPML import, parse the OPML with a structured XML parser, normalize RSS URLs, batch them within the endpoint limit, and preserve entries the API cannot resolve. For export, generate OPML from the user's subscription records and the podcast names/RSS URLs returned by the API. Do not use string concatenation to generate XML. Sources: [external-ID lookup tutorial](https://www.listennotes.help/article/42-how-to-fetch-metadata-e-g-rss-episodes-of-podcasts-by-apple-podcasts-ids-itunes-ids-or-spotify-ids) and [OPML tutorial](https://www.listennotes.help/article/43-how-to-implement-import-opml-and-export-opml-in-a-podcast-app). ## IDs And Webhooks Read podcast, episode, and playlist IDs from API responses. A human can also open an entity on ListenNotes.com and follow its “Use API to fetch this” link. Do not parse IDs from display URLs when a structured field is available. Webhook setup is an account-dashboard operation. The current tutorial describes callbacks for podcast submission and deletion flows. Implement a public HTTPS callback that responds with `200`, authenticates or validates events using whatever mechanism the live dashboard/documentation provides, is idempotent, and does not trust an undocumented payload shape. Sources: [finding IDs](https://www.listennotes.help/article/89-how-to-get-podcast-episode-playlist-ids-on-listen-notes) and [webhook tutorial](https://www.listennotes.help/article/49-how-to-use-webhooks-of-podcast-api). ## Skill source: references/playlists-and-media.md # Playlists And Media Workflows ## Application Playlists Two supported designs serve different ownership needs: 1. Store permitted episode IDs in the application's database, then use `POST /episodes` to hydrate bounded batches. 2. Let human curators manage a Listen Later playlist, then use `GET /playlists/{id}` as a headless content-management feed. For a curated feed, choose the documented episode-list or podcast-list type, such as `type=episode_list` for episodes or `type=podcast_list` for podcasts, and page with `last_timestamp_ms`. Preserve curator notes when the response provides them. Do not permanently mirror full API responses unless the applicable plan permits server-side storage. Sources: [playlist tutorial](https://www.listennotes.help/article/45-how-to-build-a-playlist-for-episodes-in-a-podcast-app) and [human curation tutorial](https://www.listennotes.help/article/34-whats-the-easiest-way-for-our-human-content-curators-to-handpick-specific-podcasts-episodes-into-our-app-using-podcast-api). ## Transcripts Use `GET /episodes/{id}?show_transcript=1` and verify the current transcript parameter and response field in OpenAPI. Treat transcripts as optional and plan-limited: the current contract says the `transcript` field is available only in PRO/ENTERPRISE plans, and the help article says less than 1% of episodes have transcripts. Design an explicit missing-transcript state. If the product needs transcripts for episodes without them, retrieve the documented audio URL and integrate a separate speech-to-text service only when the user asks for that larger workflow. Do not imply that Podcast API itself transcribes arbitrary audio. Source: [transcript tutorial](https://www.listennotes.help/article/35-how-to-get-transcripts-of-any-podcast-episodes-using-podcast-api). ## Audio And Clips Use the episode audio URL from the API response for playback or downstream processing. Listen Notes audio URLs redirect to the podcast's current media URL; preserve redirect support in the HTTP player or downloader. Clip creation is not a Podcast API endpoint. Download the audio only when the use case and applicable rights allow it, then use an audio tool such as FFmpeg to create a bounded clip. Keep media processing out of request handlers when it is slow or resource intensive. Source: [clip tutorial](https://www.listennotes.help/article/19-how-to-create-audio-or-video-clips-for-a-specific-podcast-episode-using-podcast-api). ## Embedded Player Derive the player URL by appending `embed/` to the response's `listennotes_url`, preserving the trailing slash. Render it in an iframe with an accessible title, lazy loading, and a responsive width. Do not expose the API key; the embedded player URL does not need it. Source: [embedded-player tutorial](https://www.listennotes.help/article/36-do-you-provide-a-pre-built-embedded-podcast-player-that-i-can-put-on-my-website). ## Skill source: references/search-and-discovery.md # Search And Discovery Workflows Verify every parameter against the live [OpenAPI document](https://listen-api.listennotes.com/api/v2/openapi.yaml). ## General Search Use `GET /search` for full-text search over episodes, podcasts, or curated lists. Select the response type deliberately, pass filters only when the user asks for them, and paginate with the returned `next_offset`. For episodes from a small known set of podcasts, pass their Listen Notes podcast IDs through `ocid` with `type=episode`. The current contract allows up to 5 comma-delimited podcast IDs; still verify the maximum before implementing validation. Source: [scoped episode search tutorial](https://www.listennotes.help/article/41-how-to-search-episodes-for-specific-podcasts-using-podcast-api). ## Finding A Podcast By Name For precise podcast-name search, use `GET /search` with podcast results and restrict matching to title and publisher/author fields. Quote the query when the user needs a verbatim match. For interactive suggestions, prefer `GET /typeahead` with podcast suggestions enabled. Do not claim a search is exact merely because it is quoted. Preserve a no-result path and let the user disambiguate multiple candidates. ## Search Experiences Combine endpoints by interaction rather than calling all of them automatically: - `GET /typeahead`: fast suggestions while the user types. - `GET /spellcheck`: correction for a submitted misspelled phrase. - `GET /related_searches`: more comprehensive related queries after submission. - `GET /trending_searches`: recent popular search terms. - `GET /search_episode_titles`: import or match a specific episode by title and external podcast identifier. - `GET /search`: full results and filters. See the official [search tutorial](https://www.listennotes.help/article/38-use-podcast-search-apis). ## Genres And Charts Use `GET /genres` for the genre hierarchy. Relate a child to its parent using `parent_id`; request only top-level genres when that is all the UI needs. Use `GET /best_podcasts` for country-, language-, or genre-oriented charts. To rank by the Listen Score popularity metric, use the sort value currently documented by OpenAPI. Page with the response's `next_page_number`. Sources: [genre tutorial](https://www.listennotes.help/article/46-how-to-get-sub-genres-for-a-particular-podcast-genre-using-podcast-api), [popular podcasts tutorial](https://www.listennotes.help/article/37-how-to-get-popular-podcasts-by-country-category-using-podcast-api), and [accurate name-search tutorial](https://www.listennotes.help/article/47-how-to-get-more-accurate-search-results-when-searching-podcast-names-using-podcast-api). ## Skill source: references/testing.md # Testing ## Mock Server Contract Use `https://listen-api-test.listennotes.com/api/v2` without `X-ListenAPI-Key` for safe integration tests. It returns hardcoded fake data. The mock server has three important limitations: 1. The same endpoint returns the same fake response regardless of query parameters. 2. It cannot validate search relevance, filters, sorting, plan behavior, pagination semantics, or data freshness. 3. It may be unavailable occasionally. Therefore, use it only to verify URL construction, HTTP transport, parsing, and broad response shape. See the official [mock-server tutorial](https://www.listennotes.help/article/48-how-to-test-the-podcast-api-without-an-api-key). ## Test Layers 1. Unit-test application behavior with local mocks or fixtures. - Assert the chosen method, path, encoded query, body, and header names. - Assert that the API-key value is never returned to or serialized for a client. - Cover `400`, `401`, `404`, `429`, network failures, and malformed JSON as relevant. - Cover empty results, missing optional fields, repeated cursors, and maximum-page guards. 2. Add a mock-server integration test when network tests fit the repository. - Inject the mock base URL through configuration. - Omit the API key. - Assert transport and parsing only. - Skip or classify the test appropriately if the mock service is unavailable. 3. Keep production verification opt-in. - Do not require `LISTEN_API_KEY` in ordinary CI. - Do not send live requests merely to prove generated code works. - If the user explicitly requests a live test, use the smallest bounded request and do not print response headers that may contain account information. ## Framework Checks - For server-rendered or full-stack web frameworks, confirm the request runs in a server route, server action, loader, or backend service rather than a client component. - For mobile and desktop clients, place the credentialed request behind a backend owned by the application developer. - For edge or serverless runtimes, use that platform's secret store and supported HTTP APIs. - For reusable libraries, accept the API key and base URL through explicit server-side configuration; never read browser-global environment values. # Canonical Live Resources - API docs: https://www.listennotes.com/api/docs/ - OpenAPI YAML: https://listen-api.listennotes.com/api/v2/openapi.yaml - Tutorials: https://www.listennotes.com/api/tutorials/ - FAQ: https://www.listennotes.com/api/faq/ - Billing FAQ: https://www.listennotes.com/api/billing-faq/ - Pricing and current plan limits: https://www.listennotes.com/api/pricing/ - Terms, caching, storage, and attribution: https://www.listennotes.com/api/terms/ - Official SDKs: https://www.listennotes.com/api/docs/ - Other Listen Notes product offerings: https://www.listennotes.com/llms-full.txt - Agent Skill: https://github.com/PodcastAPI/skills - Account help: hello@listennotes.com