Skip to main content
If you already have a corpus of podcasts identified by their Apple collection ID, Spotify show ID, YouTube channel ID, RSS feed URL, or any other platform-native identifier, the regular catalog endpoints aren’t the right tool to reconcile them with Particle’s catalog:
  • GET /v1/podcasts/search?q=… is a fuzzy name search. It can’t find a show whose title you’re spelling differently than we do — and there’s no guarantee the top hit is the right podcast even when names look similar.
  • GET /v1/podcasts/{id} accepts our internal ID, the Particle slug, or a numeric Apple/iTunes collection ID — but not Spotify, YouTube, or other third-party IDs.
The lookup endpoint closes that gap. Send it a platform plus up to 100 platform-native identifiers, and it returns one record per input — each echoing the identifier you sent alongside the matched Particle podcast (or omitting the podcast key when the identifier doesn’t resolve). The same data backs external links; this endpoint lets you query it in the opposite direction — from platform identifier to podcast. Use this endpoint when you want to:
  • Reconcile an existing corpus of podcasts (a CMS export, a chart scrape, a partner feed) with Particle’s catalog by Apple/Spotify/etc. IDs.
  • Map a Spotify show ID, YouTube channel ID, or other third-party identifier into our podcast.id before calling any other Particle endpoint. (A numeric Apple/iTunes collection ID can be passed straight into the {id} slot of any podcast endpoint — no lookup needed.)
  • Bulk-resolve a list of identifiers without losing the input → output correlation that a fuzzy filter on /v1/podcasts can’t give you.

Look up by Apple Podcasts ID

Response
That’s the whole shape. Each result echoes the input identifier so you can join the response back to your input list by position or by key — your call. Unresolved identifiers omit the podcast field entirely; clients should test for key presence rather than a null value, matching the convention used elsewhere in the API for nullable nested resources.

Look up by RSS feed URL

The rss platform is the odd one out: it doesn’t live in external-links because every podcast already carries its own canonical feed URL on the podcast itself. Pass the URL exactly as it appears on the podcast’s RSS feed:
Comparison is byte-exact: a ?param suffix, a trailing slash, or http:// vs https:// will not match if our stored URL is the other form. If you don’t have the URL exactly as the publisher serves it, fall back to looking up by Apple/Spotify/YouTube ID instead — those are more forgiving to normalise.

Parameters

A few details worth knowing up front:
  • Order is preserved. Results appear in the request order of their first occurrence. If you send ?identifier=A,B,A, you get two results — A then B — not three.
  • Exact matching only. Identifiers are compared exactly; case differences and prefix mismatches do not resolve. Leading and trailing whitespace is stripped automatically so a copy-pasted ID with stray spaces still works.
  • platform=bogus is a 400. Unknown platform slugs return an error listing every accepted slug — same vocabulary as the external-links responses.

Looking up the same podcast across platforms

The endpoint takes one platform at a time. To resolve a multi-platform corpus, fan out one call per platform — each call covers up to 100 identifiers and the responses are independent:
Once you have the resolved podcast.id for each input, hit GET /v1/podcasts/{id}/external-links to see every other platform that podcast also lives on. That’s the natural follow-up when you want to enrich rather than reconcile.

Behavior and edge cases

Apple Podcasts and iTunes share IDs

Apple Podcasts uses a single numeric collection ID across both its modern and iTunes-era surfaces. The lookup endpoint reflects that: platform=apple and platform=itunes are aliases that behave identically — either form finds the same matches.
Because Apple/iTunes IDs are always numeric, you can also pass one straight into the {id} slot of any podcast endpoint — e.g. GET /v1/podcasts/1535809341 — and skip this lookup entirely. The {id} slot resolves iTunes IDs the same way this lookup does — including the highest-charting tiebreaker for shared identifiers — so both always return the same podcast.

Misses omit the podcast field

Unmatched identifiers come back as {"identifier": "…"} with no podcast key. This is intentional — OpenAPI clients now see an accurate schema where podcast is optional, and absence is a single sentinel for “no match” without the ambiguity of explicit null.

Duplicates collapse

If your input list contains duplicates, the response contains one entry per unique identifier — in the order each one first appeared. We do this silently rather than echoing duplicates back, so your client doesn’t have to dedupe twice.

Compact response only

The matched podcast is returned in the compact shape (id, title, slug, image_url) — enough to pivot to any other endpoint, but without the fuller metadata that GET /v1/podcasts/{id} returns. For each identifier you actually care about, follow up with the detail endpoint using the returned id (or slug).

Ambiguous identifiers resolve to the highest-charting podcast

A few platform identifiers in the wild are claimed by more than one podcast — most often when a publisher exposes the same YouTube channel as the video presence for several shows (e.g. the parent New York Times YouTube channel is listed under The Daily, Serial, The Headlines, Matter of Opinion, The Book Review, and others). When that happens, the lookup returns the podcast with the highest current Apple Podcasts / Spotify chart ranking, so the same input always resolves to the same output across calls. If you need to find every podcast a shared identifier belongs to, that’s an external-links question, not a lookup one — start from each candidate podcast and inspect its external-link rows.

