org.atpodcasting.episode

atpodcasting.org

Schema Diff

+39 -20

From

CID
bafyreicvq22lbkb...
Indexed At
2026-02-13 13:58 UTC
View this version

To

CID
bafyreib5bfxznap...
Indexed At
2026-02-13 15:07 UTC
View this version
1 1
{
2 2
  "id": "org.atpodcasting.episode",
3 3
  "defs": {
4 4
    "main": {
5 5
      "key": "any",
6 6
      "type": "record",
7 7
      "record": {
8 8
        "type": "object",
9 9
        "required": [
10 10
          "podcast",
11 11
          "title",
12 12
          "media",
13 13
          "publishedAt",
14 14
          "duration",
15 15
          "feedItemGuid",
16 -
          "updatedAt"
16 +
          "createdAt"
17 17
        ],
18 18
        "properties": {
19 +
          "link": {
20 +
            "type": "string",
21 +
            "format": "uri",
22 +
            "description": "URL of a companion webpage or show notes page for the episode."
23 +
          },
19 24
          "media": {
20 -
            "ref": "#externalMedia",
25 +
            "ref": "#mediaRef",
21 26
            "type": "ref",
22 27
            "description": "The primary media file for the episode."
23 28
          },
24 29
          "title": {
25 30
            "type": "string",
26 31
            "maxLength": 500,
27 32
            "description": "The title of the episode."
28 33
          },
29 34
          "artwork": {
30 35
            "type": "blob",
31 36
            "accept": [
32 37
              "image/png",
33 38
              "image/jpeg"
34 39
            ],
35 40
            "maxSize": 5000000,
36 41
            "description": "Episode-specific artwork. Overrides the podcast artwork when set. Recommended: 1400x1400 to 3000x3000 pixels, square, no alpha channel."
37 42
          },
38 43
          "podcast": {
39 -
            "ref": "#podcastRef",
44 +
            "ref": "org.atpodcasting.defs#podcastRef",
45 +
            "type": "ref",
46 +
            "description": "Identifies the parent podcast. Since episodes live in the same repository as their podcast, the AT URI is always derivable from the episode's DID and the podcastGuid."
47 +
          },
48 +
          "chapters": {
49 +
            "ref": "#chaptersRef",
40 50
            "type": "ref",
41 -
            "description": "Reference to the parent podcast."
51 +
            "description": "Reference to an externally hosted chapters file."
42 52
          },
43 53
          "duration": {
44 54
            "type": "integer",
45 -
            "minimum": 0,
55 +
            "minimum": 1,
46 56
            "description": "Duration of the episode in seconds."
47 57
          },
48 -
          "updatedAt": {
58 +
          "explicit": {
59 +
            "type": "boolean",
60 +
            "description": "Whether the episode contains explicit content. Overrides the podcast-level setting when set."
61 +
          },
62 +
          "createdAt": {
49 63
            "type": "string",
50 64
            "format": "datetime",
51 -
            "description": "When the episode record was last updated."
65 +
            "description": "When the episode record was created."
52 66
          },
53 67
          "transcript": {
54 68
            "type": "array",
55 69
            "items": {
56 70
              "ref": "#transcriptRef",
57 71
              "type": "ref"
58 72
            },
59 73
            "maxLength": 10,
60 74
            "description": "References to externally hosted transcript files (e.g. VTT, SRT, JSON). Multiple entries allow providing transcripts in different formats."
61 75
          },
62 76
          "description": {
63 77
            "type": "string",
64 78
            "maxLength": 10000,
65 79
            "description": "A description or show notes for the episode."
66 80
          },
67 81
          "episodeType": {
68 82
            "type": "string",
69 83
            "description": "The type of episode. Defaults to full.",
70 84
            "knownValues": [
71 85
              "full",
72 86
              "trailer",
73 87
              "bonus"
74 88
            ]
75 89
          },
76 90
          "publishedAt": {
77 91
            "type": "string",
78 92
            "format": "datetime",
79 93
            "description": "When the episode was published."
80 94
          },
81 95
          "feedItemGuid": {
82 96
            "type": "string",
83 97
            "maxLength": 2000,
84 -
            "description": "The original feed item identifier. For syndicated podcasts, this must match the <guid> element of the corresponding RSS feed item. For AT-native implementations, this should be a generated TID. The record key (rkey) is derived from this value as uuid5(<podcast:guid>, feedItemGuid)."
98 +
            "description": "The original feed item identifier. Must match the <guid> element of the corresponding RSS feed item. The record key (rkey) is derived from this value as uuid5(<podcast:guid>, feedItemGuid)."
85 99
          },
86 100
          "seasonNumber": {
87 101
            "type": "integer",
88 102
            "minimum": 1,
89 103
            "description": "Season number of the episode."
90 104
          },
91 105
          "episodeNumber": {
92 106
            "type": "integer",
93 107
            "minimum": 1,
94 108
            "description": "Episode number within its season or the overall series."
95 109
          },
96 110
          "alternateMedia": {
97 111
            "type": "array",
98 112
            "items": {
99 -
              "ref": "#externalMedia",
113 +
              "ref": "#mediaRef",
100 114
              "type": "ref"
101 115
            },
102 116
            "maxLength": 10,
103 117
            "description": "Alternate versions of the episode media (e.g. different formats or audio-only versions of video episodes)."
104 118
          }
105 119
        }
106 120
      },
107 121
      "description": "A podcast episode. Record key is a UUIDv5 derived from the podcast GUID (as namespace) and the episode's feedItemGuid (as name), enabling deterministic lookup from RSS feed metadata."
108 122
    },
109 -
    "podcastRef": {
123 +
    "mediaRef": {
110 124
      "type": "object",
111 125
      "required": [
112 -
        "uri"
126 +
        "url",
127 +
        "mimeType"
113 128
      ],
114 129
      "properties": {
115 -
        "uri": {
130 +
        "url": {
116 131
          "type": "string",
117 -
          "format": "at-uri",
118 -
          "description": "AT URI of the podcast record."
132 +
          "format": "uri",
133 +
          "description": "URL of the media file."
134 +
        },
135 +
        "mimeType": {
136 +
          "type": "string",
137 +
          "description": "MIME type of the media file (e.g. audio/mpeg, video/mp4)."
119 138
        }
120 139
      },
121 -
      "description": "Weak reference to a podcast (no CID, allows mutation)."
140 +
      "description": "Reference to an externally hosted media file."
122 141
    },
123 -
    "externalMedia": {
142 +
    "chaptersRef": {
124 143
      "type": "object",
125 144
      "required": [
126 145
        "url",
127 146
        "mimeType"
128 147
      ],
129 148
      "properties": {
130 149
        "url": {
131 150
          "type": "string",
132 151
          "format": "uri",
133 -
          "description": "URL of the media file."
152 +
          "description": "URL of the chapters file."
134 153
        },
135 154
        "mimeType": {
136 155
          "type": "string",
137 -
          "description": "MIME type of the media file (e.g. audio/mpeg, video/mp4)."
156 +
          "description": "MIME type of the chapters file (e.g. application/json+chapters)."
138 157
        }
139 158
      },
140 -
      "description": "Reference to an externally hosted media file."
159 +
      "description": "Reference to an externally hosted chapters file."
141 160
    },
142 161
    "transcriptRef": {
143 162
      "type": "object",
144 163
      "required": [
145 164
        "url",
146 165
        "mimeType"
147 166
      ],
148 167
      "properties": {
149 168
        "url": {
150 169
          "type": "string",
151 170
          "format": "uri",
152 171
          "description": "URL of the transcript file."
153 172
        },
154 173
        "language": {
155 174
          "type": "string",
156 175
          "format": "language",
157 176
          "description": "Language of the transcript (ISO 639-1 two-letter code, e.g. 'en', 'es', 'pt')."
158 177
        },
159 178
        "mimeType": {
160 179
          "type": "string",
161 -
          "description": "MIME type of the transcript file (e.g. text/vtt, application/srt, application/json)."
180 +
          "description": "MIME type of the transcript file (e.g. text/vtt, application/x-subrip, application/json)."
162 181
        }
163 182
      },
164 183
      "description": "Reference to an externally hosted transcript file."
165 184
    }
166 185
  },
167 186
  "$type": "com.atproto.lexicon.schema",
168 187
  "lexicon": 1
169 188
}

Compare Other Versions

Lexicon Garden

@