RSS Namespace Extension for Podcasting (Tag Specification)

A wholistic RSS namespace for podcasting that is meant to synthesize the fragmented world of podcast namespaces. As elements are canonized, they will be added to this document so developers can begin implementation. The specifications below are considered locked and the team will prioritize backward compatibility. We are operating under the Rules for Standards-Makers.

The namespace for this extension is https://podcastindex.org/namespace/1.0. Clients which recognize this namespace must also recognize https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md as identical. The suggested tag prefix for use in XML is podcast, but clients should support alternate prefixes for this namespace. If your application generates RSS feeds and you implement one or more elements below, you will need to link this document in your XML:

<rss version="2.0" xmlns:podcast="https://podcastindex.org/namespace/1.0">

Podcast Tags

Each tag below exists in the podcast namespace within the specified parent. All attributes are required unless explicitly specified as optional.

Anywhere the url of a hyper-text based resource is specified, it must be given as https: and not http:.



Transcript

<podcast:transcript> This tag is used to link to a transcript or closed captions file. Multiple tags can be present for multiple transcript formats.

Parent

<item>

Count

Multiple

Attributes

Examples

<podcast:transcript url="https://example.com/episode1/transcript.html" type="text/html" />

<podcast:transcript url="https://example.com/episode1/transcript.srt" type="text/srt" rel="captions" />

<podcast:transcript url="https://example.com/episode1/transcript.json" type="application/json" language="es" rel="captions" />

<podcast:transcript url="https://example.com/episode1/transcript.vtt" type="text/vtt" />

Detailed file format information and example files are here.



Locked

<podcast:locked> This tag may be set to yes or no. The purpose is to tell other podcast platforms whether they are allowed to import this feed. A value of yes means that any attempt to import this feed into a new platform should be rejected.

Parent

<channel>

Count

Single

Attributes

Examples

<podcast:locked owner="[email protected]">yes</podcast:locked>

<podcast:locked owner="[email protected]">no</podcast:locked>



Funding

<podcast:funding> This tag lists possible donation/funding links for the podcast. The content of the tag is the recommended string to be used with the link.

Parent

<channel>

Count

Multiple

Attributes

Examples

<podcast:funding url="https://www.example.com/donations">Support the show!</podcast:funding>

<podcast:funding url="https://www.example.com/members">Become a member!</podcast:funding>

Please do not exceed 128 characters for the node value or it may be truncated by aggregators.



Chapters

<podcast:chapters> Links to an external file (see example file) containing chapter data for the episode. See the jsonChapters.md file for a description of the chapter file syntax. And, see the example.json example file for a real world example.

Parent

<item>

Count

Single

Attributes

Examples

<podcast:chapters url="https://example.com/episode1/chapters.json" type="application/json+chapters" />



Soundbite

<podcast:soundbite> Points to one or more soundbites within a podcast episode. The intended use includes episodes previews, discoverability, audiogram generation, episode highlights, etc. It should be assumed that the audio/video source of the soundbite is the audio/video given in the item's <enclosure> element.

Parent

<item>

Count

Multiple

Attributes

Examples

<podcast:soundbite startTime="73.0" duration="60.0" />

<podcast:soundbite startTime="1234.5" duration="42.25">Why the Podcast Namespace Matters</podcast:soundbite>

Please do not exceed 128 characters for the node value or it may be truncated by aggregators.



Person

<podcast:person> This element specifies a person of interest to the podcast. It is primarily intended to identify people like hosts, co-hosts and guests. Although, it is flexible enough to allow fuller credits to be given using the roles and groups that are listed in the Podcast Taxonomy Project

Parent

<item> or <channel>

Count

Multiple

Node value

This is the full name or alias of the person. This value cannot be blank.

Attributes

The role and group attributes are case-insensitive. So, "Host" is the same as "host", and "Cover Art Designer" is the same as "cover art designer".

The full taxonomy list is here as a json file.

Please do not exceed 128 characters for the node value or they may be truncated by aggregators.

Examples

<podcast:person href="https://example.com/johnsmith/blog" img="http://example.com/images/johnsmith.jpg">John Smith</podcast:person>

