A podcast episode belonging to a series
tid
Timestamp-based ID
Properties
audio
blob
Optional
Audio file reference
maxSize: 524.3 MBaudioLength
integer
Optional
Byte size of the audio file when using audioUrl. Required for a valid RSS enclosure — without this, a firehose consumer cannot reconstruct the feed from records alone.
minimum: 0audioType
string
Optional
MIME type of the audio file when using audioUrl. Pairs with audioLength for RSS enclosure reconstruction.
maxLength: 64 bytesaudio/mpeg, audio/mp4, audio/wav, audio/ogg, audio/aacaudioUrl
string
uri
Optional
External audio URL (if not using blob)
blueskyPostRef
ref
com.atproto.repo.strongRef
Optional
Reference to the Atmosphere cross-post (app.bsky.feed.post) for this episode. Set when the episode is auto-cross-posted, enabling custom feed operators to discover the cross-post from the episode record.
chapters
array
of
ref
#chapter
Optional
Episode chapters/timestamps
maxLength: 100 itemscreatedAt
string
datetime
Required
An RFC 3339 formatted timestamp.
duration
integer
Optional
Duration in seconds
minimum: 0episodeNumber
integer
Optional
Episode number in series
minimum: 1episodeType
string
Optional
Episode type per RSS spec
maxLength: 16 bytesfull, trailer, bonusfullexplicit
boolean
Optional
Whether episode is explicit
image
blob
Optional
Episode-specific cover art
maxSize: 2.1 MBimportedGuid
string
Optional
Original GUID from RSS feed (for imported episodes)
maxLength: 2048 bytespersons
array
of
ref
#person
Optional
People associated with this episode — hosts, guests, co-hosts (Podcasting 2.0 podcast:person)
maxLength: 50 itemspublishedAt
string
datetime
Optional
Publication date (null = draft)
seasonNumber
integer
Optional
Season number
minimum: 1series
ref
live.voxport.podcast.series#seriesRef
Required
Reference to parent series (uri + optional cid)
soundbites
array
of
ref
#soundbite
Optional
Short clip markers for apps to surface (Podcasting 2.0 podcast:soundbite)
maxLength: 20 itemssummary
string
Optional
Episode description/show notes (supports markdown)
maxLength: 10000 bytestags
array
of
string
Optional
Episode tags/keywords
maxLength: 20 itemstitle
string
Required
Episode title
maxLength: 256 bytestranscript
ref
#transcript
Optional
Episode transcript (singular — deprecated, prefer transcripts array)
transcripts
array
of
ref
#transcript
Optional
Episode transcripts — multiple entries for different languages/formats (Podcasting 2.0 podcast:transcript). Preferred over the singular transcript field.
maxLength: 20 itemsupdatedAt
string
datetime
Optional
An RFC 3339 formatted timestamp.
View raw schema
{
"key": "tid",
"type": "record",
"record": {
"type": "object",
"required": [
"series",
"title",
"createdAt"
],
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string",
"maxLength": 64
},
"maxLength": 20,
"description": "Episode tags/keywords"
},
"audio": {
"type": "blob",
"accept": [
"audio/mpeg",
"audio/mp4",
"audio/wav",
"audio/ogg",
"audio/aac"
],
"maxSize": 524288000,
"description": "Audio file reference"
},
"image": {
"type": "blob",
"accept": [
"image/png",
"image/jpeg"
],
"maxSize": 2097152,
"description": "Episode-specific cover art"
},
"title": {
"type": "string",
"maxLength": 256,
"description": "Episode title"
},
"series": {
"ref": "live.voxport.podcast.series#seriesRef",
"type": "ref",
"description": "Reference to parent series (uri + optional cid)"
},
"persons": {
"type": "array",
"items": {
"ref": "#person",
"type": "ref"
},
"maxLength": 50,
"description": "People associated with this episode — hosts, guests, co-hosts (Podcasting 2.0 podcast:person)"
},
"summary": {
"type": "string",
"maxLength": 10000,
"description": "Episode description/show notes (supports markdown)"
},
"audioUrl": {
"type": "string",
"format": "uri",
"description": "External audio URL (if not using blob)"
},
"chapters": {
"type": "array",
"items": {
"ref": "#chapter",
"type": "ref"
},
"maxLength": 100,
"description": "Episode chapters/timestamps"
},
"duration": {
"type": "integer",
"minimum": 0,
"description": "Duration in seconds"
},
"explicit": {
"type": "boolean",
"description": "Whether episode is explicit"
},
"audioType": {
"type": "string",
"maxLength": 64,
"description": "MIME type of the audio file when using audioUrl. Pairs with audioLength for RSS enclosure reconstruction.",
"knownValues": [
"audio/mpeg",
"audio/mp4",
"audio/wav",
"audio/ogg",
"audio/aac"
]
},
"createdAt": {
"type": "string",
"format": "datetime"
},
"updatedAt": {
"type": "string",
"format": "datetime"
},
"soundbites": {
"type": "array",
"items": {
"ref": "#soundbite",
"type": "ref"
},
"maxLength": 20,
"description": "Short clip markers for apps to surface (Podcasting 2.0 podcast:soundbite)"
},
"transcript": {
"ref": "#transcript",
"type": "ref",
"description": "Episode transcript (singular — deprecated, prefer transcripts array)"
},
"audioLength": {
"type": "integer",
"minimum": 0,
"description": "Byte size of the audio file when using audioUrl. Required for a valid RSS enclosure — without this, a firehose consumer cannot reconstruct the feed from records alone."
},
"episodeType": {
"type": "string",
"default": "full",
"maxLength": 16,
"description": "Episode type per RSS spec",
"knownValues": [
"full",
"trailer",
"bonus"
]
},
"publishedAt": {
"type": "string",
"format": "datetime",
"description": "Publication date (null = draft)"
},
"transcripts": {
"type": "array",
"items": {
"ref": "#transcript",
"type": "ref"
},
"maxLength": 20,
"description": "Episode transcripts — multiple entries for different languages/formats (Podcasting 2.0 podcast:transcript). Preferred over the singular transcript field."
},
"importedGuid": {
"type": "string",
"maxLength": 2048,
"description": "Original GUID from RSS feed (for imported episodes)"
},
"seasonNumber": {
"type": "integer",
"minimum": 1,
"description": "Season number"
},
"episodeNumber": {
"type": "integer",
"minimum": 1,
"description": "Episode number in series"
},
"blueskyPostRef": {
"ref": "com.atproto.repo.strongRef",
"type": "ref",
"description": "Reference to the Atmosphere cross-post (app.bsky.feed.post) for this episode. Set when the episode is auto-cross-posted, enabling custom feed operators to discover the cross-post from the episode record."
}
}
},
"description": "A podcast episode belonging to a series"
}