Appearance
Server API Reference
Introduction
Ease Live Server handles authorisation, manages users and events. Our cloud based production system, Cockpit, pushes events to the event server and makes them available to the clients.
The event server is the heart of the Ease Live system, making sure all events are collected and distributed as needed.
REST API
The ELS REST API enables producer applications (e.g. data importers, producer dashboards, Vizrt, Ross, vision mixers, etc.) to implement support for publishing events to Ease Live.
Any HTTP client library can be used to access the API. For Node/browser environments, there is a client bundled with the NPM package @ease-live/ease-live-client
.
Base URL
The base URL of the APIs is https://<account_id>.cloud.easelive.tv/api/v1/
.
Authentication
The API uses the OAuth2 password credentials flow to authenticate users.
After obtaining an access token from the /token endpoint the token should be stored in the client application, and be sent in the Authorization
header on subsequent requests. If sending headers is not supported by the client, the token can optionally be sent in an access_token
value in the body of the request.
Client ID
When requesting a token from an application that should publish events to the event server a client_id must be provided to identify the type of application. This should be one of:
client_id | Description |
---|---|
EaseLiveEventServerTest | Used for test runs on the event server |
WebProducerDashboard | a producer dashboard web app |
BlackmagicAtem | mixer transmitter app for Blackmagic ATEM mixers |
RossDashBoard | OG script in Ross DashBoard |
RossXPression | event transmitter app for Ross XPression |
VizrtMediaSequencer | event transmitter app for Vizrt Media Sequencer |
TIP
Just use WebProducerDashboard
as the client_id
value. The API doesn't distinguish between these Client IDs anymore, but at the moment it is still a requirement to login.
POST /token
Authenticates the user and returns an access token that will be used to authorize the user on other requests.
On successful login the reponse will contain an access_token
value. This should be stored in the client application, and be sent in the Authorization
header on subsequent requests to other endpoints.
Header | Value |
---|---|
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
grant_type | password | string | yes |
username | The username of the user to grant access to | string | yes |
password | The user's password | string | yes |
It is also possible to authenticate using a Sixty ID token:
Key | Value | Type | Required |
---|---|---|---|
grant_type | s_id_token | string | yes |
token | The Sixty ID token | string | yes |
Success response
Key | Value | Type |
---|---|---|
access_token | string containing signed JWT | string |
token_type | Type of the token. Will be Bearer | string |
expires_in | The lifetime in seconds of the access token | integer |
Error responses
Status | Error | Description |
---|---|---|
400 | unsupported_grant_type | Only supports password |
400 | invalid_client | The client is not authorized (missing client_id value) |
400 | invalid_request | The user could not be authenticated |
401 | bad_credentials | Invalid username or password |
429 | slow_down | The client sent too many requests |
Example
bash
curl -H "Content-Type: application/json" \
-X POST \
-d '{"grant_type":"password","client_id":"EaseLiveEventServerTest","username":"producer","password":"password"}' \
http://localhost:4001/api/v1/token
json
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InByb2R1Y2VyIiwicm9sZSI6InByb2R1Y2VyIiwidXNlcklkIjoiYjYxOTIyMmEtMzIyNS00MDE0LTkyZmMtNjUyMzY0ZjAwOTQzIiwiaWF0IjoxNDc4Njk5Nzc1LCJleHAiOjE0Nzg3ODYxNzV9.oSnoqh4nhfvNjsGiIMosbUnCG_ttyImbFYrKbtC_-cA",
"token_type": "Bearer",
"expires_in": 86400
}
Programs
POST /programs
Create a new program.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
id | ID of the program | string | yes |
name | Name of the program | string | yes |
scheduledStartTime | Start time | date | no |
scheduledEndTime | End time | date | no |
GET /programs/:id
Get a program.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
id | ID of the program | string | yes |
GET /programs/:id/lastUpdate
Get the last event update timestamp for the program.
PUT /programs/:id
Update program.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
id | ID of the program | string | yes |
name | Name of the program | string | yes |
scheduledStartTime | Start time | date | yes |
scheduledEndTime | End time | date | yes |
DELETE /programs/:id
Delete a program. Note that this will also delete any events created in this program.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
id | ID of the program | string | yes |
GET /programs
Get a list of programs that the logged in producer can publish events to. To find expired/old programs, use the GET /programs/filter
endpoint.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Success response
Key | Value | Type |
---|---|---|
[0].id | ID of the program in the database | string |
[0].createdTime | The ISO 8601 datetime the program was stored to the database | string |
[0].name | The title of the program | string |
[0].scheduledStartTime | The time the program is scheduled to start | string |
[0].scheduledEndTime | The time the program is scheduled to end | string |
Error responses
Status | Error | Description |
---|---|---|
401 | invalid_token | The token is missing or expired. Client should request a new token |
403 | insufficient_scope | The token doesn't have publishing access |
400 | invalid_request | Some parameter is missing or has invalid value |
Example
bash
curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InByb2R1Y2VyIiwicm9sZSI6InByb2R1Y2VyIiwidXNlcklkIjoiYjYxOTIyMmEtMzIyNS00MDE0LTkyZmMtNjUyMzY0ZjAwOTQzIiwiaWF0IjoxNDc4Njk5Nzc1LCJleHAiOjE0Nzg3ODYxNzV9.oSnoqh4nhfvNjsGiIMosbUnCG_ttyImbFYrKbtC_-cA" \
http://localhost:4001/api/v1/programs
json
[
{
"createdTime": "2016-11-09T15:37:23.817Z",
"id": "dd4d5f3e-5723-4587-b1d4-c24",
"name": "FC Bayern M\u00fcnchen - Real Madrid CF",
"scheduledEndTime": "2016-11-09T19:30:00.000Z",
"scheduledStartTime": "2016-11-09T17:00:00.000Z"
},
{
"createdTime": "2016-11-09T15:39:12.611Z",
"id": "ac4aab4e-4523-9842-a3d4-a12",
"name": "Brann - Rosenborg",
"scheduledEndTime": "2016-11-09T21:30:00.000Z",
"scheduledStartTime": "2016-11-09T19:45:00.000Z"
}
]
GET /programs/filter
Search/filter programs. Note that like /programs
, this endpoint only returns programs that the logged in user has publish access to.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
order | no | ||
sort | no | ||
limit | no | ||
skip | no | ||
search | no | ||
status | no | ||
projectId | Filter programs by project. Set to 'undefiend' to find programs without projects | no | |
from | date | no | |
to | date | no | |
live | Find programs by live status (based on scheduled start/end time). | boolean | no |
ids | no |
Events
Methods for publishing change in the state of the on-air graphics or data that should be propagated to Ease Live clients connected to the program on which the event was published. For example if the producer shows a lower third with information about a player, an event Player#show
should be posted, and when he hides it Player#hide
. Events can also be used to update data on the clients without triggering a change of visibility of a component, for example a LeagueTable#update
event.
GET /programs/:id/events
Get all program events for a given program. If the to
parameter is included, a cache header will be applied.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
from | program events with timecode greater than or equal to this value | integer | no |
to | program events with timecode less than or equal to this value | integer | no |
includeCreated | can be used in combination with from/to to consider event creation time in addition to just the timecode | boolean | no |
GET /programs/:id/events/filter
Search/filter program events.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
order | no | ||
sort | no | ||
limit | no | ||
skip | no | ||
search | no | ||
status | no | ||
ids | no |
DELETE /programs/:id/events
Delete all program events for a given program.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Success response
Key | Value | Type |
---|---|---|
deleted | Number of events deleted | integer |
DELETE /programs/:id/events/:eventId
GET /programs/:id/events/:eventId
PUT /programs/:id/events/:eventId
POST /programs/:id/events
Create new events. The events will be pushed to all clients connected to the program. It is also possible to create a batch of events at once by using the events
option.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
events | list of events, when using batch create | array | no |
event | event name in format Component#action | string | yes |
timestamp | when the event occured in milliseconds since 1970-01-01T00:00:00Z. if left out, it will be set to current server time | integer | no |
metadata | extra data for the event | object | no |
Success response
Key | Value | Type |
---|---|---|
id | ID of the event in the database | string |
programId | ID of the program that was published to | string |
createdTime | The ISO 8601 datetime the event was stored to the database | string |
timestamp | when the event occured | integer |
event | event name | string |
metadata | extra data for the event | object |
Error responses
Status | Error | Description |
---|---|---|
401 | invalid_token | The token is missing or expired. Client should request a new token |
403 | insufficient_scope | The token doesn't have publishing access |
400 | invalid_request | Some parameter is missing or has invalid value |
Example
bash
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InByb2R1Y2VyIiwicm9sZSI6InByb2R1Y2VyIiwidXNlcklkIjoiYjYxOTIyMmEtMzIyNS00MDE0LTkyZmMtNjUyMzY0ZjAwOTQzIiwiaWF0IjoxNDc4Njk5Nzc1LCJleHAiOjE0Nzg3ODYxNzV9.oSnoqh4nhfvNjsGiIMosbUnCG_ttyImbFYrKbtC_-cA" \
-d '{"event":"ScoreBug#show","timestamp":1478106472323,"metadata":{"home":1,"away":3}}' \
http://localhost:4001/api/v1/programs/dd4d5f3e-5723-4587-b1d4-c24/events
json
{
"event": "ScoreBug#show",
"timestamp": 1478106472323,
"metadata": {
"away": 3,
"home": 0
},
"programId": "dd4d5f3e-5723-4587-b1d4-c24",
"createdTime": "2016-11-08T10:04:05.995Z",
"id": "88c26ebc-4f2d-41b2-bbc9-15e4537079d9"
}
POST /programs/:id/events/import
Batch import of program events, mainly for use with non-live programs. Imported events will not be pushed to clients unless they reconnect.
NOTE: This will delete any existing events in the program. For pushing multiple events without deleting, use the regular POST /programs/:id/events
endpoint.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
programId | ID of the program to published to | string | |
events | array of event objects | array | yes |
GET /programs/:id/events/export
Projects
GET /projects
POST /projects
GET /projects/:id
PUT /projects/:id
DELETE /projects/:id
GET /projects/:id/users
GET /projects/:id/programs
Application revisions
An application revision has the following properties:
- id
- projectId
- title
- description
- version
- status (published, draft)
- content (json object)
- createdBy
- updatedBy
- createdTime
- updatedTime
GET /projects/:id/application
Returns latest application revision with published status (shortcut for /status/published
)
GET /projects/:id/application/status/:status
Returns latest application revision with given status
GET /projects/:id/application/version/latest
Returns latest published version, or falls back to latest draft version.
GET /projects/:id/application/version/:version
Returns application revision by version (either version ID or string).
GET /projects/:id/application/live/:version
Returns an end-user revision by version (either version ID or string). This is used by end-users and is stripped of sensitive data such as credentials not needed for mass consumption.
GET /projects/:id/application/revisions(?status=draft/publish)
List all revisions, optionally filtered
POST /projects/:id/application/revisions
Create new revision
GET /projects/:id/application/revisions/:id
Get a specific revision by ID
PUT /projects/:id/application/revisions/:id
Update revision
PATCH /projects/:id/application/revisions/:id
Patch revision. Patch can be supplied using either the JSON Patch or JSON Merge Patch standards.
POST /projects/:id/revisions
Create new revision
Application proxy requests
Proxy requests an API data source setup in Studio, instead of executing the request in the browser. If any headers, query params or body params are missing, the defaults in the data source will be used.
Supports the request methods below:
GET /projects/:id/application/requests/:version/:dataSourceId
POST /projects/:id/application/requests/:version/:dataSourceId
PUT /projects/:id/application/requests/:version/:dataSourceId
DELETE /projects/:id/application/requests/:version/:dataSourceId
Project storage
It is possible to store any JSON payload in a project scope. The value will be non-guaranteed persisted in the cache layer, but the GET HTTP request to retrieve the value will be cached for 24h. This is useful for sharing information between clients in a live setting.
GET /storage/:projectId/:itemId
Success response
Key | Value | Type |
---|---|---|
id | UUID | string |
metadata | JSON data structure | object |
createdTime | The ISO 8601 datetime the metadata was stored | string |
Example response:
json
{
"id": "k3M2ChfEcs4vYz5GsyH6jG",
"metadata": {
"myProperty": "myValue"
},
"createdTime": "2021-09-08T10:04:05.995Z",
}
POST /storage/projectId
If you don't specify an id, the API will create it for you.
Header | Value |
---|---|
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
id | ID of the value so you can retrieve it | string | no |
metadata | json object | object | yes |
Success response
Key | Value | Type |
---|---|---|
id | UUID | string |
metadata | JSON data structure | object |
createdTime | The ISO 8601 datetime the metadata was stored | string |
Example response:
json
{
"id": "k3M2ChfEcs4vYz5GsyH6jG",
"metadata": {
"myProperty": "myValue"
},
"createdTime": "2021-09-08T10:04:05.995Z",
}
Project analytics
* /api/v1/projects/:projectId/analytics
Matomo proxy for fetching reports. Limited to the project's idSite
GET /api/v1/projects/:projectId/analytics/site
Verify the Matomo config, to ensure it has a Matomo site with the correct dimensions and reports. If there is an existing site, but it has issues that can't be automatically solved by PUT
(or POST
in the case of 'not-created'
), it returns { status: 'errors' }
.
Success response
Key | Value | Type |
---|---|---|
status | 'ok' / 'incomplete' / 'errors' / 'not-created' | string |
message | A more detailed reason for the returned status | string |
idSite | The ID of the project's Matomo site | string |
site | The full Matomo metadata for the site | object |
dimensions | All the site's custom dimensions as returned by Matomo | array |
dimensionIds | Dimension ID's mapped to camelCase keys of their names, split into { visit, action } | object |
reports | The site's custom reports | array |
reportIds | Custom report ID's mapped to camelCase keys of their names | object |
badReports | Any reports that are incorrectly configured | array |
missingReports | Any reports that are missing | array |
proxyHasAccess | Whether SixtyReadOnly has 'view' access | boolean |
Error responses
Status | Error | Description |
---|---|---|
404 | Not found | The site ID in the metadata does not exist |
500 | Any other error returned by Matomo |
POST /api/v1/projects/:projectId/analytics/site
Create a new Matomo site from scratch, fully configured with dimensions and reports. It will:
- Create a new Matomo site
- Add our custom dimensions
- Add our custom reports
- Write the Matomo ID to the project's metadata
- Write the custom dimension ID's to the project's metadata
- Give the SixtyReadOnly user 'view' access to the new site
Success response
POST returns the same status response as GET when successful.
Error responses
Status | Error | Description |
---|---|---|
500 | Already exists | The project already has a Matomo ID. Verify it with GET , and finish setup with PUT if incomplete. |
500 | Any other error returned by Matomo |
PUT /api/v1/projects/:projectId/analytics/site
Finish the setup of an existing site (only works if the project metadata contains a Matomo ID, and as long as GET
doesn't return { status: 'errors' }
). It will:
- Add our custom dimensions if they don't exist
- Add any missing custom reports
- Update the project's metadata with the site and dimension ID's
- Give the SixtyReadOnly user 'view' access to the site
Success response
PUT returns the same status response as GET when successful.
Error responses
Status | Error | Description |
---|---|---|
404 | Not found | The site ID in the metadata does not exist |
500 | Bad config | There are problems with the config. Call GET for details. |
500 | Any other error returned by Matomo |
Users
GET /users/me
GET /users
POST /users
Create user.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Key | Value | Type | Required |
---|---|---|---|
role | User role (one of admin/producer/user/client) | string | yes |
username | string | yes | |
password | string | yes | |
name | string | no | |
string | no |
GET /users/:id
PUT /users/:id
DELETE /users/:id
GET /users/roles
Returns an array of strings with role names, e.g.:
[
"admin",
"producer",
"client",
"user"
]
Statistics
GET /statistics/dashboard
GET /statistics/filtered
Status
Methods for informing the server about the status of the client and getting the status of the server from the client.
GET /version
Returns information about version, buld number, and build date.
POST /ping
Let the server know that the client is still online. Recommended to call on an interval of 1 minute when no events are being sent.
Header | Value |
---|---|
Authorization | Bearer $ACCESS_TOKEN |
Content-Type | application/json |
Success response
Key | Value | Type |
---|---|---|
current_time | The current time on the server | integer |
Error responses
Status | Error | Description |
---|---|---|
401 | invalid_token | The token is missing or expired. Client should request a new token |
400 | invalid_request | Some parameter is missing or has invalid value |
Example
bash
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InByb2R1Y2VyIiwicm9sZSI6InByb2R1Y2VyIiwidXNlcklkIjoiYjYxOTIyMmEtMzIyNS00MDE0LTkyZmMtNjUyMzY0ZjAwOTQzIiwiZXZlbnRQdWJsaXNoZXJJZCI6IjU1ZjcyYzA2LTkwODQtNGIzOC04NTcxLWJkMjlmOGY0ZDAwYSIsImV2ZW50UHVibGlzaGVyTmFtZSI6IkVhc2UgTGl2ZSBFdmVudCBTZXJ2ZXIgVGVzdCIsImlhdCI6MTQ3ODUzODYzNiwiZXhwIjoxNDc4NjI1MDM2fQ.-Cr-D99d8ziRBcADuWWSsjY35YUE1GcHKqMBGHBxBik" \
http://localhost:4001/api/v1/ping
POST /servertime
Gets the current time on the server. If the client can not be synced with NTP, and assuming the server is synced with NTP, this can be used in the client to calculate a more accurate timestamp for events sent by the client.
Key | Value | Type | Required |
---|---|---|---|
requestTime | time on the client when the request was sent, in milliseconds since 1970-01-01T00:00:00Z | integer | no |
Success response
Key | Value | Type |
---|---|---|
serverTime | The current time on the server, in milliseconds since 1970-01-01T00:00:00Z | integer |
requestTime | The argument for the requestTime parameter, if available | integer |
Example
bash
curl -X POST \
-H "Content-Type: application/json" \
-d '{"requestTime":1478600537319}' \
http://localhost:4001/api/v1/servertime
WS API
admin/getLivePrograms
Returns a list of active programs. Only available if the statistics module is enabled.
admin/createProgram
Same as POST /programs
.
admin/deleteProgram
Same as DELETE /programs/:id
.
updateProgram
Same as PUT /programs/:id
.
Previously: admin/updateProgram
. This alias will be removed in a future major release.
deleteAllProgramEvents
Same as DELETE /programs/:id/events
.
Previously: admin/deleteAllProgramEvents
. This alias will be removed in a future major release.
getProducerPrograms
Same as GET /programs
.
getProgram
Same as GET /programs/:id
.
getProgramEvents
Same as GET /programs/:id/events
.
Previously: admin/getProgramEvents
. This alias will be removed in a future major release.
importProgramEvents
Import events. Same as POST /programs/:programId/events/import
.
login
Authenticate user. Same as POST /token
.
producer
Publish events. Same as POST /programs/:id/events
.
servertime
Same as POST /servertime
.
subscribe
Subscribe to program/channel.
unsubscribe
Unsubscribe from program/channel.