-
Notifications
You must be signed in to change notification settings - Fork 0
/
openapi.yaml
1066 lines (1061 loc) · 46.5 KB
/
openapi.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
openapi: "3.1.0"
info:
version: "0.1.2"
title: "microfeed api"
description: |
Allows to use microfeed as a headless cms or integrate with external services like Zapier.
Using the microfeed api, you can programmatically create, update, delete items, and update the channel metadata.
termsOfService: "https://github.com/microfeed/microfeed/blob/main/LICENSE"
contact:
name: "Listen Notes, Inc."
url: "https://www.microfeed.org"
email: "[email protected]"
servers:
- url: https://media-hghdev-xyz.pages.dev
description: API Production Server
tags:
- name: Feed API
description: |
Read-only endpoints to fetch the jsonfeed and individual items.
Anyone can use Feed API endpoints without authentication.
In other words, these endpoints are public.
You can disable Feed API endpoints at https://media-hghdev-xyz.pages.dev/admin/settings/ -
toggle "Visible" of "JSON" in the "Subscribe methods" section.
- name: Admin API
description: |
Endpoints to do CRUD operations on the microfeed instance, e.g.,
create a new item, update an existing item, delete an item, upload media files...
You need to use your microfeed instance's API key to access these endpoints.
You can find your microfeed instance's API key at the API section of https://media-hghdev-xyz.pages.dev/admin/settings/.
paths:
/json:
get:
tags:
- Feed API
summary: Fetches json for a feed
description: |
Fetches json data for a feed, including channel metadata and a list of items.
The response data is in JSON feed format. For the formal JSON feed definition,
please see https://www.jsonfeed.org/version/1.1/
The response data can also be used as variables in the Web Feed mustache template at
/admin/settings/code-editor/?type=themes&theme=custom#webFeed
operationId: fetchFeedJson
parameters:
- name: next_cursor
in: query
description: |
Offset for items, for pagination. You'll use **next_cursor** from response for this parameter.
required: false
schema:
type: integer
example: 1672707197212
- name: sort
in: query
description: |
How do you want to sort these items?
required: false
schema:
type: string
example: newest_first
default: newest_first
enum: [ "newest_first", "oldest_first" ]
responses:
200:
description: Success response.
links:
paginate:
operationId: fetchFeedJson
parameters:
next_cursor: $response.body#/_microfeed/items_next_cursor
sort: $response.body#/_microfeed/items_sort_order
description: Pagination through items.
content:
application/json:
schema:
$ref: "#/components/schemas/FeedJson"
404:
description: |
This microfeed instance's Json feed is disabled by the admin at /admin/settings/
content:
text/plain:
schema:
type: string
description: "Not Found"
/i/{id}/json:
get:
tags:
- Feed API
summary: Fetches json for an item
description: |
Fetches json feed data for an item. The items data field contains only 1 item.
The response data is in JSON feed format. For the formal JSON feed definition,
please see https://www.jsonfeed.org/version/1.1/
operationId: fetchItemJson
parameters:
- $ref: '#/components/parameters/itemIdParam'
responses:
200:
description: Success response.
content:
application/json:
schema:
$ref: "#/components/schemas/FeedJson"
404:
description: |
This item does not exist, or
this microfeed instance's Json feed is disabled by the admin at /admin/settings/
content:
text/plain:
schema:
type: string
description: "Not Found"
/api/channels/primary/:
put:
tags:
- Admin API
summary: Update the channel
description: |
Update the channel's metadata.
operationId: apiUpdatePrimaryChannel
parameters:
- $ref: '#/components/parameters/apiKeyParam'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ChannelRequestBodyJson'
responses:
200:
description: Success response.
401:
$ref: '#/components/responses/Unauthorized'
5XX:
$ref: '#/components/responses/ServerError'
/api/items/:
post:
tags:
- Admin API
summary: Creates a new item.
description: |
Creates a new item.
operationId: apiCreateNewItem
parameters:
- $ref: '#/components/parameters/apiKeyParam'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ItemRequestBodyJson'
responses:
201:
description: Success response.
401:
$ref: '#/components/responses/Unauthorized'
5XX:
$ref: '#/components/responses/ServerError'
/api/items/{id}/:
put:
tags:
- Admin API
summary: Updates an item.
description: |
Updates an item's metadata.
operationId: apiUpdateItemById
parameters:
- $ref: '#/components/parameters/apiKeyParam'
- $ref: '#/components/parameters/itemIdParam'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ItemRequestBodyJson'
responses:
200:
description: Success response.
404:
$ref: '#/components/responses/NotFound'
401:
$ref: '#/components/responses/Unauthorized'
5XX:
$ref: '#/components/responses/ServerError'
delete:
tags:
- Admin API
summary: Deletes an item.
description: |
Deletes an item.
Please note that this endpoint doesn't delete the media files associated with this item (e.g., audio, image...).
operationId: apiDeleteItemById
parameters:
- $ref: '#/components/parameters/apiKeyParam'
- $ref: '#/components/parameters/itemIdParam'
responses:
200:
description: Success response.
404:
$ref: '#/components/responses/NotFound'
401:
$ref: '#/components/responses/Unauthorized'
5XX:
$ref: '#/components/responses/ServerError'
get:
tags:
- Admin API
summary: Fetches json for an item.
description: |
Fetches json feed data for an item.
This endpoint returns the same result as *GET /i/{id}/json*.
The only difference is that *GET /i/{id}/json* doesn't require an API key and
can be disabled via /admin/settings/.
operationId: apiFetchItemById
parameters:
- $ref: '#/components/parameters/apiKeyParam'
- $ref: '#/components/parameters/itemIdParam'
responses:
200:
description: Success response.
content:
application/json:
schema:
$ref: "#/components/schemas/FeedJson"
404:
$ref: '#/components/responses/NotFound'
401:
$ref: '#/components/responses/Unauthorized'
5XX:
$ref: '#/components/responses/ServerError'
/api/feed/:
get:
tags:
- Admin API
summary: Fetches json for a feed.
description: |
Fetches json feed data for a feed.
This endpoint returns the same result as *GET /json*.
The only difference is that *GET /json* doesn't require an API key and
can be disabled via /admin/settings/.
operationId: apiFetchFeed
parameters:
- $ref: '#/components/parameters/apiKeyParam'
responses:
200:
description: Success response.
links:
paginate:
operationId: apiFetchFeed
parameters:
next_cursor: $response.body#/_microfeed/items_next_cursor
sort: $response.body#/_microfeed/items_sort_order
description: Pagination through items.
content:
application/json:
schema:
$ref: "#/components/schemas/FeedJson"
401:
$ref: '#/components/responses/Unauthorized'
5XX:
$ref: '#/components/responses/ServerError'
/api/media_files/presigned_urls/:
post:
tags:
- Admin API
summary: Creates a r2 presigned url
description: |
Creates a presigned url for uploading a media file to R2.
How to upload a file to R2 via microfeed API:
1. Get a presigned url via
```
curl -X POST $microfeed_url/api/media_files/presigned_urls/ \
-H "Content-Type: application/json" \
-H "X-MicrofeedAPI-Key: $MICROFEED_API_KEY" \
-d '{"item_id": "$ITEM_ID", "category": "image", "full_local_file_path": "$FULL_LOCAL_FILE_PATH"}'
```
You'll get a response like *{"presigned_url": $PRESIGNED_URL, "media_url": $MEDIA_URL}*
2. Then upload a local file to R2 via the returned $PRESIGNED_URL
```
curl -X PUT -T $FULL_LOCAL_FILE_PATH $PRESIGNED_URL
```
Once you get a status 200 from the response, you can use the $MEDIA_URL to
update a channel's icon or an item's image / attachment.url.
operationId: apiGetR2PresignedUrl
parameters:
- $ref: '#/components/parameters/apiKeyParam'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PresignedUrlRequestBodyJson'
responses:
201:
description: Success response.
content:
application/json:
schema:
$ref: '#/components/schemas/PresignedUrlResponseJson'
401:
$ref: '#/components/responses/Unauthorized'
5XX:
$ref: '#/components/responses/ServerError'
components:
parameters:
apiKeyParam:
name: X-MicrofeedAPI-Key
in: header
required: true
style: simple
explode: false
schema:
type: string
description: "Get API Key on https://media-hghdev-xyz.pages.dev/admin/settings/"
itemIdParam:
name: id
in: path
description: An item's id.
required: true
style: simple
explode: false
schema:
type: string
example: GOwipulXxh9
schemas:
FeedJson:
type: object
properties:
version:
type: string
description: |
The URL of the json feed version of the format the feed uses.
See https://www.jsonfeed.org/version/1.1/
example: "https://jsonfeed.org/version/1.1"
required: true
title:
type: string
description: |
A channel's name.
If this channel is a podcast, then it would be a podcast name, e.g., The Joe Rogan Experience, The Daily...
If this is a blog, then it's the blog site's name, e.g., TechCrunch, Daring Fireball...
example: Joe Joe and John John Podcast
required: true
description:
type: string
description: |
A channel's description.
If this channel is a podcast, the maximum amount of text allowed for the description is 4000 characters - this is a requirement of Apple Podcasts.
If this is a blog, then you can write as many words as you want for the description.
example: <p>some html description here</p>
home_page_url:
type: string
description: |
A channel's website. By default, it's the url of this website.
But you can set it to fit your use case, e.g., your homepage on your university's website.
example: https://my-website.com
feed_url:
type: string
description: |
The URL of the json feed, and serves as the unique identifier for the feed.
example: https://my-website.com/json
next_url:
type: string
description: |
The URL of a feed that provides the next n items, where n is defined in /admin/settings/.
This allows for pagination.
example: https://my-website.com/json/?next_cursor=1672707197212&sort=newest_first
icon:
type: string
description: |
A channel's image.
If it's a podcast, then the image must be a minimum size of 1400 x 1400 pixels and
a maximum size of 3000 x 3000 pixels, in JPEG or PNG format, 72 dpi,
with appropriate file extensions (.jpg, .png), and in the RGB colorspace -
this is the requirement of Apple Podcasts.
example: https://media-cdn.my-website.com/projectname/production/images/channel-1f7e6bdb428ee91c298dfe1bc399fd23.png
favicon:
type: string
description: |
The url of an image to be used as the favicon of this site,
which can be changed in /admin/settings/.
example: https://cdn-my-website.com/images/favicon.jpg
language:
type: string
description: |
A channel's language.
The primary language for the feed in the format specified in RFC 5646.
The value is usually a 2-letter language tag from ISO 639-1,
optionally followed by a region tag. (Examples: en or en-US.)
example: en-us
default: en-us
items:
type: array
description: |
The first n items in the feed.
The sort order is determined by _microfeed.items_sort_order.
Please follow the next_url field to see next page of items.
items:
$ref: "#/components/schemas/ItemJson"
_microfeed:
$ref: "#/components/schemas/FeedMicrofeedJson"
ItemJson:
type: object
properties:
id:
type: string
description: A unique id of this item.
example: EOvEbn2lb8r
required: true
title:
type: string
description: |
An item's title. It could be a podcast episode's title, a blog post's title,
a custom title of a curated article...
If it's a podcast episode, please don’t specify the episode number or season number in this tag.
Instead, specify those details in the appropriate tags ( , ).
Also, don’t repeat the title of your show within your episode title.
example: A great episode with an awesome interviewee
attachments:
type: array
description: |
An item can have an associated media file, which can be
an audio, a video, a document, an image or an external url.
Although this is an array, there can be up to 1 attachment.
items:
type: object
properties:
url:
type: string
description: |
The url of a media file associated with this item, which can be
an audio, a video, a document, an image or an external url.
example: https://media-cdn.mywebsite.org/projectname/production/media/audio-bd99c7997f0e181e3c4ad411a1160333.mp3
required: true
mime_type:
type: string
description: |
The type of the attachment, such as audio/mpeg.
example: audio/mpeg
required: true
size_in_bytes:
description: |
The file size of this attachment in bytes, if it is not an external url.
type: integer
example: 256789
duration_in_seconds:
type: integer
description: |
The duration of this attachment in seconds, if it is an audio or an video.
example: 259677
url:
type: string
description: |
An item's web link. By default, it's a web page on this microfeed site.
But you can set it to fit your use case in the admin dashboard at /admin/.
example: https://my-website.com/i/my-episode-EOvEbn2lb8r/
content_html:
type: string
description: |
An item's description.
If this is a podcast episode, you'd better limit the description length to be within 4000 characters,
or Apple Podcasts and other podcast apps/websites may truncate the text.
If this is a blog post, then you can write as many words as you want :)
example: <p>This is awesome</p>
content_text:
type: string
description: |
The plain text version of content_html.
example: This is awesome
image:
type: string
description: |
A square-sized image specific to this item.
If it's a podcast episode, the image size should be a minimum size of 1400 x 1400 pixels and a maximum size of 3000 x 3000 pixels,
in JPEG or PNG format, 72 dpi, with appropriate file extensions (.jpg, .png),
and in the RGB colorspace - this is a requirement of Apple Podcasts.
example: https://media-cdn.my-website.com/projectname/production/images/item-1f7e6bdb428ee91c298dfe1bc399fd23.png
banner_image:
type: string
description: |
The url of an image in attachments, only when the associated media file is an image.
example: https://media-cdn.my-website.com/projectname/production/media/image-ef5e5ec8c909ed44a800a03fe5667b50.png
date_published:
type: string
description: |
The date and time when an item was released, in RFC 3339 format.
example: 2023-01-03T00:35:14.994Z
_microfeed:
$ref: "#/components/schemas/ItemMicrofeedJson"
FeedMicrofeedJson:
type: object
description: |
microfeed-specific data fields for a feed.
properties:
microfeed_version:
type: string
description: |
The microfeed version in Semantic Versioning (x.y.z or major.minor.patch).
Backward compatibility is maintained in a major version.
For example, 0.2.2 should be backward compatible with 0.1.1, because both have the same major version 0;
2.1.2 may or may not be backward compatible with 0.2.1, because they have different major versions
(i.e., 2 vs 0).
example: 0.1.2
base_url:
type: string
description: |
The base url of current site. You can use multiple domain names for the same microfeed instance,
and dynamically render pages based on this field.
example: https://www.my-website.com
categories:
type: array
description: |
If this feed is for a podcast, then there should be podcast categories.
All available categories are from Apple Podcasts:
https://podcasters.apple.com/support/1691-apple-podcasts-categories
Although you can specify more than one category, Apple Podcasts only recognizes the first category and subcategory.
There can be up to 2 levels of categories.
items:
type: object
properties:
name:
type: string
description: The name of a level-1 category.
example: Arts
categories:
type: array
items:
type: object
properties:
name:
type: string
description: The name of a level-2 category.
example: Books
subscribe_methods:
type: array
description: |
All available subscription methods of this feed.
For example, you can list all podcast apps that people can use to subscribe to this feed.
items:
type: object
properties:
name:
type: string
description: A human-readable name of this subscription method.
example: RSS
type:
type: string
description: The type of this subscription method.
enum:
- rss
- json
- apple podcasts
- spotify
- google podcasts
- amazon music
- overcast
- pocket casts
- castro
- listen notes
- custom
url:
type: string
description: The url of this subscription method.
example: https://podcasts.apple.com/us/podcast/id1200361736
image:
type: string
description: The url of this subscription method's icon.
example: https://my-website.com/assets/brands/subscribe/rss.png
description_text:
type: string
description: The plain text version of the description field of this feed / channel.
example: This is a great podcast.
"itunes:type":
type: string,
description: |
The type of a podcast on Apple Podcasts.
Learn more: https://help.apple.com/itc/podcasts_connect/#/itcb54353390
enum:
- episodic
- serial
default: episodic
items_sort_order:
type: string,
description: |
The sort order of items.
enum:
- newest_first
- oldest_first
default: newest_first
items_next_cursor:
type: string
description: |
This data field is for pagination through items.
You can pass a next_cursor=[items_next_cursor] query string to feed_url to fetch next page of items.
example: 1672705853661
"itunes:block":
type: boolean
description: |
Apple Podcasts-specific data field.
The podcast show or hide status in Apple Podcasts.
If you want your show removed from the Apple directory, it is true.
default: false
"itunes:complete":
type: boolean
description: |
Apple Podcasts-specific data field.
The podcast update status.
If you will never publish another episode to your show, select 'yes'.
Specifying the itunes:complete tag with a 'yes' value indicates that a podcast is complete and you will not post any more episodes in the future.
Specifying any value other than 'yes' has no effect.
default: false
"itunes:new-feed-url":
description: |
Apple Podcasts-specific data field.
The new podcast RSS Feed URL.
If you change the URL of your podcast feed, you should use this tag in your new feed.
Use the itunes:new-feed-url tag to manually change the URL where your podcast is located.
You should maintain your old feed until you have migrated your existing subscribers. Learn how to update your podcast RSS feed URL.
Note: The itunes:new-feed-url tag reports new feed URLs to Apple Podcasts and isn’t displayed in Apple Podcasts.
type: string
"itunes:email":
type: string
description: |
Apple Podcasts-specific data field.
The podcast owner's contact email. It'll be public in the rss feed.
Many podcast platforms require this email to validate your podcast ownership.
example: [email protected]
"itunes:explicit":
type: boolean
description: |
The podcast parental advisory information.
If you specify true, indicating the presence of explicit content, Apple Podcasts displays an Explicit parental advisory graphic for your podcast.
Podcasts containing explicit material aren’t available in some Apple Podcasts territories.
If you specify false, indicating that your podcast doesn’t contain explicit language or adult content, Apple Podcasts displays a Clean parental advisory graphic for your podcast.
default: false
"itunes:title":
type: string
description: |
The show title specific for Apple Podcasts.
itunes:title is a string containing a clear concise name of your show on Apple Podcasts.
example: An alternative title on Apple Podcasts only
ItemMicrofeedJson:
type: object
description: microfeed-specific data fields for an item.
properties:
status:
type: string
description: The status of this item.
enum:
- published
- unlisted
- unpublished
is_audio:
type: boolean
description: Is the media file associated with this item an audio?
default: false
is_document:
type: boolean
description: Is the media file associated with this item a document?
default: false
is_external_url:
type: boolean
description: Is the media file associated with this item an external url?
default: false
is_video:
type: boolean
description: Is the media file associated with this item a video?
default: false
is_image:
type: boolean
description: Is the media file associated with this item an image?
default: false
web_url:
type: string
description: The url of this item's web page
example: https://my-website.com/i/some-slug-EOvEbn2lb8r/
json_url:
type: string
description: The url of this item's json feed
example: https://my-website.com/i/some-slug-EOvEbn2lb8r/
rss_url:
type: string
description: The url of this item's rss feed
example: https://my-website.com/i/some-slug-EOvEbn2lb8r/
guid:
type: string
description: |
An item's guid. By default, it's the id of this item. But you can set it to fit your use case.
It is very important that each episode have a unique GUID and that it never changes once it's set,
even if an episode’s metadata, like title or enclosure URL, do change.
Failing to comply with these guidelines may result in duplicate episodes being shown to listeners,
inaccurate data in Analytics, and can cause issues with your podcasts’s listing and
chart placement in Apple Podcasts and other podcast apps/websites.
example: EOvEbn2lb8r
date_published_short:
type: string
description: |
This item's published date in human friendly format, using the website visitor's timezone.
example: Mon Jan 02 2023
date_published_ms:
type: integer
description: The item's published date in milliseconds.
example: 1672707197212
"itunes:title":
type: string
description: |
An episode title specific for Apple Podcasts.itunes:title is a string containing a clear concise name of your episode on Apple Podcasts.
Don’t specify the episode number or season number in this tag. Instead, specify those details in the appropriate tags ( itunes:episode, itunes:season). Also, don’t repeat the title of your show within your episode title.
Separating episode and season number from the title makes it possible for Apple to easily index and order content from all shows.
example: An alternative title of this episode on Apple Podcasts
"itunes:block":
type: boolean
description: |
The episode show or hide status on Apple Podcasts.
If you want an episode removed from the Apple directory, set it to true.
Specifying the itunes:block tag with a true value prevents that episode from appearing in Apple Podcasts.
For example, you might want to block a specific episode if you know that its content would otherwise cause the entire podcast to be removed from Apple Podcasts.
Specifying any value other than true has no effect.
"itunes:episodeType":
type: string
description: |
The episode type in Apple Podcasts. Learn more:
https://help.apple.com/itc/podcasts_connect/#/itcb54353390
enum:
- full
- trailer
- bonus
default: full
"itunes:season":
type: integer
description: |
The episode season number in Apple Podcasts.
If an episode is within a season use this tag.
Where season is a non-zero integer (1, 2, 3, etc.) representing your season number.
To allow the season feature for shows containing a single season, if only one season exists in the RSS feed, Apple Podcasts doesn’t display a season number. When you add a second season to the RSS feed, Apple Podcasts displays the season numbers.
"itunes:episode":
type: integer
description: |
An episode number in Apple Podcasts.
"itunes:explicit":
type: boolean
description: |
The episode parental advisory information.
If you specify true, indicating the presence of explicit content, Apple Podcasts displays an Explicit parental advisory graphic for your episode. Episodes containing explicit material aren’t available in some Apple Podcasts territories.
If you specify false, indicating that the episode does not contain explicit language or adult content, Apple Podcasts displays a Clean parental advisory graphic for your episode.
default: false
ChannelRequestBodyJson:
type: object
properties:
title:
type: string
description: |
The channel's title.
If this channel is a podcast, then it would be a podcast name, e.g., The Joe Rogan Experience, The Daily...
If this is a blog, then it's the blog site's name, e.g., TechCrunch, Daring Fireball...
example: The Daily Podcast
homepage_url:
type: string
description: |
A channel's website.
example: https://my-website.com
description:
type: string
description: |
A channel's description in html.
If this channel is a podcast, the maximum amount of text allowed for the description is 4000 characters -
this is a requirement of Apple Podcasts.
If this is a blog, then you can write as many words as you want for the description.
example:
<b>hello</b> This ia a description!
icon:
type: string
description:
A channel's cover image url.
If it's a podcast, then the image must be a minimum size of 1400 x 1400 pixels and
a maximum size of 3000 x 3000 pixels, in JPEG or PNG format, 72 dpi,
with appropriate file extensions (.jpg, .png), and in the RGB colorspace -
this is the requirement of Apple Podcasts.
The image should be uploaded to the R2 bucket used by this microfeed instance.
You can use *POST /api/v1/media_files/presigned_urls/* to upload the image to the R2 bucket.
Then you can use the returned *media_url* as the icon.
example:
https://media-cdn.my-website.com/projectname/production/images/channel-1f7e6bdb428ee91c298dfe1bc399fd23.png
authors:
type: array
description: |
A channel's authors / publishers.
For now, we only support up to 1 author / publisher.
items:
type: object
properties:
name:
type: string
description: |
A channel's author / publisher.
If this channel is a podcast, then it would be the publisher's name,
e.g., Gimlet Media, New York Times, Joe Rogan...
example: John Doe
language:
type: string
description: |
A channel's language.
The primary language for the feed in the format specified in RFC 5646.
The value is usually a 2-letter language tag from ISO 639-1, optionally followed by a region tag.
example: en-us
expired:
type: boolean
description: |
Usually used for a podcast.
If you will never publish a new item in the future, set it to true.
example: false
_microfeed:
type: object
description: |
Data fields that are not in the jsonfeed.org standard.
properties:
itunes:explicit:
type: boolean
description: |
The podcast parental advisory information.
If you specify true, indicating the presence of explicit content, Apple Podcasts displays an Explicit parental advisory graphic for your podcast.
Podcasts containing explicit material aren’t available in some Apple Podcasts territories.
If you specify false, indicating that your podcast doesn’t contain explicit language or adult content, Apple Podcasts displays a Clean parental advisory graphic for your podcast.
example: false
itunes:title:
type: string
description: |
The show title specific for Apple Podcasts.
itunes:title is a string containing a clear concise name of your show on Apple Podcasts.
example: Another title
itunes:block:
type: boolean
description: |
The podcast show or hide status in Apple Podcasts.
If you want your show removed from the Apple directory, set it to true.
example: false
itunes:type:
type: string
description: |
The type of show.
If your show is Serial you must use this tag.
Its values can be one of the following:
1) Episodic (default). Specify episodic when episodes are intended to be consumed without any specific order. Apple Podcasts will present newest episodes first and display the publish date (required) of each episode. If organized into seasons, the newest season will be presented first - otherwise, episodes will be grouped by year published, newest first.
For new subscribers, Apple Podcasts adds the newest, most recent episode in their Library.
2) Serial. Specify serial when episodes are intended to be consumed in sequential order. Apple Podcasts will present the oldest episodes first and display the episode numbers (required) of each episode. If organized into seasons, the newest season will be presented first and itunes:episode numbers must be given for each episode.
enum:
- serial
- episodic
example: episodic
copyright:
type: string
description: |
The show copyright details.
If your show is copyrighted you should use this tag.
example: Copyright 1995-2019 John John Appleseed
itunes:email:
type: string
description: |
The podcast owner's contact email.
It'll be public in the rss feed. Many podcast platforms require this email to validate your podcast ownership.
example: [email protected]
ItemRequestBodyJson:
type: object
properties:
title:
type: string
description: |
An item's title. It could be a podcast episode's title, a blog post's title, a custom title of a curated article...
If it's a podcast episode, please don’t specify the episode number or season number in this tag. Instead, specify those details in the appropriate tags ( , ).
Also, don’t repeat the title of your show within your episode title.
example: Episode 1 - Introduction
status:
type: string
description: |
An item's status is either published, unlisted, or unpublished.
1. published: listed on the web/rss/json feed, and visible via the direct web link.
2. unpublished: not listed on the web/rss/json feed, and not visible via the direct web link. An admin can still find it and edit on the See all items page.
3. unlisted: not listed on the web/rss/json feed, but visible via the direct web link.
enum:
- published
- unpublished
- unlisted
attachment:
type: object
description: |
An item can have a main media file.
For example, if it's a podcast episode, then a media file should be an audio;
if it's a self-hosted photo album, then a media file should be a high-definition image;
if it's a content curation site, then a media file could be an external url (e.g., an article url from New York Times).
The media file / attachment should be uploaded to the R2 bucket used by this microfeed instance.
You can use *POST /api/v1/media_files/presigned_urls/* to upload to the R2 bucket.
Then you can use the returned *media_url* for *url".
properties:
category:
type: string
description: |
The category of the attachment.
enum:
- audio
- video
- image
- document
- external_url
example: audio
url:
type: string
description: |
The url of the attachment.
If it's an audio, video, image, or document, then it should be the url of the media file uploaded to
the R2 bucket associated with this microfeed instance.
You can use *POST /api/v1/media_files/presigned_urls/* to upload to the R2 bucket.
Then you can use the returned *media_url* for *url*.
If it's an external_url, then it should be the url of the external resource.
example: https://media-cdn.my-website.com/projectname/production/media/audio-ef5e5ec8c909ed44a800a03fe5667b50.mp3
mime_type:
type: string
description: |
The mime type of the attachment.
example: image/png
size_in_bytes:
type: integer
description: |
The attachment's size in bytes.
example: 4096
duration_in_seconds:
description: |
If it's an audio or video, then it should be the duration of the media file in seconds.
type: integer
example: 602
url:
type: string
description: |
An item's web link. By default, it's a web page on your microfeed. But you can set it to fit your use case.
example: https://example.com/episode1
content_html:
type: string
description: |
An item's description in html.
If this is a podcast episode, you'd better limit the description length to be within 4000 characters, or Apple Podcasts and other podcast apps/websites may truncate the text.
If this is a blog post, then you can write as many words as you want :)
example: <b>some text</b>
image:
type: string
description: |
A square-sized image specific to this item.
If it's a podcast episode, the image size should be a minimum size of 1400 x 1400 pixels and a maximum size of 3000 x 3000 pixels, in JPEG or PNG format, 72 dpi, with appropriate file extensions (.jpg, .png), and in the RGB colorspace - this is a requirement of Apple Podcasts.
The image should be uploaded to the R2 bucket used by this microfeed instance.
You can use *POST /api/v1/media_files/presigned_urls/* to upload the image to the R2 bucket.
Then you can use the returned *media_url* as the image.
example: https://media-cdn.my-website.com/projectname/production/images/item-1f7e6bdb428ee91c298dfe1bc399fd23.png
date_published_ms:
type: integer
description: |
The Unix epoch when an item was released, in milliseconds.
example: 1669782691867
_microfeed:
type: object
description: |
Data fields that are not in the jsonfeed.org standard.
properties:
itunes:title:
description: |
An episode title specific for Apple Podcasts.
itunes:title is a string containing a clear concise name of your episode on Apple Podcasts.
Don’t specify the episode number or season number in this tag. Instead, specify those details in the appropriate tags (itunes:episode, itunes:season).
Also, don’t repeat the title of your show within your episode title.
Separating episode and season number from the title makes it possible for Apple to easily index and order content from all shows.
type: string
example: Another episode title
itunes:block:
type: boolean
description: |
The episode show or hide status on Apple Podcasts.
If you want an episode removed from the Apple directory, specifcy true.
example: false
itunes:episodeType:
type: string
enum:
- full
- trailer
- bonus
description: |
The episode type in Apple Podcasts.
If an episode is a trailer or bonus content, use this tag.
Where the episodeType value can be one of the following:
1. full (default). Specify full when you are submitting the complete content of your show.
2. trailer. Specify trailer when you are submitting a short, promotional piece of content that represents a preview of your current show.
3. bonus. Specify bonus when you are submitting extra content for your show (for example, behind the scenes information or interviews with the cast) or cross-promotional content for another show.
example: full
itunes:season:
type: integer
description: |
The episode season number in Apple Podcasts.
If an episode is within a season use this tag.
Where season is a non-zero integer (1, 2, 3, etc.) representing your season number.
To allow the season feature for shows containing a single season, if only one season exists in the RSS feed, Apple Podcasts doesn’t display a season number. When you add a second season to the RSS feed, Apple Podcasts displays the season numbers.
example: 1