place.pod.episode
Schema Diff
+70 -7
Compatibility Analysis
Breaking Changes Detected
10 breaking changes, 21 non-breaking changes.
Breaking Changes (10)
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "place.pod.episode:body", src: "place.pod.episode:body", tgt: "place.pod.episode:body.audioSizeBytes", kind: "prop", name: Some("audioSizeBytes") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "place.pod.episode:body", src: "place.pod.episode:body", tgt: "place.pod.episode:body.guid", kind: "prop", name: Some("guid") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "place.pod.episode:body", src: "place.pod.episode:body", tgt: "place.pod.episode:body.audioMimeType", kind: "prop", name: Some("audioMimeType") }
- RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "place.pod.episode:body", src: "place.pod.episode:body", tgt: "place.pod.episode:body.description", kind: "prop", name: Some("description") }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.chaptersUrl", sort: "maxLength", value: "2048" }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.transcriptUrl", sort: "maxLength", value: "2048" }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.audioUrl", sort: "maxLength", value: "2048" }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.durationSeconds", sort: "minimum", value: "0" }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.audioSizeBytes", sort: "minimum", value: "0" }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.imageUrl", sort: "maxLength", value: "2048" }
Non-Breaking Changes (21)
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.alternateEnclosures" }
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.alternateEnclosures:items" }
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.chaptersMimeType" }
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.episodeType" }
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.guid" }
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.link" }
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.people" }
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.people:items" }
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.soundbites" }
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.soundbites:items" }
- AddedVertex AddedVertex { vertex_id: "place.pod.episode:body.transcriptMimeType" }
- AddedEdge AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.alternateEnclosures", kind: "prop", name: Some("alternateEnclosures") }
- AddedEdge AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.chaptersMimeType", kind: "prop", name: Some("chaptersMimeType") }
- AddedEdge AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.episodeType", kind: "prop", name: Some("episodeType") }
- AddedEdge AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.link", kind: "prop", name: Some("link") }
- AddedEdge AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.people", kind: "prop", name: Some("people") }
- AddedEdge AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.soundbites", kind: "prop", name: Some("soundbites") }
- AddedEdge AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.transcriptMimeType", kind: "prop", name: Some("transcriptMimeType") }
- AddedEdge AddedEdge { src: "place.pod.episode:body.alternateEnclosures", tgt: "place.pod.episode:body.alternateEnclosures:items", kind: "items", name: None }
- AddedEdge AddedEdge { src: "place.pod.episode:body.people", tgt: "place.pod.episode:body.people:items", kind: "items", name: None }
- AddedEdge AddedEdge { src: "place.pod.episode:body.soundbites", tgt: "place.pod.episode:body.soundbites:items", kind: "items", name: None }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "place.pod.episode:body.alternateEnclosures" }AddedVertex { vertex_id: "place.pod.episode:body.alternateEnclosures:items" }AddedVertex { vertex_id: "place.pod.episode:body.chaptersMimeType" }AddedVertex { vertex_id: "place.pod.episode:body.episodeType" }AddedVertex { vertex_id: "place.pod.episode:body.guid" }AddedVertex { vertex_id: "place.pod.episode:body.link" }AddedVertex { vertex_id: "place.pod.episode:body.people" }AddedVertex { vertex_id: "place.pod.episode:body.people:items" }AddedVertex { vertex_id: "place.pod.episode:body.soundbites" }AddedVertex { vertex_id: "place.pod.episode:body.soundbites:items" }AddedVertex { vertex_id: "place.pod.episode:body.transcriptMimeType" }
Constraint Changes
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.audioUrl", sort: "maxLength", value: "2048" }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.chaptersUrl", sort: "maxLength", value: "2048" }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.durationSeconds", sort: "minimum", value: "0" }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.imageUrl", sort: "maxLength", value: "2048" }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.transcriptUrl", sort: "maxLength", value: "2048" }
- ConstraintAdded ConstraintAdded { vertex_id: "place.pod.episode:body.audioSizeBytes", sort: "minimum", value: "0" }
Additional Notes
- Breaking: RequiredEdgeAdded { vertex_id: "place.pod.episode:body", src: "place.pod.episode:body", tgt: "place.pod.episode:body.audioSizeBytes", kind: "prop", name: Some("audioSizeBytes") }
- Breaking: RequiredEdgeAdded { vertex_id: "place.pod.episode:body", src: "place.pod.episode:body", tgt: "place.pod.episode:body.guid", kind: "prop", name: Some("guid") }
- Breaking: RequiredEdgeAdded { vertex_id: "place.pod.episode:body", src: "place.pod.episode:body", tgt: "place.pod.episode:body.audioMimeType", kind: "prop", name: Some("audioMimeType") }
- Breaking: RequiredEdgeRemoved { vertex_id: "place.pod.episode:body", src: "place.pod.episode:body", tgt: "place.pod.episode:body.description", kind: "prop", name: Some("description") }
- Non-breaking: AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.alternateEnclosures", kind: "prop", name: Some("alternateEnclosures") }
- Non-breaking: AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.chaptersMimeType", kind: "prop", name: Some("chaptersMimeType") }
- Non-breaking: AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.episodeType", kind: "prop", name: Some("episodeType") }
- Non-breaking: AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.link", kind: "prop", name: Some("link") }
- Non-breaking: AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.people", kind: "prop", name: Some("people") }
- Non-breaking: AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.soundbites", kind: "prop", name: Some("soundbites") }
- Non-breaking: AddedEdge { src: "place.pod.episode:body", tgt: "place.pod.episode:body.transcriptMimeType", kind: "prop", name: Some("transcriptMimeType") }
- Non-breaking: AddedEdge { src: "place.pod.episode:body.alternateEnclosures", tgt: "place.pod.episode:body.alternateEnclosures:items", kind: "items", name: None }
- Non-breaking: AddedEdge { src: "place.pod.episode:body.people", tgt: "place.pod.episode:body.people:items", kind: "items", name: None }
- Non-breaking: AddedEdge { src: "place.pod.episode:body.soundbites", tgt: "place.pod.episode:body.soundbites:items", kind: "items", name: None }
1
1
{
2
2
"$type": "com.atproto.lexicon.schema",
3
3
"defs": {
4
4
"main": {
5
5
"description": "A single podcast episode.",
6
6
"key": "tid",
7
7
"record": {
8
8
"properties": {
9
+
"alternateEnclosures": {
10
+
"description": "Optional Podcasting 2.0 alternate media files with technical metadata.",
11
+
"items": {
12
+
"maxLength": 2048,
13
+
"type": "string"
14
+
},
15
+
"type": "array"
16
+
},
9
17
"audioMimeType": {
10
-
"description": "MIME type of the audio file. Common values: audio/mpeg, audio/wav, audio/aac.",
18
+
"description": "MIME type for the RSS enclosure, such as audio/mpeg or audio/mp4.",
11
19
"maxLength": 100,
12
20
"type": "string"
13
21
},
14
22
"audioSizeBytes": {
15
-
"description": "File size of the audio asset in bytes. Useful for download progress indicators.",
23
+
"description": "Audio file size in bytes for the RSS enclosure length attribute.",
24
+
"minimum": 0,
16
25
"type": "integer"
17
26
},
18
27
"audioUrl": {
19
28
"description": "Direct URL to the audio file. Must be publicly accessible and use HTTPS.",
20
29
"format": "uri",
30
+
"maxLength": 2048,
31
+
"type": "string"
32
+
},
33
+
"chaptersMimeType": {
34
+
"description": "MIME type for chaptersUrl; required when exporting podcast:chapters.",
35
+
"maxLength": 100,
21
36
"type": "string"
22
37
},
23
38
"chaptersUrl": {
24
-
"description": "URL to a chapters file. Accepts JSON or WebVTT formats.",
39
+
"description": "URL to a chapters file.",
25
40
"format": "uri",
41
+
"maxLength": 2048,
26
42
"type": "string"
27
43
},
28
44
"createdAt": {
29
45
"description": "ISO 8601 timestamp of when the episode record was created.",
30
46
"format": "datetime",
31
47
"type": "string"
32
48
},
33
49
"description": {
34
50
"description": "Summary or show notes for the episode. May contain basic formatting.",
35
51
"maxGraphemes": 4000,
36
52
"type": "string"
37
53
},
38
54
"durationSeconds": {
39
55
"description": "Length of the episode in whole seconds. Strongly recommended for player UX.",
56
+
"minimum": 0,
40
57
"type": "integer"
41
58
},
42
59
"episodeNumber": {
43
60
"description": "Episode number within the season or series.",
44
61
"type": "integer"
45
62
},
63
+
"episodeType": {
64
+
"description": "Apple episode type. Full is the default when omitted.",
65
+
"knownValues": [
66
+
"full",
67
+
"trailer",
68
+
"bonus"
69
+
],
70
+
"maxLength": 20,
71
+
"type": "string"
72
+
},
46
73
"explicit": {
47
-
"description": "Whether this specific episode contains explicit content. Defaults to false if omitted.",
74
+
"description": "Whether this specific episode contains explicit content.",
48
75
"type": "boolean"
49
76
},
77
+
"guid": {
78
+
"description": "Globally unique, immutable episode identifier required by Apple and PSP.",
79
+
"maxLength": 255,
80
+
"type": "string"
81
+
},
50
82
"imageUrl": {
51
83
"description": "Episode-specific artwork URL. Falls back to show cover if omitted.",
52
84
"format": "uri",
85
+
"maxLength": 2048,
86
+
"type": "string"
87
+
},
88
+
"link": {
89
+
"description": "Public webpage for the episode, corresponding to the RSS item link.",
90
+
"format": "uri",
91
+
"maxLength": 2048,
53
92
"type": "string"
54
93
},
94
+
"people": {
95
+
"description": "Structured episode credits such as hosts, guests, and producers.",
96
+
"items": {
97
+
"maxLength": 100,
98
+
"type": "string"
99
+
},
100
+
"type": "array"
101
+
},
55
102
"publishedAt": {
56
103
"description": "ISO 8601 timestamp when the episode was published. May differ from createdAt.",
57
104
"format": "datetime",
58
105
"type": "string"
59
106
},
60
107
"seasonNumber": {
61
108
"description": "Season number the episode belongs to.",
62
109
"type": "integer"
63
110
},
64
111
"showUri": {
65
112
"description": "AT Protocol URI of the parent place.pod.show record.",
66
113
"format": "uri",
67
114
"type": "string"
68
115
},
116
+
"soundbites": {
117
+
"description": "Optional Podcasting 2.0 highlights with start times and durations.",
118
+
"items": {
119
+
"maxLength": 255,
120
+
"type": "string"
121
+
},
122
+
"type": "array"
123
+
},
69
124
"title": {
70
125
"description": "Title of the episode.",
71
126
"maxLength": 200,
72
127
"type": "string"
73
128
},
129
+
"transcriptMimeType": {
130
+
"description": "MIME type for transcriptUrl; required when exporting podcast:transcript.",
131
+
"maxLength": 100,
132
+
"type": "string"
133
+
},
74
134
"transcriptUrl": {
75
-
"description": "URL to a transcript file. Improves accessibility and searchability.",
135
+
"description": "URL to a transcript file.",
76
136
"format": "uri",
137
+
"maxLength": 2048,
77
138
"type": "string"
78
139
}
79
140
},
80
141
"required": [
81
142
"showUri",
82
143
"title",
83
-
"description",
84
144
"audioUrl",
85
-
"createdAt"
145
+
"createdAt",
146
+
"guid",
147
+
"audioMimeType",
148
+
"audioSizeBytes"
86
149
],
87
150
"type": "object"
88
151
},
89
152
"type": "record"
90
153
}
91
154
},
92
155
"description": "A single podcast episode.",
93
156
"id": "place.pod.episode",
94
157
"lexicon": 1
95
158
}