{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "JSON Feed",
    "description": "JSON Feed Version 1",
    "type": "object",
    "properties": {
        "version": {
            "description": "The URL of the version of the format the feed uses. This should appear at the very top.",
            "type": "string",
            "format": "uri",
            "const": "https://jsonfeed.org/version/1"
        },
        "title": {
            "description": "The name of the feed, which will often correspond to the name of the website (blog, for instance), though not necessarily.",
            "type": "string"
        },
        "home_page_url": {
            "description": "The URL of the resource that the feed describes. This resource may or may not actually be a \u201chome\u201d page, but it should be an HTML page. If a feed is published on the public web, this should be considered as required.",
            "type": "string",
            "format": "uri"
        },
        "feed_url": {
            "description": "The URL of the feed, serves as the unique identifier for the feed. This should be considered required for feeds on the public web.",
            "type": "string",
            "format": "uri"
        },
        "description": {
            "description": "Provides more detail, beyond the title, on what the feed is about. A feed reader may display this text.",
            "type": "string"
        },
        "user_comment": {
            "description": "A description of the purpose of the feed. This is for the use of people looking at the raw JSON, and should be ignored by feed readers.",
            "type": "string"
        },
        "next_url": {
            "description": "The URL of a feed that provides the next n items, where n is determined by the publisher. This allows for pagination, but with the expectation that reader software is not required to use it and probably won\u2019t use it very often.",
            "type": "string",
            "format": "uri"
        },
        "icon": {
            "description": "The URL of an image for the feed suitable to be used in a timeline, much the way an avatar might be used. It should be square and relatively large \u2014 such as 512 x 512 \u2014 so that it can be scaled-down and so that it can look good on retina displays. It should use transparency where appropriate, since it may be rendered on a non-white background.",
            "type": "string",
            "format": "uri"
        },
        "favicon": {
            "description": "The URL of an image for the feed suitable to be used in a source list. It should be square and relatively small, but not smaller than 64 x 64 (so that it can look good on retina displays). This image should use transparency where appropriate, since it may be rendered on a non-white background.",
            "type": "string",
            "format": "uri"
        },
        "author": {
            "description": "The feed author.",
            "allOf": [
                {
                    "$ref": "#/definitions/author"
                }
            ]
        },
        "expired": {
            "description": "Whether or not the feed is finished \u2014 that is, whether or not it will ever update again. A feed for a temporary event, such as an instance of the Olympics, could expire. If the value is true, then it\u2019s expired. Any other value, or the absence of expired, means the feed may continue to update.",
            "type": "boolean"
        },
        "hubs": {
            "description": "Describes endpoints that can be used to subscribe to real-time notifications from the publisher of this feed.",
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "type": {
                        "description": "Describes the protocol used to talk with the hub, such as \u201crssCloud\u201d or \u201cWebSub.\u201d",
                        "type": "string"
                    },
                    "url": {
                        "type": "string",
                        "format": "uri"
                    }
                },
                "patternProperties": {
                    "^_[a-zA-Z][^.]*$": {
                        "$ref": "#/definitions/extension"
                    }
                },
                "additionalProperties": false,
                "required": [
                    "type",
                    "url"
                ]
            }
        },
        "items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "id": {
                        "description": "Unique for that item for that feed over time. If an item is ever updated, the id should be unchanged. New items should never use a previously-used id. Ideally, the id is the full URL of the resource described by the item, since URLs make great unique identifiers.",
                        "type": "string"
                    },
                    "url": {
                        "description": "The URL of the resource described by the item. It\u2019s the permalink. This may be the same as the id.",
                        "type": "string",
                        "format": "uri"
                    },
                    "external_url": {
                        "description": "The URL of a page elsewhere. This is especially useful for linkblogs. If url links to where you\u2019re talking about a thing, then external_url links to the thing you\u2019re talking about.",
                        "type": "string",
                        "format": "uri"
                    },
                    "title": {
                        "description": "Plain text. Microblog items in particular may omit titles.",
                        "type": "string"
                    },
                    "content_html": {
                        "description": "The HTML of the item.",
                        "type": "string"
                    },
                    "content_text": {
                        "description": "The plain text of the item.",
                        "type": "string"
                    },
                    "summary": {
                        "description": "A plain text sentence or two describing the item. This might be presented in a timeline, for instance, where a detail view would display all of content_html or content_text.",
                        "type": "string"
                    },
                    "image": {
                        "description": "The URL of the main image for the item. This image may also appear in the content_html \u2014 if so, it\u2019s a hint to the feed reader that this is the main, featured image. Feed readers may use the image as a preview (probably resized as a thumbnail and placed in a timeline).",
                        "type": "string",
                        "format": "uri"
                    },
                    "banner_image": {
                        "description": "The URL of an image to use as a banner. Some blogging systems (such as Medium) display a different banner image chosen to go with each post, but that image wouldn\u2019t otherwise appear in the content_html. A feed reader with a detail view may choose to show this banner image at the top of the detail view, possibly with the title overlaid.",
                        "type": "string",
                        "format": "uri"
                    },
                    "date_published": {
                        "description": "The date in RFC 3339 format.",
                        "type": "string",
                        "format": "date-time"
                    },
                    "date_modified": {
                        "description": "The modification date in RFC 3339 format.",
                        "type": "string",
                        "format": "date-time"
                    },
                    "author": {
                        "description": "The author of the item.",
                        "allOf": [
                            {
                                "$ref": "#/definitions/author"
                            }
                        ]
                    },
                    "tags": {
                        "description": "Can have any plain text values you want. Tags tend to be just one word, but they may be anything. Note: they are not the equivalent of Twitter hashtags. Some blogging systems and other feed formats call these categories.",
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "attachments": {
                        "description": "Lists related resources. Podcasts, for instance, would include an attachment that\u2019s an audio or video file.",
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "url": {
                                    "description": "The location of the attachment.",
                                    "type": "string",
                                    "format": "uri"
                                },
                                "mime_type": {
                                    "description": "The type of the attachment, such as \u201caudio/mpeg.\u201d",
                                    "type": "string"
                                },
                                "title": {
                                    "description": "A name for the attachment. Important: if there are multiple attachments, and two or more have the exact same title (when title is present), then they are considered as alternate representations of the same thing. In this way a podcaster, for instance, might provide an audio recording in different formats.",
                                    "type": "string"
                                },
                                "size_in_bytes": {
                                    "description": "How large the file is.",
                                    "type": "number"
                                },
                                "duration_in_seconds": {
                                    "description": "How long it takes to listen to or watch, when played at normal speed.",
                                    "type": "number"
                                }
                            },
                            "patternProperties": {
                                "^_[a-zA-Z][^.]*$": {
                                    "$ref": "#/definitions/extension"
                                }
                            },
                            "additionalProperties": false,
                            "required": [
                                "url",
                                "mime_type"
                            ]
                        }
                    }
                },
                "patternProperties": {
                    "^_[a-zA-Z][^.]*$": {
                        "$ref": "#/definitions/extension"
                    }
                },
                "additionalProperties": false,
                "anyOf": [
                    {
                        "required": [
                            "content_html"
                        ]
                    },
                    {
                        "required": [
                            "content_text"
                        ]
                    }
                ],
                "required": [
                    "id"
                ]
            }
        }
    },
    "patternProperties": {
        "^_[a-zA-Z][^.]*$": {
            "$ref": "#/definitions/extension"
        }
    },
    "additionalProperties": false,
    "required": [
        "version",
        "title",
        "items"
    ],
    "definitions": {
        "author": {
            "title": "Author",
            "type": "object",
            "properties": {
                "name": {
                    "description": "The author\u2019s name.",
                    "type": "string"
                },
                "url": {
                    "description": "The URL of a site owned by the author. It could be a blog, micro-blog, Twitter account, and so on. Ideally the linked-to page provides a way to contact the author, but that\u2019s not required. The URL could be a mailto: link.",
                    "type": "string",
                    "format": "uri"
                },
                "avatar": {
                    "description": "The URL for an image for the author. It should be square and relatively large \u2014 such as 512 x 512 \u2014 and should use transparency where appropriate, since it may be rendered on a non-white background.",
                    "type": "string",
                    "format": "uri"
                }
            },
            "minProperties": 1,
            "patternProperties": {
                "^_[a-zA-Z][^.]*$": {
                    "$ref": "#/definitions/extension"
                }
            },
            "additionalProperties": false
        },
        "extension": {
            "title": "Extension",
            "type": "object",
            "patternProperties": {
                "^[^.]*$": {}
            },
            "additionalProperties": false
        }
    }
}