SAPI is the “Server API” that can be used to manage, publish, and retrieve content from (web) applications. The SAPI Reference Guide contains information about its general usage and authentication, as well as a list of supported endpoints and routes.
The SAPI is a RESTful API that uses JSON notation for most content representations.
1.0 | SAPI characteristics
The Server API is accessible using your publication’s base URL, for example my-beautiful-publication.bbvms.com or company-name.bbvms.com.
1.1 | Object structure
- A standardised object structure is used for all media objects:
- “type” property: object type (e.g.
"project"or"mediaclip") - “id” property: unique entity ID
- “status”: current status; content uses
draftorpublished, configurations useactiveorinactive
- “type” property: object type (e.g.
- All endpoints are lowercase versions of the object type, for example:
- Mediaclip:
my-beautiful-publication.bbvms.com/sapi/mediaclip - Project:
my-beautiful-publication.bbvms.com/sapi/project - Channel:
my-beautiful-publication.bbvms.com/sapi/channel - Playout:
my-beautiful-publication.bbvms.com/sapi/playout
- Mediaclip:
- Objects are returned in JSON format.
- Dates are in ISO 8601 format and use the Zulu (UTC) timezone.
1.2 | HTTP methods (GET, DELETE, PUT, POST)
Standard HTTP methods are used for all supported actions:
Retrieves an object. For example: GET my-beautiful-publication.bbvms.com/sapi/mediaclip/123456
Retrieves a list of or searches across the given object type. For example: GET my-beautiful-publication.bbvms.com/sapi/mediaclip
Deletes an object. For example: DELETE my-beautiful-publication.bbvms.com/sapi/mediaclip/123456
Creates the object included in the payload (body) of the request. For example: POST my-beautiful-publication.bbvms.com/sapi/mediaclip
Updates an object with the properties included in the payload. For example: PUT my-beautiful-publication.bbvms.com/sapi/mediaclip/123456
API requests are designed to be stateless; no session is required. One-time tokens are used to sign and authorise requests.
Responses consist of either the requested or updated object, or a Response object (type: "Response") containing information about the executed API request.
1.3 | HTTP status codes
HTTP status codes follow the standard pattern:
- 200 (OK): successful request
- 204 (No Content): a pre-flight response
- 400 (Bad Request): incomplete or invalid request; the server could not understand the request due to invalid syntax
- 403 (Forbidden): the client does not have authorised access to the object
- 404 (Not Found): the object cannot be found, or is hidden because its status is
"draft"
1.4 | Metadata versioning and state management
Most object types (endpoints) support metadata versioning and state management.
Retrieve all metadata versions:
For example: GET my-beautiful-publication.bbvms.com/sapi/project/1234/versions
Retrieve metadata versions including the version author:
For example: GET my-beautiful-publication.bbvms.com/sapi/mediaclip/123456/versions?metadata
Retrieve a specific version:
For example: GET my-beautiful-publication.bbvms.com/sapi/project/version/yRYi1fLkiumvZYm.qsrI1uILf1ayACNz
To PUT or GET an object in a specified state (e.g. "staging" or "work-in-progress"): include a state HTTP header in the request. If the specified state is not found, the default state is used.
2.0 | Authentication
Authentication is required using time-based tokens on a shared secret. As part of the onboarding process you will receive a set of API key credentials. OVP users with admin access can also retrieve these credentials in the publication settings; see API key management for more information.
The secret from the API key credentials is used to calculate time-based tokens. SAPI uses the HOTP algorithm for token calculation; read more about HOTP.
For a detailed explanation of the authentication flow, see SAPI Authentication.
For production integrations, Blue Billywig recommends using one of the official SAPI SDKs, which handle authentication, request construction, and error handling out of the box. SDKs are available for PHP, Node.js, Python, and PowerShell.
If you prefer to implement authentication directly, the following examples show how to calculate a time-based token.
2.1 | Node.js example
The following example uses the speakeasy package to calculate a time-based token.
var speakeasy = require("speakeasy");
var request = require("request");
var ROOT_SECRET_ID = 123; // Use "id" from API key credentials.
var ROOT_SECRET = "12345678f9e01dc2ba3e4d56c7b89ae0"; // Use "secret" from API key credentials.
var token = speakeasy.totp({ secret: ROOT_SECRET, digits: 10, step: 120 });
var url = "http://yourcompanyname.bbvms.com/sapi/publication?rpctoken=" + ROOT_SECRET_ID + "-" + token;
request.get({ url: url }, function(error, response, body) {
console.log("body: ", body);
console.log("response: ", response);
});2.2 | PHP example
Example HOTP framework in PHP: https://github.com/Jakobo/hotp-php
Use the HOTP::generateByTime method with the "secret" from the API key credentials and a 120-second time window to calculate a 10-digit token.
Set an rpctoken HTTP header using both the "id" from the API key credentials and the calculated token, for example:
123-1234567890