<podcast:person role="guest" href="https://www.imdb.com/name/nm0427852888/" img="http://example.com/images/janedoe.jpg">Jane Doe</podcast:person>

<podcast:person role="guest" href="https://www.wikipedia/alicebrown" img="http://example.com/images/alicebrown.jpg">Alice Brown</podcast:person>

<podcast:person group="writing" role="guest" href="https://www.wikipedia/alicebrown" img="http://example.com/images/alicebrown.jpg">Alice Brown</podcast:person>

<podcast:person group="visuals" role="Cover Art Designer" href="https://example.com/artist/beckysmith">Becky Smith</podcast:person>



Location

<podcast:location> This tag is intended to describe the location of editorial focus for a podcast's content (i.e. "what place is this podcast about?"). The tag has many use cases and is one of the more complex ones. You are highly encouraged to read the full implementation document before starting to code for it.

Parent

<item> or <channel>

Count

Single

Node Value

This is a free-form string meant to be a human readable location. It may conform to conventional location verbiage (i.e. "Austin, TX"), but it shouldn't be depended on to be parseable in any specific way. This value cannot be blank.

Attributes

Please do not exceed 128 characters for the node value or it may be truncated by aggregators.

Examples

<podcast:location geo="geo:30.2672,97.7431" osm="R113314">Austin, TX</podcast:location>

<podcast:location geo="geo:33.51601,-86.81455" osm="R6930627">Birmingham Civil Rights Museum</podcast:location>

<podcast:location geo="geo:-27.86159,153.3169" osm="W43678282">Dreamworld (Queensland)</podcast:location>

Please see the implementation document and the example feed for more examples.



Season

<podcast:season> This element allows for identifying which episodes in a podcast are part of a particular "season", with an optional season name attached.

Parent

<item>

Count

Single

Node Value

The node value is an integer, and represents the season "number". It is required.

Attributes

Please do not exceed 128 characters for the name attribute.

Examples

<podcast:season>5</podcast:season>

<podcast:season name="Race for the Whitehouse 2020">3</podcast:season>

<podcast:season name="Egyptology: The 19th Century">1</podcast:season>

<podcast:season name="The Yearling - Chapter 3">3</podcast:season>



Episode

<podcast:episode> This element exists largely for compatibility with the season tag. But, it also allows for a similar idea to what "name" functions as in that element.

Parent

<item>

Count

Single

Node Value

The node value is a decimal number. It is required.

Attributes

The episode numbers are decimal, so numbering such as 100.5 is acceptable if there was a special mini-episode published between two other episodes. In that scenario, the number would help with proper chronological sorting, while the display attribute could specify an alternate special "number" (a moniker) to display for the episode in a podcast player app UI.

Please do not exceed 32 characters for the display attribute.

Examples

<podcast:episode>3</podcast:episode>

<podcast:episode>315.5</podcast:episode>

<podcast:episode display="Ch.3">204</podcast:episode>

<podcast:episode display="Day 5">9</podcast:episode>



Trailer

<podcast:trailer> This element is used to define the location of an audio or video file to be used as a trailer for the entire podcast or a specific season. There can be more than one trailer present in the channel of the feed. This element is basically just like an <enclosure> with the extra pubdate and season attributes added.

Parent

<channel>

Count

Multiple

Node Value

The node value is a string, which is the title of the trailer. It is required.

Attributes

If there is more than one trailer tag present in the channel, the most recent one (according to its pubdate) should be chosen as the preview by default within podcast apps. If the season attribute is present, it must be a number that matches the format of the <podcast:season> tag. So, for a podcast that has 3 published seasons, a new <podcast:trailer season="4"> tag can be put in the channel to later be matched up with a <podcast:season>4<podcast:season> tag when it is published within a new <item>.

Examples

<podcast:trailer pubdate="Thu, 01 Apr 2021 08:00:00 EST" url="https://example.org/trailers/teaser" length="12345678" type="audio/mp3">Coming April 1st, 2021</podcast:trailer>
<podcast:trailer pubdate="Thu, 01 Apr 2021 08:00:00 EST" url="https://example.org/trailers/season4teaser" length="12345678" type="video/mp4" season="4">Season 4: Race for the Whitehouse</podcast:trailer>

