Skip to main content

Engineering

How Podmae Ranks Podcasts From Three Different Directories

A plain look at the fan-out, dedupe, and scoring formula that turns a search into a ranked list — plus where the two optional AI steps fit in.

P
Podmae
Jul 20, 2026 · 6 min read

Type "shows about how startups raise venture capital" into Podmae and, about a second later, you get back a ranked list of podcasts pulled from three different directories, deduplicated, and scored against a formula with real, tunable weights. Here's what happens in between.

The problem: three directories, no shared ID

Apple's podcast directory, Spotify, and PodcastIndex each keep their own catalog. None of them agree on an ID for the same show, and none of them has everything.

A search that only hits one directory misses shows the other two have. So every search runs against all three at once, and the results get merged afterward. That merge step turns out to be most of the hard part.

From a sentence to a set of search terms

Before anything gets sent to an API, the query gets normalized. Unicode-normalized, lowercased, punctuation stripped down to letters, digits, and a few symbols.

Then it's split into words, and around 40 stop words get dropped — things like "a," "the," "podcast," "show," "best," "how," "learn." What's left gets deduplicated and capped at 16 keywords.

From there, a topic-specific expansion step adds synonyms. A query mentioning "ai," "artificial intelligence," or "machine learning" gets both phrases appended. One mentioning "founder" or "startup" gets "founders" and "startups" added. The keywords get joined into a phrase, combined with whatever synonyms matched, and the whole set is capped at 5 search terms. That's what actually goes to the providers.

If a user is entitled to it and AI query rewriting is on, this step gets skipped entirely — a small model (Claude Haiku) rewrites the request into up to 5 clean queries instead. If that call fails or times out, the deterministic version above runs normally. Search doesn't depend on the AI step succeeding.

Searching three APIs at once

Each search term gets sent to each provider in parallel, through a pooled HTTP client — up to 15 requests per search. Apple allows up to 200 results per request, PodcastIndex up to 1,000, and Spotify caps at 10 (the live API errors above that).

Every request gets a 2-second connect timeout and a 6-second response timeout, with two retries on a short backoff.

Responses get processed in the order the requests were made, not the order they come back in. That's deliberate. The final ranking doesn't depend on which provider happened to answer fastest.

Merging the same show, found three times

The same podcast often shows up in results from all three providers. Before anything gets scored, those duplicates have to collapse into one record.

Two things count as a match: sharing a provider ID (an Apple collection ID, a Spotify ID, a PodcastIndex feed ID), or a fuzzy identity match — normalized title and creator, with "the," "podcast," and "show" stripped out of the title first.

Once two candidates are flagged as the same show, they merge: the union of their provider URLs and genres, the higher episode count, the newest release date. There's also a guard that drops a candidate if it only matched because of a synonym expansion and doesn't contain any term the user actually typed. Otherwise the synonym list would slowly pull results off-topic.

A show is more trustworthy if three separate companies decided to carry it. That's the entire justification for the cross-provider bonus below.

The scoring formula

Every merged show gets scored against the same terms used for search. Matching happens in three places — anywhere in the name, creator, or genres; specifically in the title; specifically in the genres — using word-boundary matching for single words and substring matching for phrases.

score = 14 × (terms matched anywhere)
      + 12 × (terms matched in the title)
      +  8 × (terms matched in the genres)
      + min(episode_count, 400) / 20        # capped at +20
      + 10 × (boost terms found in the title)
      −  8 × (penalty terms found in the title)
      + cross-provider bonus (+5 for 2 providers, +10 for 3)

score = clamp(score, 0, 100)

Episode count is a soft signal for catalog depth — a show with 400 or more episodes gets the full +20, but back-catalog alone can't win a search.

Boost and penalty terms are topic-specific. A finance-focused search profile adds points for "private equity" or "venture capital," and subtracts them for "crypto," "web3," or "real estate" — vocabulary that overlaps but isn't the same topic. The cross-provider bonus rewards a show for being findable in more than one directory: +5 for two, +10 for all three.

Sorting, and what actually comes back

Default sort is relevance: score descending, then episode count descending, then a stable ID as the final tiebreak. Two shows with identical scores always land in the same order, no matter which order the providers responded in.

Results are capped at 25. Each one comes back with name, creator, genres, episode count, last release date, links to each provider, artwork, which providers it was found on, its score, and which terms matched. Users can re-sort by episode count, recency, or name without re-running the search.

An optional second pass from AI

For relevance-sorted show searches with more than one result, there's a second AI stage after scoring. A short description gets built for each top candidate — name, creator, genres, episode count — and sent to a reranking model, which returns a relevance score between 0 and 1 per show.

That score gets blended with the heuristic score, not swapped in for it: 40% heuristic, 60% AI. The underlying scores and data never get overwritten. The AI only reorders and adds its own score alongside them.

This runs once, after the page has already rendered with the heuristic ranking — the reranked order streams in a moment later and is then saved with the search. It's cached for an hour, and any failure just falls back to the heuristic order. A search never fails because the AI step did.

The short version

None of this is one clever trick. It's a stop-word list, three HTTP clients with their own rate limits, a dedupe step that has to guess when two records are the same show, and a scoring formula built out of plain integer weights, tuned by hand. The AI stages sit on top of that and can be turned off without breaking anything — which is closer to how most "AI-powered" search actually works than the phrase usually implies.

Get the next one in your inbox

One email a month. Search, ranking, and the business of podcasts.