Introduction
PLAY'A API was made to unify and simplify the delivery of video content. This document describes the workflow of the API and is divided into three main chapters:
General Information
Responses
Requests
General information
Authorization
API authorization is based on JSON Web Tokens (you can find more information about JWT you can find here: https://jwt.io/introduction/).
There are two common ways to receive authorization tokens. The first one assumes that you have valid credentials to access all the content with user tokens. The second way grants you access to free content with guest tokens.
Most of the endpoints have a mandatory Header:
"Authorization: Bearer <access_token>"
where <access_token> is an access token received from the endpoint of the authentication. It can be either a user access token or a guest access token. If the provided token expires or is invalid, API will respond with the following message:
{
"status": {
"code": 401,
"message": "Unauthorized"
}
}
Headers
Each request to PLAY'A API typically contains the following headers:
Content-Type: application/json
Accept: application/json
Authorization: Bearer <access_token>
HTTP status code
For all requests, API responds with the following http status codes:
​
200 Ok - successfully processed;
>=500 - server error;
404 - incorrect address or request format;
Responses
PLAYA service generates a json object as a response on each request. It has a specific format described in this chapter. Correct response can be parsed only from response with the HTTP status code 200 Ok.
The simplest json object (also called a skeleton) is being generated for every request. It looks like this:
{
status: {
code: <status code>,
message: <detailed message>
}
}
The skeleton contains a status object with properties "code" and "message". Every request has a status code and message which describes this code. Table 1 explains the individual status codes.
Table 1: Status codes
Code Status
​
1 Authorization failed
2 Ok
3 General error (see details in status message)
4 User is expired
5 User is inactive
6 User is blocked
7 Successful registry
8 Registration: email exists
10 Registration: email not sent
11 Registration: invalid email
401 Unauthorized
404 Not found
Besides the status object, the response may contain other objects described in this chapter.
{
status: {
code: 2,
message: “Ok”
},
data: {
<...>,
<...>
}
}
where <...> is any object generated by endpoint. Additional objects may be added to the response depending on the result of the processing of the request and the request type. Detailed definition of endpoint’s responses can be found in the chapter “Requests”.
Response objects
Status object
status: {
code: <code> ,
message: <string>
}
Announcement object
announcement: {
newslink: <string>
}
Announcements array
announcements: [
<announcement>,
<announcement>,
...
]
Configuration object
configuration: {
"site_logo": <string>,
"site_name": <string>,
"lobby_logo": <string>,
"theme": <int>,
"categories": <bool>,
"announcements": <bool>,
"free_videos": <bool>,
"registry": <bool>
}
where:
-
site_logo: a logo of the website (PNG with alpha channel - 256 px width, 256 px height)
-
site_name: a name of the website
-
lobby_logo: a logo of the lobby (PNG with alpha channel - 546 px width, 100 px height)
-
theme: a identifier of the theme (0 - red (default), 1 - blue, 2 - orange)
-
categories: enables/disables categories' UI
-
announcements: enables/disables announcements' UI
-
free_videos: enables/disables free videos' UI
-
registry: enables/disables the registry's UI
Category object
category: {
id: <int>,
name: <string>,
image: <string>
}
where:
-
id: an identifier of the category
-
name: a name of the category
-
image: a link to the categories announce image
Favorites array
favorites: [
<id>,
<id>,
...
]
where <id> - is an identifier of the video
Video object
video: {
id: <int>,
date_gmt: <string>,
title: <string>,
status: <string>,
content: <string>,
video_category: [
<category_id>,
...
],
video-poster: <string>,
video-preview-sprite: <string>,
trailer-preview-sprite: <string>,
video-links: {
<type: string>: <link: string>,
...
},
trailer-links: {
<type: string>: <link: string>,
...
},
video-positions: [
<string>,
...
],
video-rating: <int>,
video-featured: <int>,
video-duration: <string>,
video-fps: <string>,
video-starring: [
<string>,
...
],
timecodes_for_trailer: [
<int>",
...
],
timeline_for_trailer: [
<timeline>,
...
],
timecodes_for_video: [
<int>,
...
],
timeline_for_video: [
<timeline>,
...
],
automatic_camera_tilt: [
<camera_tilt>,
...
],
automatic_camera_tilt_trailer: [
<camera_tilt>,
...
],
is_partners: <int>
}
where:
-
id: an identifier of the video
-
date_gmt: a publishing date of the video, e.g. "2016-01-11T16:03:45"
-
title: a title of the video
-
status: a status of the video (publish, draft - available only for administrators and moderators)
-
content: a description of the video
-
video_category: an array of the video’s categories
-
video-poster: a link to the video’s poster
-
video-preview-sprite: a link to the video’s preview sprite
-
trailer-preview-sprite: a link to the trailer’s preview sprite
-
video-links: an array of the video’s links
-
trailer-links: an array of the trailer’s links
-
video-positions: an array with video’s positions ("Standing", "Sitting", "Lying", "Swivel")
-
video-rating: a rating of the video
-
video-featured: a feature rate of the video
-
video-duration: duration of the video (format HH:MM:SS)
-
video-fps: FPS value of the video
-
video-starring: an array with the videos starring
-
timecodes_for_trailer: an array of the trailer’s timecodes (in milliseconds)
-
timecodes_for_video: an array of the video’s timecodes (in milliseconds)
-
(LEGACY) automatic_camera_tilt: an array of the video’s camera tilt objects:
camera_tilt: {
camera_tilt: <float>,
time_code: <int>
}
-
(LEGACY) automatic_camera_tilt_trailer: an array of the trailer’s camera tilt objects
-
(NEW) timeline_for_trailer - an array of timeline objects for trailers:
timeline: {
time: <int>,
zoom: <float>,
height: <float>,
tilt: <float>,
title: <string>
}
Videos array
where <video> is a video object with empty field video-links.
Timestamps object
timestamps: {
ts_announcements: <int>,
ts_categories: <int>,
ts_videos: <int>
}
where:
-
ts_announcements: timestamp of announcements' latest update
-
ts_categories: timestamp of categories' latest update
-
ts_videos: timestamp of videos' latest update
Token object
{
access: <string>,
refresh: <string>
}
User object
{
is_guest: <boolean>,
username: <string>,
role: <int>,
avatar: <int>
}
where:
-
is_guest: a guest's token indicator - if true, there will be no other fields
-
role: a role of the user (0 - user, 1 -moderator, 2 - administrator)
-
avatar: ID of the user’s avatar (0 to 15)
Requests
Attention! All requests in this chapter have a prefix /api/playa/v1/
User registry
If a provided email address is not registered in the service, a registration email will be sent to the given email address. That email will contain a link to a "Join Now" page where user will be able to register.
An email option is mandatory.
An allow_marketing option will add email to the service's subscription list.
Response may contain the following status codes: 7, 8, 10, 11.
POST: auth/registry
{
email: <email>,
allow_marketing: <int>,
}
Response: {Status}
Request:
curl -X POST '<service_url>/api/playa/v1/auth/registry' -H 'Accept: application/json' -H 'Content-Type: application/json' --data-raw '{"email":"test@user.email","allow_marketing":1}'
Response:
{
"status": {
"code":7,
"message":"Ok"
}
}
User authentication
Returns a fresh pair of user tokens (access user token and refresh user token) if provided credentials are valid. The token pair may then be used to request the rest of the endpoints and to refresh the token pair when access token expires.
POST: auth/user
Request:
{
email: <email>,
password: <password>
}
Request:
curl -X POST '<service_url>/api/playa/v1/auth/user' -H 'Accept: application/json' -H 'Content-Type: application/json'
--data-raw '{"email":"user@mail.test","password":"userpassword"}'
Response:
{
"status": {
"code":2,
"message":"Ok"
},
"data": {
"token": {
"access_token": "<a-user-access-token>",
"refresh_token":"<a-user-refresh-token>"
}
}
}
Request:
curl -X POST '<service_url>/api/playa/v1/auth/user' -H 'Accept: application/json' -H 'Content-Type: application/json'
--data-raw '{"email":"incorrect-user@mail.test","password":"orincorrectpassword"}'
Response:
{
"status": {
"code":1,
"message":"Incorrect email or password."
}
}
Guest authentication
Guest token pairs can be used in the same way as user token pairs - but responses will contain only public information. All private and personal information is inaccessible when using a guest token pair.
POST: auth/guest
Request:
curl -X POST '<service_url>/api/playa/v1/auth/guest' -H 'Accept: application/json'
Response:
{
"status": {
"code": 2,
"message": "Ok"
},
"data": {
"token": {
"access_token": "<a-guest-access-token>",
"refresh_token": "<a-guest-refresh-token>"
}
}
}
Token refreshing
When the service receives an expired access token, it sends the response with status code 401 (Unauthorized) for all requests where the access token is mandatory. In this case, a token pair must be refreshed by sending the request with a refresh token. The service will respond with a new pair of access and refresh tokens if the provided refresh token is valid and not expired. Otherwise, the service will also respond with the status code 401 and the status message will contain the information that the supplied refresh token is invalid or expired – in this case, a new authentication must be initiated. After refreshing, all previous token pairs become invalid. This endpoint doesn’t require an authorization header.
POST: auth/refresh
Request:
{
refresh_token: <string>
}
Request:
curl -X POST '<service_url>/api/playa/v1/auth/refresh' -H 'Accept: application/json' -H 'Content-Type: application/json'
--data-raw '{"refresh_token":"<refresh-token;"}'
Response:
{
"status": {
"code": 2,
"message": "Ok"
},
"data": {
"token": {
"access_token": "<a-guest-access-token>",
"refresh_token": "<a-guest-refresh-token>"
}
}
}
User information
This endpoint responds with a user object. This object contains user fields only when the access user token is provided in the authorization header. When a guest access token is provided, the user object contains only a guest indicator field. More information about that can be found in the “Responses” chapter.
GET: account/info
Request:
curl -X GET '<service_url>/api/playa/v1/account/info' -H 'Accept: application/json' -H 'Content-Type: application/json' -H ''Authorization: Bearer <access-token>'
Response:
{
"status": {
"code": 2,
"message": "Ok"
},
"data": {
"user": {
"is_guest": false,
"username": "user@email.test",
"role": 0,
"avatar": 0
}
}
}
Request:
curl -X GET '<service_url>/api/playa/v1/account/info' -H 'Accept: application/json' -H 'Content-Type: application/json'
-H 'Authorization: Bearer <access-token>'
Response:
{
"status": {
"code": 2,
"message": "Ok"
},
"data": {
"user": {
"is_guest": true
}
}
}
Avatar set (Legacy)
Sets a new avatar for the current user.
PUT: account/avatar
{
avatar: <int>
}
Response: {Status}
Request:
curl -X PUT '/api/playa/v1/account/avatar' -H 'Authorization: Bearer <access-token>' -H 'Accept: application/json' -H 'Content-Type: application/json' --data-raw '{"avatar":0}'
Response:
{
"status": {
"code": 2,
"message": "Ok"
}
}
Favorites (Legacy)
Returns a list of favourite videos for the current user.
GET: account/favorites
Request:
curl -X GET '<service_url>/api/playa/v1/account/favorites' -H 'Authorization: Bearer <access-token>' -H 'Accept: application/json' -H 'Content-Type: application/json'
Response:
{
"status": {
"code": 2,
"message": "Ok"
},
"data": {
"favorites": [98949, 99234, 97514, 97996, 97702, 98619, 98221, 95902, 96224, 117975, 113903]
}
}
Add a favourite (Legacy)
Adds a new favorite video id to the current user’s favorite video list.
PUT: account/favorites/{id}
Response: {Status}
Request:
curl -X PUT '<service_url>/api/playa/v1/account/favorites/121115' -H 'Authorization: Bearer <access-token>' -H 'Accept: application/json' -H 'Content-Type: application/json'
Response:
{
"status": {
"code": 2,
"message": "Ok"
}
}
Remove a favorite (Legacy)
Removes a favorite video id from the current user’s favorite video list.
DELETE: account/favorites/{id}
Response: {Status}
Request:
curl -X DELETE '<service_url>/api/playa/v1/account/favorites/121115' -H 'Authorization: Bearer <access-token' -H 'Accept: application/json' -H 'Content-Type: application/json'
Response:
{
"status": {
"code": 2,
"message": "Ok"
}
}
Configuration
Returns detailed information about the website’s configuration. Configuration explains which entities are available on the service. This endpoint requires authorization.
GET: configuration
Response: {Status, Configuration}
Request:
curl -X DELETE '<service_url>/api/playa/v1/configuration' -H 'Authorization: Bearer <access-token>' -H 'Accept: application/json'
Response:
{
"status": {
"code": 2,
"message": "ok"
},
"data": {
"configuration": {
"categories": true,
"announcements": false,
"free_videos": false
}
}
}
Video
Returns detailed information about video with specified id. If the authorization header will contain a guest access token, a video-links field will be empty.
GET: video/{id}
Request:
curl -X GET '<service_url>/api/playa/v1/video/101435' -H 'Authorization: Bearer <access-token>' -H 'Accept: application/json'
Response:
{
"status": {
"code": 2,
"message": "Ok"
},
"data": {
"video": {
"id": 101435,
"date_gmt": "2019-09-13T08:03:53",
"title": "A title",
"status": "publish",
"video_category": [260, 262, 482, 72, 440],
"video-poster": "<link>",
"video-preview-sprite": "<link>",
"trailer-preview-sprite": "",
"video-links": {
"3D 180 HQ": "<link>",
"3D 180 HD": "<link>",
"3D 180 4K": "<link>",
"3D 180 5K": "<link>",
"3D 180 6K": "<link>"
},
"trailer-links": {
"3D 180 HQ_trailer": "<link>",
"3D 180 HD_trailer": "<link>",
"3D 180 4K_trailer": "<link>",
"3D 180 5K_trailer": "<link>",
"3D 180 6K_trailer": "<link>"
},
"video-positions": ["Sitting", "Standing"],
"video-rating": 26,
"video-featured": 0,
"video-duration": "49:41",
"video-fps": "60",
"video-starring": ["Actor 1", "Actor 2"],
"seek_markers_full": [],
"seek_markers_trailer": [],
"timecodes_for_trailer": [76183],
"timecodes_for_video": [127667, 245417, 580717, 1000700, 1304883, 1531300, 1751817, 1991033, 2282450, 2614050, 2927867],
"automatic_camera_tilt": [{
"camera_tilt": -0.22,
"time_code": 49350
}, {
"camera_tilt": 0,
"time_code": 1745583
}, {
"camera_tilt": 0.68,
"time_code": 1751600
}, {
"camera_tilt": 0,
"time_code": 2273700
}, {
"camera_tilt": 0.39,
"time_code": 2279717
}],
"automatic_camera_tilt_trailer": [{
"camera_tilt": -0.22,
"time_code": 33733
}, {
"camera_tilt": 0,
"time_code": 38333
}, {
"camera_tilt": -0.22,
"time_code": 40383
}, {
"camera_tilt": 0,
"time_code": 48117
}, {
"camera_tilt": -0.22,
"time_code": 50533
}, {
"camera_tilt": 0,
"time_code": 58100
}, {
"camera_tilt": -0.22,
"time_code": 60517
}, {
"camera_tilt": 0,
"time_code": 67200
}, {
"camera_tilt": -0.22,
"time_code": 69617
}, {
"camera_tilt": 0.68,
"time_code": 71683
}, {
"camera_tilt": 0.39,
"time_code": 73717
}, {
"camera_tilt": 0,
"time_code": 78700
}],
"description": "A long text description <…>"
}
}
}
Videos
Returns a list of all videos. This endpoint supports pagination parameters page (optional page number – default 1) and per_page (optional video count per page – default 500).
GET: videos?page={page}&per_page={per_page}
Request:
curl -X GET '<service_url>/api/playa/v1/videos?page=50&per_page=2' -H 'Authorization: Bearer <access-token>' -H 'Accept: application/json'
Response:
{
"status": {
"code": 2,
"message": "Ok"
},
"data": {
"videos": [{
"id": 67833,
"date_gmt": "2018-12-18T08:17:50",
"title": "A title",
"status": "publish",
"video_category": [257, 266, 263, 482, 440],
"video-poster": "<link>",
"video-preview-sprite": "<link>",
"trailer-preview-sprite": "",
"trailer-links": {
"3D 180 HQ_trailer": "<link>",
"3D 180 HD_trailer": "<link>",
"3D 180 4K_trailer": "<link>",
"3D 180 5K_trailer": "<link>",
"3D 180 6K_trailer": "<link>"
},
"video-positions": ["Sitting"],
"video-rating": 8,
"video-featured": 0,
"video-duration": "42:50",
"video-fps": "60",
"video-starring": ["Actor 41"],
"seek_markers_full": [],
"seek_markers_trailer": [],
"timecodes_for_trailer": [0, 0, 0, 0, 0, 0, 0],
"timecodes_for_video": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"automatic_camera_tilt": [],
"automatic_camera_tilt_trailer": [],
"description": "A long text description <…>"
}, {
"id": 67013,
"date_gmt": "2018-12-13T11:21:48",
"title": "A title",
"status": "publish",
"video_category": [257, 139, 74, 262, 440],
"video-poster": "<link>",
"video-preview-sprite": "<link>",
"trailer-preview-sprite": "",
"trailer-links": {
"3D 180 HQ_trailer": "<link>",
"3D 180 HD_trailer": "<link>",
"3D 180 4K_trailer": "<link>",
"3D 180 5K_trailer": "<link>",
"3D 180 6K_trailer": "<link>"
},
"video-positions": ["Sitting"],
"video-rating": 13,
"video-featured": 0,
"video-duration": "47:23",
"video-fps": "60",
"video-starring": ["Actor 6"],
"video-tags": ["Tag 9", "Tag 16", "Tag 29", "Tag 33", "Tag 36", "Tag 41"],
"seek_markers_full": [],
"seek_markers_trailer": [],
"timecodes_for_trailer": [0, 0, 0, 0, 0, 0, 0, 0],
"timecodes_for_video": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"automatic_camera_tilt": [],
"automatic_camera_tilt_trailer": [],
"description": "A long text description <…>"
}]
}
}
Free videos
Returns a list of all videos. This endpoint supports pagination parameters page (optional page number – default 1) and per_page (optional video count per page – default 500).
GET: videos/free
Request:
curl -X GET '<service_url>/api/playa/v1/videos/free' -H 'Authorization: Bearer <access-token>' -H 'Accept: application/json'
Response:
(See videos response)
Categories
Returns a list of the video’s categories.
GET: videos/categories
Request:
curl -X GET '<service_url>/api/playa/v1/videos/categories' -H 'Authorization: Bearer <access-token>' -H 'Accept: application/json'
Response:
{
"status": {
"code": 2,
"message": "Ok"
},
"data": {
"categories": [{
"id": 64,
"name": "First category",
"cat-image": "<link>"
}, {
"id": 65,
"name": "Second category",
"cat-image": "<link>"
}, {
"id": 134,
"name": "Third category",
"cat-image": "<link>"
}]
}
}
Announcements
Returns a list of announcements with image links.
GET: announcements
Response: {Status, Announcements}
Request:
curl -X GET '<service_url>/api/playa/v1/announcements' -H 'Authorization: Bearer <access-token>' -H 'Accept: application/json'
Response:
{
"status": {
"code": 2,
"message": "Ok"
},
"data": {
"announcements": [{
"caption": "Caption 1",
"newslink": "<link>"
}, {
"caption": "Caption 2",
"newslink": "<link>"
}]
}
}
Timestamps
Returns the last updated timestamps for the entities: announcements, categories, and videos. These timestamps should be used to build a request workflow – update only the entities that have changed.
GET: timestamps
​
Response: {Status, Timestamps}
Request:
curl -X GET '<service_url>/api/playa/v1/timestamps' -H 'Authorization: Bearer <access-token>' -H 'Accept: application/json'
Response:
{
"status": {
"code": 2,
"message": "Ok"
},
"data": {
"timestamps": {
"ts_categories": 1584525289,
"ts_videos": 1584544393,
"ts_announcements": 1574235871
}
}
}