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.
Important data fields
Section titled “Important data fields”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).
Identifier fields
Section titled “Identifier fields”Field | Type | Nullable? | Description |
---|---|---|---|
podcast_guid | String <UUID> | No | The globally unique ID of the podcast |
sync_id | String <UUID> | No | The 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_id s? 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 Optional | String | Yes | The ID used by the client when sending new episode information to the server, to make episode identification easier when receiving a response |
episode_guid | String <UUID> | Yes | The globally unique ID of the episode, as present in the RSS feed (guid tag) |
title | String | Yes | The title of the episode, as present in the RSS feed (title tag) |
publish_date | Datetime | Yes | The date of publishing of the episode, as present in the RSS feed (pubDate tag). Presented in ISO 8601 format |
enclosure_url | String | Yes | The media file of the episode, as present in the RSS feed (enclosure tag) |
episode_url | String | Yes | The (webpage) URL of the episode, as present in the RSS feed (link tag) |
Data fields
Section titled “Data fields”Field | Type | Nullable? | Description |
---|---|---|---|
playback_position | Integer | Yes/No? | The most recent playback position |
played_status | Boolean | No | Whether the episode has ben (marked as) |
new_status Optional | Boolean | Yes | Whether the user (manually) interacted with the episode. Example: In AntennaPod this is used to indicate whether an episode is in the Inbox |
download_status Optional | Boolean | Yes | Whether the episode is downloaded on the client. For further details, see below. |
favorite_status Optional | Boolean | Yes | Whether the episode has been favorited by the user |
Implementation details
Section titled “Implementation details”Deduplication
Section titled “Deduplication”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.
Download status
Section titled “Download status”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" } }
<?xml version="1.0" encoding="UTF-8"?> <played_status> <value>true</value> <timestamp>2024-06-19T15:46</timestamp> </played_status>
Timestamps are recorded in ISO 8601 format. When a new episode is created, timestamps are set to current time.