(later matches with)

<podcast:season name="Race for the Whitehouse">4</podcast:season>



License

<podcast:license> This element defines a license that is applied to the audio/video content of a single episode, or the audio/video of the podcast as a whole. Custom licenses must always include a url attribute. Implementors are encouraged to read the license tag companion document for a more complete picture of what this tag is intended to accomplish.

Parent

<channel> or <item>

Count

Single

Node Value

The node value must be a lower-cased reference to a license "identifier" defined in the SPDX License List file if the license being used is a well-known, public license. Or, if it is a custom license, it must be a free form abbreviation of the name of the license as you reference it publicly.

Attributes

Examples

<podcast:license>cc-by-4.0</podcast:license>

<podcast:license url="https://example.org/mypodcastlicense/full.pdf">my-podcast-license-v1</podcast:license>



Alternate Enclosure

<podcast:alternateEnclosure> This element is meant to provide different versions of, or companion media to the main <enclosure> file. This could be an audio only version of a video podcast to allow apps to switch back and forth between audio/video, lower (or higher) bitrate versions for bandwidth constrained areas, alternative codecs for different device platforms, alternate URI schemes and download types such as IPFS or WebTorrent, commentary tracks or supporting source clips, etc. This is a complex tag, so implementors are highly encouraged to read the companion document for a fuller understanding of how this tag works and what it is capable of.

Parent

<item>

Count

Multiple

Node Value

The node value must be one or more <podcast:source> elements that each define a uri where the media file can be downloaded or streamed. A single, optional <podcast:integrity> element may also be included to allow for file integrity checking.

Attributes

Examples

<enclosure url="https://example.com/file-0.mp3" length="43200000" type="audio/mpeg" />

<podcast:alternateEnclosure type="audio/mpeg" length="43200000" bitrate="128000" default="true" title="Standard">
    <podcast:source uri="https://example.com/file-0.mp3" />
    <podcast:source uri="ipfs://someRandomMpegFile" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="audio/opus" length="32400000" bitrate="96000" title="High quality">
    <podcast:source uri="https://example.com/file-high.opus" />
    <podcast:source uri="ipfs://someRandomHighBitrateOpusFile" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="audio/aac" length="54000000" bitrate="160000" title="High quality AAC">
    <podcast:source uri="https://example.com/file-proprietary.aac" />
    <podcast:source uri="ipfs://someRandomProprietaryAACFile" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="audio/opus" length="5400000" bitrate="16000" title="Low bandwidth">
    <podcast:source uri="https://example.com/file-low.opus" />
    <podcast:source uri="ipfs://someRandomLowBitrateOpusFile" />
</podcast:alternateEnclosure>
<podcast:alternateEnclosure type="audio/mpeg" length="2490970" bitrate="160707.74">
    <podcast:source uri="https://example.com/file-0.mp3" />
    <podcast:source uri="ipfs://QmdwGqd3d2gFPGeJNLLCshdiPert45fMu84552Y4XHTy4y" />
    <podcast:source uri="https://example.com/file-0.torrent" contentType="application/x-bittorrent" />
    <podcast:source uri="http://example.onion/file-0.mp3" />
</podcast:alternateEnclosure>

<podcast:alternateEnclosure type="video/mp4" length="10562995" bitrate="681483.55" height="1080">
    <podcast:source uri="https://example.com/file-1080.mp4" />
    <podcast:source uri="ipfs://QmfQKJcp2xdByEt8mzWr1AJUhwvb9rdWPoacvdq2roDhgh" />
    <podcast:source uri="https://example.com/file-1080.torrent" contentType="application/x-bittorrent" />
    <podcast:source uri="http://example.onion/file-1080.mp4" />
</podcast:alternateEnclosure>



Source

<podcast:source> This element defines a uri location for a <podcast:alternateEnclosure> media file. It is meant to be used as a child of the <podcast:alternateEnclosure> element. At least one <podcast:source> element must be present within every <podcast:alternateEnclosure> element.

