place.pod.episode

pod.place

Schema Diff

+70 -7

From

CID
bafyreiheuj63zwh...
Indexed At
2026-06-21 18:48 UTC
View this version

To

CID
bafyreibrghevgz2...
Indexed At
2026-07-26 16:24 UTC
View this version

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

Compare Other Versions

Lexicon Garden

@