100-identifier cap

Calls with more than 100 identifiers are rejected with a 400. The cap is generous enough that most reconciliations fit in a single round-trip; if you need more, fan out in chunks of 100. (The cap is per platform — you can do multiple platform calls in parallel.)

Look up an episode by Apple Podcasts episode ID

Everything above resolves a show. GET /v1/podcasts/episodes/lookup is the episode-level counterpart, and it takes the same shape: one platform, up to 100 identifiers, one echoed result per input. The identifier is the i parameter in an Apple Podcasts episode URL — https://podcasts.apple.com/us/podcast/…/id315114957?i=1000785846210 identifies episode 1000785846210. You can pass either the bare ID or the whole URL; the URL form is parsed for you, and the identifier is echoed back exactly as you sent it.
Response
Each result carries the parent podcast too, so resolving an Apple episode ID tells you which show it belongs to without a second call. As with the podcast lookup, an unresolved identifier omits the episode key entirely rather than returning null.
Episode coverage is partial — roughly two-thirds of our catalog. A miss is a normal outcome here, not an error, and you should design for it.Apple only publishes episode IDs through a show’s catalog listing, and that listing is capped at the show’s 200 most recent episodes (often fewer). Deep back-catalog episodes therefore have no Apple ID we can observe. A further ~12% of episodes carry no feed guid, which is the only key Apple exposes for matching.In practice: recent episodes and small-to-mid shows resolve almost always; long-running daily shows resolve only for their recent window. If an ID doesn’t resolve, fall back to GET /v1/podcasts/episodes/search or GET /v1/podcasts/{id}/episodes scoped to the show.
platform=itunes is accepted as an alias for platform=apple, matching the podcast lookup above.

Look up an episode by YouTube video ID

platform=youtube resolves a YouTube video to the episode it belongs to. Pass the bare video ID or the whole URL — watch?v=, youtu.be/, /live/, /shorts/ and /embed/ forms are all understood:
YouTube coverage works differently from Apple. It reflects the videos we have discovered for an episode — from the feed’s own links, Podcasting 2.0 alternate enclosures, Media RSS, show-note URLs, and channel matching — rather than a per-episode lookup against YouTube. Every video we hold is resolvable, so there is no partial-window caveat like Apple’s; the limit is simply whether we found a video for that episode at all. Episodes published before we began discovering videos for a show generally have none.Where a single video is attached to more than one episode, the lookup prefers the episode whose video came from the most precise discovery method (a feed enclosure or a runtime-validated channel match ahead of a URL scraped from show notes), then the most popular podcast. Repeated calls always give the same answer.

Look up an episode by RSS guid

platform=guid resolves the <guid> an episode carries in its publisher’s feed. This is the podcast ecosystem’s canonical episode identifier — if you already parse feeds, or work with a host, player or analytics tool, it is almost certainly the ID you hold.
Guids are opaque strings and are matched exactly as supplied. Publishers use whatever form they like — a UUID, a permalink URL, a hosting-provider ID — and we never parse or normalize them, so pass the value through byte for byte.
A guid identifies an episode within its feed, not globally. The vast majority are unique across the whole catalogue, but around 1.4% are not, because some publishers reuse a template value and because the same show can appear in the index twice. Where a guid reaches more than one episode the lookup returns the one on the most popular podcast, and repeated calls always give the same answer.Coverage is the broadest of any identifier here: roughly 89% of episodes carry a guid. The rest are episodes whose feed omitted one.
A guid containing a comma cannot be looked up here. Identifiers are comma-separated, so a guid such as tag:soundcloud,2010:tracks/2327580812 splits into two values and neither resolves. This affects about 1.2% of episodes, nearly all of them SoundCloud-hosted, which use that form throughout. Look those episodes up by podcastindex ID or a platform ID instead.

Look up an episode by PodcastIndex episode ID

platform=podcastindex resolves a PodcastIndex episode ID:
PodcastIndex IDs are numeric and unique — a given ID resolves to at most one episode, with no tie-breaking involved. A non-numeric value cannot match anything and is reported as a miss rather than failing the request, so one bad value in a batch never costs you the rest.

Look up an episode by hosting-platform episode ID

If you work in a podcast host’s own dashboard, the ID you have is theirs. Four are resolvable — megaphone, omny, acast and art19:
These IDs are read from the episode’s audio URL, which means coverage is simply whether that episode is served by that host — there is no partial-window caveat. It also means an episode resolves under exactly one of these, the host that serves it.
Pass the bare ID, not the audio URL. Publishers route audio through arbitrary stacks of tracking prefixes — podtrac, pdst.fm, pscrb.fm, mgln.ai and others, often several deep — so the URL you hold may not resemble the one we stored. The ID inside it is stable; the wrapping is not.
platform=rss is not accepted here — an RSS feed URL identifies a show, not an episode, so use the podcast lookup above for that.

Choosing the right endpoint

  • External links — given a Particle podcast, list every third-party platform identifier we have for it; the opposite direction of this endpoint.
  • Podcasts overview — full Podcast object and all sub-resources.
  • Concepts — pagination, pricing weights, and authentication.