Skip to content

Episodes endpoint

The episodes endpoint allows synchronising user-generated episode metadata. As the RSS feed is the authoritative source of truth, episode metadata such as title are only synchronised in some cases for episode identification and matching.

Clients can query the endpoint by specifying the datetime from which they want to fetch changes to ensure they only fetch information that is relevant to them since their last sync.

We distinguish two types of data fields: identifier fields (used to identify and match episodes) and data fields (used to synchronise users’ interaction with episodes).

FieldTypeNullable?Description
podcast_guidString <UUID>NoThe globally unique ID of the podcast
sync_idString <UUID>NoThe synchronisation ID of the episode, MUST globally unique across the server and its clients [K-NL: and what about users - do users’ episodes share the same sync_ids? It would make sense but at the same time user 1 might use a client X which does deduplication in a different way than client Y and so the two users would get different deduplication results, and thus their episodes in the server’s database couldn’t be merged.]
temporary_id OptionalStringYesThe ID used by the client when sending new episode information to the server, to make episode identification easier when receiving a response
episode_guidString <UUID>YesThe globally unique ID of the episode, as present in the RSS feed (guid tag)
titleStringYesThe title of the episode, as present in the RSS feed (title tag)
publish_dateDatetimeYesThe date of publishing of the episode, as present in the RSS feed (pubDate tag). Presented in ISO 8601 format
enclosure_urlStringYesThe media file of the episode, as present in the RSS feed (enclosure tag)
episode_urlStringYesThe (webpage) URL of the episode, as present in the RSS feed (linktag)
FieldTypeNullable?Description
playback_positionIntegerYes/No?The most recent playback position
played_statusBooleanNoWhether the episode has ben (marked as)
new_status OptionalBooleanYesWhether the user (manually) interacted with the episode.
Example: In AntennaPod this is used to indicate whether an episode is in the Inbox
download_status OptionalBooleanYesWhether the episode is downloaded on the client. For further details, see below.
favorite_status OptionalBooleanYesWhether the episode has been favorited by the user

When fetching a feed, several scenarios could lead to duplicated episdes if not matched correctly. To ensure that in these cases episode must be matched and deduplicated to ensure their data is still synced. For details on this topic, please see Episode matching & deduplication.

The download_status is a declaration of intent, not an indication of the current status. If a user downloads an episode on client A, this client passes on this value to the server and thereby to other clients. Client B can then:

  • download immediately
  • download later (e.g. as soon as a WiFi connection is availalbe)

It is up to the implementers whether this applies both to automatic and manual downloads, or only to manual downloads.

While an optional field, if download_status is supported both by the server and the client, the client is expected to respect this field value. If the client may not download due to space limitations or won’t download at all, then it should not declare support for this field.

Timestamping changes to resolve field conflicts

Section titled “Timestamping changes to resolve field conflicts”

To prevent unresolvable conflicts at field level, apps are expected to record timestamps. These MUST be the time at which a field value was changed in the client (by the user or system). More recent values take presedence. The time of sending by the client or processing by the client should not be sent.

To enable this, all data fields are nested objects with a value and a timestamp field:

{
"played_status": {
"value": true,
"timestamp": "2024-06-19T15:46"
}
}

Timestamps are recorded in ISO 8601 format. When a new episode is created, timestamps are set to current time.