Open Stories is a syndication format for distributing stories to friends and families.
Stories are small pieces of media – such as images and video clips – with a 9:16 aspect ratio.
An OpenStories feed is essentially a JSON Feed Version 1.1 with extensions.
You can validate a OpenStoriesFeed
with its TypeScript definitions in openstories-types
.
<open-stories>
: A custom element that will display a singleOpenStoriesFeed
's content.
A minimal OpenStoriesFeed
may look like the following; note, specifically the required _open_stories
object for each item
.
{
"version": "https://jsonfeed.org/version/1.1",
"title": "Valid feed",
"_open_stories": {
"version": "0.0.9"
},
"items": [
{
"id": "a1",
"content_text": "Text",
"authors": [{"name": "muan", "url": "https://muan.co"}],
"_open_stories": {
"mime_type": "image/jpg",
"url": "https://example.com/a1.jpg",
"alt": "Sky"
}
},
{
"id": "a2",
"content_text": "Text 2",
"authors": [{"name": "muan", "url": "https://muan.co"}],
"_open_stories": {
"mime_type": "image/jpg",
"url": "https://example.com/a2.jpg",
"alt": "Sky"
}
}
]
}
The top level object of the feed matches that of a JSON Feed with the following additions:
_open_stories
(required, Open Stories Metadata): The Open Stories Metadata of this feed.items
: (required, an array of Open Stories Items): The items of the feed.feed_url
: (required, string): Unlike in JSON Feed,feed_url
is a required field in Open Stories feeds.
Metadata that identifies an Open Stories feed
preview
(optional, Preview): Data that helps clients display a preview of the feed while loading its items.version
: (required, String): The version of the Open Stories used for this feed. Currently, only0.0.9
is supported.
Items represent stories in the feed. Items in an Open Stories feed match Items of a JSON Feed with the following additions:
_open_stories
(required, either Image Story or Video Story): The story this item represents.authors
: (optional, an array of Open Stories Authors): The authors that created this item.
Addtionally, authoring software of Open Stories is encouraged to populate the content_html
field of the Item with an approximation of the stories contents, e.g. an <img>
point at the same url
as the Item's _open_stories.url
, with an alt
attribute matching _open_stories.alt
.
<img src='{{ item._open_stories.url }}' alt='{{ item._open_stories.alt }}'>
{{ item._open_stories.caption }}
or
<video src='{{ item._open_stories.url }}' aria-describedby='description'>
<track src='{{ item._open_stories.tracks[0].url }}' kind='{{ item._open_stories.tracks[0].kind }}'></track>
</video>
<div id='description'>{{ item._open_stories.title }}</div>
Common fields between Image Stories and Video Stories:
url
: (required, String): The URL of the image. Expected to be in a 9:16 aspect ratio.date_expired
(optional, String): The date at which the story did or will expire. Clients are encouraged not to display stories after this date.preview
(optional, Preview): Data that helps the client display a preview while this image is loading.reactions
(optional, Reactions): Data that describes how clients can react to this image.content_warning
(optional, String): If present, clients should display this warning before showing the story to the user.duration_in_seconds
(optional, Number): How long the story should be displayed for. Clients are free to adjust this number.alt
(required, String): The alt text of the image.caption
(optional, String): The caption of the image.
Fields unique to Image Story:
mime_type
(required, String beginning withimage/${string}
): the MIME type of the image.
Common fields between Image Stories and Video Stories:
url
: (required, String): The URL of the video. Expected to be in a 9:16 aspect ratio.date_expired
(optional, String): The date at which the story did or will expire. Clients are encouraged not to display stories after this date.preview
(optional, Preview): Data that helps the client display a preview while this video is loading.reactions
(optional, Reactions): Data that describes how clients can react to this video.content_warning
(optional, String): If present, clients should display this warning before showing the story to the user.duration_in_seconds
(optional, Number): How long the story should be displayed for. Clients are free to adjust this number.title
(required, String): A description of the video.
Fields unique to Video Story:
mime_type
(required, String beginning withvideo/
): the MIME type of the video.tracks
(optional, an array of Tracks): The subtitle, caption, or chapters track of a video. Modeled after theHTMLTrackElement
.
url
(required, String): The URL of a WEBVTT file.lang
(optional, String): A BCP47 language subtag for the track.kind
(optional, String): 'captions' (default), 'subtitles', 'chapters'.label
(optional, String): A user readable label for the track.
Authors represent people that created the stories in the feed. Authors in an Open Stories feed match Authors of a JSON Feed with the following additions:
name
(required, String): Unlike in JSON Feed,name
is a required field in Open Stories feeds.url
(required, String): Unlike in JSON Feed,url
is a required field in Open Stories.url
is expected to uniquely identify the author across feeds and items.
A Preview is a light-weight representation that allows clients to construct a more pleasant preview image while the actual story is loading.
blurhash
(optional, String): A blurhash representation of this item, at a 9:16 aspect ratio.color
(optional, String): A solid color that can be used as a placeholder to this story.
Reactions allow a client to communicate back to the authors of a story.
open_heart_urls
(optional, String): A Open Heart URL.