Parent

<podcast:alternateEnclosure>

Count

Multiple

Node Value

None

Attributes

Examples

<podcast:alternateEnclosure type="video/mp4" length="7924786" bitrate="511276.52" height="720">
    <podcast:source uri="https://example.com/file-720.mp4" />
    <podcast:source uri="ipfs://QmX33FYehk6ckGQ6g1D9D3FqZPix5JpKstKQKbaS8quUFb" />
    <podcast:source uri="https://example.com/file-720.torrent" contentType="application/x-bittorrent" />
    <podcast:source uri="http://example.onion/file-720.mp4" />
</podcast:alternateEnclosure>



Integrity

<podcast:integrity> This element defines a method of verifying integrity of the media given either an SRI-compliant integrity string (preferred) or a base64 encoded PGP signature. This element is optional within a <podcast:alternateEnclosure> element. It allows to ensure that the file has not been tampered with.

Parent

<podcast:alternateEnclosure>

Count

Single

Node Value

None

Attributes

Examples

<podcast:alternateEnclosure type="video/mp4" length="7924786" bitrate="511276.52" height="720">
    <podcast:source uri="https://example.com/file-720.mp4" />
    <podcast:source uri="ipfs://QmX33FYehk6ckGQ6g1D9D3FqZPix5JpKstKQKbaS8quUFb" />
    <podcast:integrity type="sri" value="sha384-ExVqijgYHm15PqQqdXfW95x+Rs6C+d6E/ICxyQOeFevnxNLR/wtJNrNYTjIysUBo" />
</podcast:alternateEnclosure>



Guid

<podcast:guid> This element is used to declare a unique, global identifier for a podcast. The value is a UUIDv5, and is easily generated from the RSS feed url, with the protocol scheme and trailing slashes stripped off, combined with a unique "podcast" namespace which has a UUID of ead4c236-bf58-58c6-a2c6-a6b28d128cb6. Tools like this one can help generate these values by hand. Or, language libraries like this one in Ruby are widely available.

A podcast gets assigned a podcast:guid once in its lifetime using its current feed url (at the time of assignment) as the seed value. That GUID is then meant to follow the podcast from then on, for the duration of its life, even if the feed url changes. This means that when a podcast moves from one hosting platform to another, its podcast:guid should be discovered by the new host and imported into the new platform for inclusion into the feed.

Using this pattern, podcasts can maintain a consistent identity across the open RSS ecosystem without a central authority.

Tips: A GUID is 36 characters long. All podcasts in the Podcast Index have already been assigned a GUID; but if one exists in the RSS feed, that value is canonical.

Parent

<channel>

Count

Single

Node Value

The node value is a UUIDv5 string.

Attributes

There are no attributes for this tag.

Examples

Example GUID for feed url mp3s.nashownotes.com/pc20rss.xml:

<podcast:guid>917393e3-1b1e-5cef-ace4-edaa54e1f810</podcast:guid>

Example GUID for feed url podnews.net/rss:

<podcast:guid>9b024349-ccf0-5f69-a609-6b82873eab3c</podcast:guid>

The podcast:guid value above enables podcasters to produce a link that can share a podcast on a variety of different platforms.

The format of the link is https://(a podcast website link)#fastfollow-(type):(a podcast guid)

type is currently podcast, but may be extended in future.

A working example is https://podnews.net/podcast/i8xe9/listen#fastfollow-podcast:9b024349-ccf0-5f69-a609-6b82873eab3c or the QR code given below.

podnews-qr

When scanned on a mobile phone's camera app, this link will go to the specified podcast website. Behavior of this website is up to the creator: some may use a default homepage, others may sniff the useragent and open a default podcast app on a device. In the working example, above, an iPhone user may be taken to Apple Podcasts; an Android user may be taken to Google Podcasts; and another device will be given a page with a player.

When scanned on a QR code reader inside a podcast app, like CurioCaster, the app can parse the podcast:guid value from the URL, allowing the podcast to be opened within the application.