SubReader helps dyslexics enjoy foreign language movies by providing spoken subtitles in an individual and discreet manner. By connecting a pair of earplugs to the phone, through which the subtitles will be read aloud, the dyslexic is able to participate in movie nights, cinema trips etc. on the same behalf as non-dyslexics.
This document describes the endpoint necessary for integration with the SubReader app. It uses standard REST
practices and is not dependent on any language specific features in order to be easily implemented in existing backends.
This first revision does not consider synchronization of the reading of subtitles with the video playback.
Optional field names are indicated by the ?
postfix.
If authentication is required in order to access certain content, the user should be able to authenticate by issuing a POST
request to the /authenticate
endpoint with the following JSON body:
{
"username": <Email or Username: String>,
"password": <Password: String>
}
Upon successful authentication the server should respond with a 200
status code and the following JSON body:
{
"accessToken": {
"expiresIn?": <Seconds: Number>,
"value": <JWT: String>
},
"refreshToken?": {
"expiresIn?": <Seconds: Number>,
"value": <JWT: String>
}
}
In case the user cannot be authenticated (Eg. the user has entered the wrong credentials) the server should respond with a status code 404
and the following JSON body:
{
"error": {
"code?": <Error code: Number>,
"message": <Error Message: String>
}
}
After authenticating the client will use the Authorization
header to authorize access with the server:
Authorization: Bearer <JWT Access Token>
If the client requests an endpoint or resource which requires that the user is authenticated without specifying the Authorization
header, the server should respond with a 401
status code.
If the user is succesfully authenticated, but does not have access to the request endpoint or resource, the server should respond with a 403
status code.
In order to refresh the access token, the client has to send a POST
request with the following body:
{
"refreshToken": <JWT Refresh token: String>
}
If the access token is successfully refreshed, the server should respond with:
{
"accessToken": {
"expiresIn?": <Seconds: Number>,
"value": <JWT: String>
}
}
The server should respond with the following JSON body:
{
"results": [
{
"type": "movie" | "series",
"id": <Unique ID>,
"imdb_id?": <Unique ID>,
"title": <Movie or Series title: String>,
"poster": "https://cdn.example.net/poster.png",
},
{
"type": "movie" | "series",
"id": <Unique ID>,
"imdb_id?": <Unique ID>,
"title": <Movie or Series title: String>,
"poster": "https://cdn.example.net/poster.png",
},
...
]
}
If the ID is of a movie or episode, the server should respond with the following JSON body:
{
"type": "movie" | "episode",
"id": <Unique ID>,
"imdb_id?": <Unique ID>,
"title": <Movie or Episode title: String>,
"poster": "https://cdn.example.net/poster.png",
"description?": <Description: String>,
"subtitles": [
{
"language": "da",
"srt": "https://cdn.example.net/da.srt"
},
{
"language": "sv",
"srt": "https://cdn.example.net/sv.srt"
}
]
}
If the ID instead belongs to a series the server should return:
{
"type": "series",
"id": <Unique ID>,
"imdb_id?": <Unique ID>,
"title": <Series title: String>,
"poster": "https://cdn.example.net/poster.png",
"seasons": [
{
"type": "season",
"id": <Unique ID>,
"imdb_id?": <Unique ID>,
"title": <Season title: String>,
"episodes": [
{
"type": "episode",
"id": <Unique ID>,
"imdb_id?": <Unique ID>,
"title": <Episode title: String>,
"description?": <Description of Series: String>,
}
]
}
]
}