Podcast Sponsor Tracker - Which Brands Advertise on Which Shows avatar

Podcast Sponsor Tracker - Which Brands Advertise on Which Shows

Pricing

from $50.00 / 1,000 podcast-processeds

Go to Apify Store
Podcast Sponsor Tracker - Which Brands Advertise on Which Shows

Podcast Sponsor Tracker - Which Brands Advertise on Which Shows

Reads public podcast RSS show notes and returns one row per detected sponsor placement: show, episode, advertiser, tracked URL, and the offer or promo code when the notes contain one. Keeps advertiser history between runs and emits first-seen, returned, lapsed and promo-code-changed events.

Pricing

from $50.00 / 1,000 podcast-processeds

Rating

0.0

(0)

Developer

Mikkel Bech-Hansen

Mikkel Bech-Hansen

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a month ago

Last modified

Security

Limited permissions

Share

This actor reads the public RSS feeds of the podcasts you name and returns one row for every sponsor placement it finds in the show notes: which brand, on which show, in which episode, the tracked link the sponsor was given (https://eightsleep.com/huberman), and the offer or promo code when the notes contain one. It remembers what it saw last time, so from the second run onwards it also tells you when an advertiser shows up on a show for the first time, comes back after a break, goes quiet, or changes its promo code. There is no AI model in the loop - the tracked URL and the promo code are the evidence, and the actor reports what is literally written in the feed.

What you actually get

Three kinds of row, tagged by recordType, all in one dataset:

  • placement - one advertiser found in one episode. This is the unit you pay for.
  • change_event - a typed change for a (brand, show) pair: advertiser-first-seen-on-show, advertiser-returned, advertiser-lapsed, promo-code-changed.
  • brand_show_rollup - one summary row per (advertiser, show): tenure, placement count, cadence, last known offer. These are free.

Input

Every field has a working default. Running it with no input at all scans two real podcasts (Huberman Lab and My First Million) for the last 90 days.

FieldTypeDefaultNotes
feedUrlsarray of stringsHuberman Lab + My First MillionPodcast RSS feed URLs. The fastest and most reliable way to name a show.
applePodcastIdsarray of strings[]Apple Podcasts numeric IDs (1469759170) or full Apple Podcasts URLs containing /id.... Resolved to feed URLs via Apple's public iTunes Lookup API and cached.
searchTermsarray of strings[]Show names, resolved through Apple's public iTunes Search API. First result with a public feed wins, so use exact titles.
daysBackinteger90Episode window, 1-1825. Feeds stream newest-first and the download aborts once episodes fall outside it.
maxEpisodesPerShowinteger501-500. Hard cap per show.
maxShowsinteger101-200. Counts feed URLs, Apple IDs and search terms together.
minConfidencehigh | mediumhighSee "How detection works" below.
showAliasesarray of strings[]Extra URL path slugs identifying the show in sponsor links (add tfs if sponsors link to brand.com/tfs). Applied to every show in the run.
extraSponsorDomainsarray of strings[]Domains always treated as an advertiser. Useful to follow one brand across many shows.
ignoreDomainsarray of strings[]Added to the built-in ignore list.
brandNameOverridesarray of objects[][{"domain":"joinhampton.com","brandName":"Hampton"}].
resolveRedirectsbooleanfalseHEAD-follow each tracked link (up to 3 redirects) to record the final landing URL. Adds one request per unique link and noticeably slows the run.
lapsedAfterDaysinteger451-365. Days without a placement before an advertiser counts as lapsed. Set it above the show's publishing gap.
emitChangeEventsbooleantrueChange-event rows.
emitBrandRollupsbooleantrueRollup rows. Never charged.
forceFullRescanbooleanfalseRe-process episodes already seen. Re-charges for placements already delivered.
stateKeyValueStoreNamestringpodcast-sponsor-placement-stateNamed key-value store holding advertiser history between runs. Keep it constant across scheduled runs of the same watchlist.
requestTimeoutSecsinteger455-300.
maxRequestRetriesinteger20-10. Exponential backoff.
maxFeedMegabytesinteger121-100. Safety cap on how much of one feed is downloaded.
proxyConfigurationobjectno proxyPodcast RSS is plain public XML and normally needs no proxy.

Output

A real placement record, exactly as returned by the default run:

{
"recordType": "placement",
"showTitle": "Huberman Lab",
"showFeedUrl": "https://feeds.megaphone.fm/hubermanlab",
"showAppleCollectionId": null,
"showDomain": "hubermanlab.com",
"episodeTitle": "Essentials: Improve Flexibility with Research-Supported Stretching Protocols",
"episodeGuid": "3b42bd84-6a51-11f1-b442-0f78f81b3455",
"episodePublishedAt": "2026-06-18T08:00:00.000Z",
"episodeUrl": "https://www.hubermanlab.com/episode/essentials-improve-flexibility-with-research-supported-stretching-protocols",
"brandName": "AG1",
"brandDomain": "drinkag1.com",
"trackedUrl": "https://drinkag1.com/huberman",
"landingUrl": null,
"promoCode": null,
"offerText": null,
"confidence": "high",
"signals": ["slugMatch:huberman", "strongCue:thank you to our sponsor"],
"cueText": "Thank you to our sponsors AG1: https://drinkag1.com/huberman LMNT: https://drinklmnt.com/huberman Eight Sleep: https://eightsleep.com/huberman",
"detectedAt": "2026-09-11T23:27:17.514Z"
}

A change_event record:

{
"recordType": "change_event",
"eventType": "advertiser-lapsed",
"showTitle": "Huberman Lab",
"brandName": "Waking Up",
"brandDomain": "wakingup.com",
"daysSinceLastSeen": 50.6,
"firstSeenAt": "2026-07-23T08:00:00.000Z",
"lastSeenAt": "2026-07-23T08:00:00.000Z",
"placementCount": 1,
"promoCode": null,
"previousPromoCode": null,
"detectedAt": "2026-09-11T23:31:02.118Z"
}

A brand_show_rollup record carries firstSeenAt, lastSeenAt, tenureDays, placementCount, episodesWithPlacement, placementsPerMonth, lastPromoCode, lastOfferText, isActive and daysSinceLastSeen.

How detection works

A link in the show notes becomes a placement when there is deterministic evidence for it:

  • high (default) - the link's last path segment matches a slug derived from the show's title (drinkag1.com/huberman, somewhere.com/mfm) - this is the strongest possible signal, because a sponsor-specific vanity path exists only for tracking - or the link directly follows an explicit advertising cue such as "brought to you by", "thanks to our sponsors", "presented by".
  • medium - also returns links that merely follow a call to action ("visit", "check out", "go to") or sit next to a promo code. Wider coverage, and it will pick up links that are not ads.

The show's own domain, domains containing the show's name, social profiles, podcast platforms, ad-tech hosts and link shorteners are excluded automatically. Promo codes and offers are only read from the same line as the link they belong to, so one sponsor's "use code SAVE20" is never attached to the next sponsor down the page.

Cost

Pay-per-event. Prices are set in the Store listing; the plan this actor is built around is sponsor-placement-detected $0.006, advertiser-change-event $0.01, show-scanned $0.01. Rollup rows are free.

  • First run, 10 shows x 50 episodes, a typical backfill: 10 show scans ($0.10) plus roughly 300-600 placements ($1.80-$3.60). About $2-$4.
  • A daily scheduled run over the same 10 shows, which is the way this is meant to be used: 10 show scans ($0.10) plus only the placements in genuinely new episodes - a handful of shows publish per day, so typically 5-30 placements ($0.03-$0.18) and 0-5 change events ($0-$0.05). Usually under $0.35 a day.

The second run onwards is cheap by design: episodes already processed are never re-charged. Set ACTOR_MAX_TOTAL_CHARGE_USD on the run to cap spend - the actor checks the limit after each charge and ends the run cleanly instead of working for free.

Known limitations

Read these before you buy. Most are inherent to the data source, not bugs.

  • It only sees sponsors that are written into the show notes. Dynamically inserted / programmatic ads - the ads stitched into the audio at download time by the ad server - never appear in the RSS feed at all. What you get is host-read and notes-listed sponsorship, which is a subset of a show's true ad load. No RSS-based tool can see the rest.
  • Some shows list no sponsors in their notes at all, even though they clearly run ads. Conan O'Brien Needs A Friend, for example, carries only its own network's link in the notes. Zero rows for such a show is a correct answer, not a failure.
  • Promo codes are much rarer than you would expect. In the feeds checked while building this, only about 1 episode in 15-25 contained an explicit code XXXX. The near-universal evidence is the tracked URL; offer text ("$500 off", "20% off") is fairly common; an actual code is the exception. Do not buy this expecting a promo-code database.
  • Offers and codes are read from the same line as the link. If a show puts the offer on the following line, it is missed. This is deliberate - the alternative mis-attributes offers between sponsors.
  • Brand identity is the registrable domain. An advertiser using several domains appears as several brands; use brandNameOverrides and extraSponsorDomains to reconcile. Brand names are read from the notes where they corroborate the domain, and fall back to the domain otherwise.
  • Change events need at least two runs against the same stateKeyValueStoreName. The first run is a baseline and deliberately emits no "first seen" events, or every advertiser would be reported as new.
  • advertiser-lapsed is relative to your lapsedAfterDays setting, not to any inside knowledge of the contract. A show that skips a month will produce lapse events unless you raise the threshold.
  • Detection is pattern matching, not comprehension. It will miss unusual note formats and, at medium confidence, will return some links that are not ads. The signals field on every row shows exactly why the row was emitted, so you can audit it.
  • Apple lookups are rate limited to roughly 20 calls per minute per IP, and answer HTTP 429 above that. Resolved feeds are cached in the state store; prefer feedUrls for large watchlists.
  • Very large archives are capped by maxFeedMegabytes. Feeds are streamed newest-first and normally stop far below the cap, but a feed sorted oldest-first will be truncated.
  • No personal data. The actor never emits itunes:owner contact fields, host or guest emails, or any listener data. It reports show-level and advertiser-level facts only.

This actor is not affiliated with, endorsed by, or connected to Apple, Apple Podcasts, any podcast host or network, any podcast platform, or any of the advertisers whose placements it reports.

It uses two public sources:

Podcast RSS feeds. RSS feeds are published openly and are intended to be retrieved automatically by podcast clients, which is what this actor does - it sends a descriptive User-Agent, reads the feed once per run, and stops downloading as soon as it has the episodes in your window. Even so, "publicly reachable" and "permitted by the publisher's terms" are separate questions: an individual podcast, host or network may have terms of service or feed policies that restrict automated access, redistribution, or commercial use of its feed content, regardless of the feed being public. Using this actor may not comply with those terms. Show notes are also the publisher's copyrighted material; this actor extracts factual data points from them (links, brand domains, codes) rather than republishing the notes, but how you store, redistribute or publish the output is your responsibility.

Apple's iTunes Search / Lookup API (used only when you supply applePodcastIds or searchTerms). This is a public endpoint Apple provides without an API key, but it is governed by Apple's own terms, which restrict how the returned data may be used and rate-limit requests to roughly 20 per minute per IP. Review Apple's current terms before relying on this path, and prefer supplying feedUrls directly if you do not want Apple in the loop at all - the actor never calls Apple when only feedUrls is set.

You are responsible for your own compliance with all of the above, and for how you use the returned data - including any competitive-intelligence, outreach or advertising use, and any applicable local law. If you are unsure whether your use case is permitted, take your own legal advice.