KZO API
Base URI
The following are the mandatory and optional HTTP headers supported by the KZO REST service platform.
Request Headers
Authorization: Mostly mandatory. A few services, such as authentication, do not require this header.
Content-Length: Mandatory, if the body of the REST request contains content. Most REST client frameworks will compute and add this header for a user.
Content-MD5: Optional, but recommended. The Base64-encoded 128-bit MD5 digest of the request body (without the headers). This header can be used in the signature to verify integrity of the request body.
Content-Type: Mandatory, if the body of the REST request contains content. This should be of the form:
"application/vnd.kzo+json"
Content-Encoding: Optional; should be used if the request body contains additionally encoded content.
Accept: Mandatory, if the REST request expects content to be returned in the response. This should be of the form:
"application/vnd.kzo+json"
Date: Mandatory. The current date and time according to the client. All timestamps must follow the ISO8601 standard, and use UTC (Z for “Zulu”). Example: 2012-10-10T14:12:24.324Z
If-Match: Mandatory if the request is an update (using either PUT or POST). This should contain the version stamp of the resource to be updated. The version stamp is found from the ETag header in the response when the resource was originally created or queried by the client, or when the client queried metadata on the resource (HEAD request).
If-None-Match: Optional. This can be used to perform a conditional GET of a resource. If specified, the ETag value of the resource representation available to the client should be used here.
X-KZO-Session-Token: Mandatory if the request is from an authenticated user within an existing session. This should contain the session token provided to that user.
Host: Mandatory. Most REST client frameworks will add this header for the user.
Response Headers
Content-Length: Mandatory, if the body of the REST response contains content. Most REST server frameworks will compute and add this header.
Content-Type: Mandatory, if the body of the REST response contains content. This should be of the form:
"application/vnd.kzo+json"
ETag: Mandatory if this is a response to a resource update, a resource create, or a resource GET. It contains the latest version stamp of the resource.
Content-Encoding: Optional; should be used if the response body contains additionally encoded content.
Authorization Header:
All API consumers must correctly add an Authorization header to the REST request. It contains an AccessKeyType
, AccessKeyId
, and a Signature
It has the following format:
Authorization: AccessKeyType:AccessKeyID:Signature
AccessKeyType
The AccessKeyType field must be either PLATFORM
, or SESSION
.
Signature
This is the specification for the Signature
field:
Signature = Base64( HMAC-SHA1( SecretAccessKey, UTF-8-Encoding-Of( StringToSign ) ) );
The SecretAccessKey
should be used to sign the UTF-8-encoded StringToSign, using HMAC-SHA1. The resulting signature should then be Base64-encoded.
This is the specification of StringToSign
:
StringToSign = HTTP-Method + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Accept + "\n" +
Date + "\n" +
CanonicalizedKzoHeaders+
CanonicalizedResource;
Content-MD5 = The Content-MD5 header value as is. If not present, then leave it out.
Content-Type = The Content-Type header value as is. If not present (with GETs), leave it out.
Accept = The Accept header value as is. If not present, leave it out.
Date = The Date header value as is. If not present, leave it out.
CanonicalizedKzoHeaders = Concatenate all headers starting with “X-KZO” (the complete header - key and value), as follows: Convert each header to lowercase, sort them lexicographically using the header key, remove all whitespaces surrounding the colon between the key and value, and finally add a newline ("\n") after each header.
CanonicalizedResource = The HTTP Request URL, including the protocol name and the query string.
The following HTTP Response codes will be used with successful requests:
200 OK
Standard response code for a successful GET
. The HTTP response will contain the requested resource.
201 Created
Standard response code for a successful POST
. The response will contain the newly created resource including the id so that it can be used on subsequent requests.
202 Accepted
Used when the request has been accepted and its processing will be done asynchronously on the server. Often used with long-running processes such as workflows or batch requests. Note that the processing can still fail; usually, the response will include a URL in the Location header where the current status of the processing can be queried by the client.
204 No Content
Standard response code for a successful PATCH
, POST
, or DELETE
.
304 Not Modified
Used with a conditional GET
, when the resource representation of the client is the same as that on the server.
400 Bad Request
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
GET
Used for retrieving resources
POST
Used for creating new resources
PATCH
Used for updating select attributes for a resource. For example, a Media
object has multiple attributes such as title
and description
. A PATCH
request may accept one or more of the attributes to update the resource, so that all attributes are not required in the request payload.
PUT
Used for replacing resources entirely. Any missing attributes will either trigger an error (if they are required), or set the attribute’s value to null (if they are optional).
DELETE
Used for deleting resources.
Purpose
Used by a User to authenticate with credentials against the platform and establish a session.
Preconditions
- Since credentials and the Access Key’s secret key are passed in the request and response respectively, this service MUST be invoked using SSL (HTTPS).
- The Authorization header is not specified for this service.
- The User must exist in the Tenant’s User base, and the credentials must match.
- The User and Tenant must be in an ACTIVE state on the platform.
- A User can already be associated with multiple ACTIVE Session Access Keys, but a threshold must be enforced. If this threshold is exceeded this request must be rejected.
Description
The platform creates a new ACTIVE Session Access Key for the specified User.
Request body
Responses
Body
Examples
POST https://tenant.kzoplatform.com/api/v2/security/session_access_key HTTP/1.1
Content-Type: application/json
{
"username" : "admin",
"password" : "myCrypticPassw0rd"
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_key_id" : "AKIAIOSFODNN7EXAMPLE",
"secret_access_key" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"expiration" : "2014-10-10T14:12:23.324Z",
"session_token" : "ddkfssdfvDNN7EXAMPLE",
"status" : "ACTIVE"
}
Containers are abstract objects that can either contain media (such as videos) or other containers to form a hierarchy. All media created must belong to a container.
Only one root container is allowed, which is created automatically during the tenant creation process. Therefore, all containers created through the API must belong to another container.
{id}
{id}
/container{id}
/permissions{id}
/permissions{id}
/permissions/{permissionid}
Examples
GET https://tenant.kzoplatform.com/api/v2/containers/14 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"id" : 14,
"root" : false,
"published" : false,
"display" : false,
"name" : "Marketing Videos",
"parent_container_id" : 1,
"description" : "My awesome description for this container",
"items" : [ {
"id" : 1,
"order" : 1,
"media" : {
"id" : 234,
"container_id" : 12,
"title" : "Baby's first video!",
"description" : "A lovely description for your new video.",
"upload_url" : "https://tenant.kzoplatform.com/files/video/4436",
"complete" : false,
"closed_captions" : [ {
"id" : 38583,
"language" : "en",
"text" : "I'm a chapter title!",
"start_msec" : 7743,
"end_msec" : 10322
} ],
"renditions" : [ {
"id" : 94862,
"filesize" : 403857413,
"md5" : "9729bfefe48c6c088f0ffa2cea05edf5",
"completed" : false,
"bitrate" : 800,
"resolution" : "720",
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
} ],
"chapters" : [ {
"id" : 7534,
"text" : "My first chapter!",
"msec" : 1232,
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
} ],
"thumbnails" : [ {
"id" : 8238,
"msec" : 5000,
"md5" : "9729bfefe48c6c088f0ffa2cea05edf5",
"href" : "https://tenant.kzoplatform.com/files/thumbnails/234223.jpg",
"size" : "34938",
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
} ],
"comments" : [ {
"id" : 1,
"media_id" : 1,
"parent_id" : null,
"text" : "This video is great!",
"msec" : "5500",
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1,
"deleted_at" : "2012-10-10T16:34:23.871Z",
"deleted_by" : 1
} ],
"slide_deck" : {
"id" : 553,
"slides" : [ null ],
"href" : null,
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
},
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
},
"container" : [ ],
"link_type" : "original"
} ]
}
{id}
/containerCreates a container
Path variables
The id of the parent container that this container should become a child of
Request body
1
Responses
Body
Examples
POST https://tenant.kzoplatform.com/api/v2/containers/1/container HTTP/1.1
Content-Type: application/json
{
"order" : 1,
"display" : true,
"name" : "Marketing Videos",
"description": "All of our Marketing videos will go in here"
}
HTTP/1.1 201 Created
Content-Type: application/json
{
"id" : 14,
"root" : false,
"published" : false,
"display" : false,
"name" : "Marketing Videos",
"description" : "My awesome description for this container",
"items" : [],
"parent_container_id" : 1,
}
{id}
/permissionsPath variables
Responses
Body
Examples
GET https://tenant.kzoplatform.com/api/v2/containers/234/permissions HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
[ {
"id" : 5683,
"role" : {
"id" : 12,
"name" : "admin",
"abilities" : [ "CREATE CONTENT" ]
},
"group" : {
"id" : 48,
"name" : "Marketing",
"members" : [ {
"id" : 5542,
"username" : "admin",
"password" : null,
"email" : "admin@example.org",
"avatar_url" : "https://tenant.kzoplatform.com/files/avatar/5542"
} ]
},
"container_id" : 234
} ]
{id}
/permissionsPermissions are a mapping between groups and roles and are applied to a container
Path variables
Request body
Responses
Body
Examples
POST https://tenant.kzoplatform.com/api/v2/containers/234/permissions HTTP/1.1
Content-Type: application/json
{
"role_id" : 12,
"group_id" : 48
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"id" : 5683,
"role" : {
"id" : 12,
"name" : "admin",
"permissions" : [ {
"id" : 22,
"name" : "CREATE CONTENT"
} ]
},
"group" : {
"id" : 48,
"name" : "Marketing"
},
"container_id" : 234
}
{id}
{id}
/media{id}
{id}
{id}
/video{id}
/slide_deck{id}
View information about a given Media object (like a video)
Path variables
Responses
Body
Examples
GET https://tenant.kzoplatform.com/api/v2/media/234 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"id" : 234,
"container_id" : 12,
"title" : "Baby's first video!",
"description" : "A lovely description for your new video.",
"upload_url" : "https://tenant.kzoplatform.com/files/video/4436",
"complete" : false,
"closed_captions" : [ {
"id" : 38583,
"language" : "en",
"text" : "I'm a chapter title!",
"start_msec" : 7743,
"end_msec" : 10322
} ],
"renditions" : [ {
"id" : 94862,
"filesize" : 403857413,
"md5" : "9729bfefe48c6c088f0ffa2cea05edf5",
"completed" : false,
"bitrate" : 800,
"resolution" : "720",
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
} ],
"chapters" : [ {
"id" : 7534,
"text" : "My first chapter!",
"msec" : 1232,
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
} ],
"thumbnails" : [ {
"id" : 8238,
"msec" : 5000,
"md5" : "9729bfefe48c6c088f0ffa2cea05edf5",
"href" : "https://tenant.kzoplatform.com/files/thumbnails/234223.jpg",
"size" : "34938",
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
} ],
"comments" : [ {
"id" : 1,
"media_id" : 1,
"parent_id" : null,
"text" : "This video is great!",
"msec" : "5500",
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
} ],
"slide_deck" : {
"id" : 553,
"slides" : [ "" ],
"href" : "",
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
},
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
}
{id}
/mediaPath variables
The id of the container you wish to put the new video in
Request body
Responses
Body
Examples
POST https://tenant.kzoplatform.com/api/v2/containers/{id}/media HTTP/1.1
Content-Type: application/json
{
"title" : "Baby's first video!",
"description" : "A lovely description for your new video.",
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"id" : 234,
"container_id" : 12,
"title" : "Baby's first video!",
"description" : "A lovely description for your new video.",
"upload_url" : "https://tenant.kzoplatform.com/files/video/4436",
"complete" : false,
"closed_captions" : [],
"renditions" : [],
"chapters" : [],
"thumbnails" : [],
"comments" : [],
"slide_deck" : {},
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
}
Examples
PUT https://tenant.kzoplatform.com/api/v2/media/234 HTTP/1.1
Content-Type: application/json
{
"id" : 234,
"title" : "Baby's first video!",
"description" : "A lovely description for your new video.",
"complete" : true,
"closed_captions" : [ {
"id" : 38583,
"language" : "en",
"text" : "I'm a chapter title!",
"start_msec" : 7743,
"end_msec" : 10322
} ],
"chapters" : [ {
"id" : 7534,
"text" : "My first chapter!",
"start_msec" : 1232,
"end_msec" : 29384
} ],
"slide_deck" : 553
}
{id}
Updates select properties of the Media object
Path variables
Request body
Any property/properties of the media object are allowed here
Responses
Examples
PATCH https://tenant.kzoplatform.com/api/v2/media/234 HTTP/1.1
Content-Type: application/json
{
"complete" : true
}
{id}
/videoUploading can only be accomplished on a video marked as completed
: false
. Newly created Media objects completed property are false by default.
Once uploading is complete, do not forget to set the completed
status to true
. This informs the Media pipeline that there is work to perform.
Path variables
the media ID
Request body
Post file contents of the video directly as a multi-part form-data post.
Responses
Methods relating to the player. These are generally very similar to the Media
methods, with the exception that the data returned is formatted for easy display
{containerid}
{containerid}
Path variables
Responses
Body
Examples
POST https://tenant.kzoplatform.com/api/v2/users HTTP/1.1
Content-Type: application/json
{
"username" : "admin",
"password" : "password",
"email" : "admin@example.org",
"avatar_url" : "https://tenant.kzoplatform.com/files/avatar/5542"
}
HTTP/1.1 201 Created
Content-Type: application/json
{
"id" : 5542,
"username" : "admin",
"email" : "admin@example.org",
"avatar_url" : "https://tenant.kzoplatform.com/files/avatar/5542"
}
Examples
PATCH https://tenant.kzoplatform.com/api/v2/users/5543 HTTP/1.1
Content-Type: application/json
{
"email" : "administrator@example.org"
}
Request parameters
Where to search (e.g. closed_captions, slides, media, chapters, everything). By default searches everything
Responses
Body
Examples
GET https://tenant.kzoplatform.com/api/v2/search?q=awesome&page=1&domain=chapters,comments HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"count" : 19,
"page" : 1,
"query" : "awesome",
"domain": ["chapters", "comments"],
"items" : [ {
"media" : {
"id" : 234,
"container_id" : 12,
"title" : "Baby's first video!",
"description" : "A lovely description for your new video.",
"upload_url" : "https://tenant.kzoplatform.com/files/video/4436",
"complete" : false,
"thumbnails" : [ {
"id" : 8238,
"msec" : 5000,
"md5" : "9729bfefe48c6c088f0ffa2cea05edf5",
"href" : "https://tenant.kzoplatform.com/files/thumbnails/234223.jpg",
"size" : "34938",
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1,
"deleted_at" : "2012-10-10T16:34:23.871Z",
"deleted_by" : 1
} ],
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
},
"comments" : [ {
"id" : 1,
"media_id" : 1,
"parent_id" : null,
"text" : "This video is great!",
"msec" : "5500",
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
} ],
"chapters" : [ {
"id" : 7534,
"text" : "My first chapter!",
"msec" : 1232,
"created_at" : "2012-10-10T14:12:24.324Z",
"created_by" : 1,
"modified_at" : "2012-10-10T14:12:24.324Z",
"modified_by" : 1
} ],
"closed_captions" : [ {
"id" : 38583,
"language" : "en",
"text" : "I'm a chapter title!",
"start_msec" : 7743,
"end_msec" : 10322
} ],
"slide" : [ {
"id" : 8563,
"page_number" : 3,
"text" : "slide text here"
} ]
} ]
}
This method differs from the regular search in that it allows the requester to perform a search as another user. This can be problematic as it is slow to create new session tokens for each request, and the application will not know the users’s password to create that token.
This method requires the DELEGATE_SEARCH
permission
Request parameters
Where to search (e.g. closed_captions, slides, media, chapters, everything). By default searches everything
Username to perform the search as
Responses
Body
{id}
{id}
{id}
{id}
/members/{username}
Examples
GET https://tenant.kzoplatform.com/api/v2/groups/48 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"id" : 48,
"name" : "Marketing",
"members" : [ {
"id" : 5542,
"username" : "admin",
"password" : null,
"email" : "admin@example.org",
"avatar_url" : "https://tenant.kzoplatform.com/files/avatar/5542"
} ]
}
Examples
POST https://tenant.kzoplatform.com/api/v2/groups HTTP/1.1
Content-Type: application/json
{
"name" : "Marketing"
}
HTTP/1.1 201 Created
Content-Type: application/json
{
"id" : 48,
"name" : "Marketing",
"members": []
}
{id}
Currently accepting both PUT and PATCH as there is only one field to update
Path variables
Request body
Responses
Examples
PUT https://tenant.kzoplatform.com/api/v2/groups/48 HTTP/1.1
Content-Type: application/json
{
"name" : "Marketing People"
}
Roles are a collection of abilities grouped together in some logical way. For example, there could be a role called “Subject Matter Expert”, which would have abilities like CREATE_CONTENT
and EDIT_CONTENT
, but would not include abilities like MANAGE_USERS
.
Roles are used in conjunction with Groups and Containers to create permissions. These permissions are managed with the /containers/:id/permissions method.
Not implemented in v5.0
Instead, several pre-created roles will be offered.
Request body
The name of the role
Responses
Body
Responses
Body
Examples
GET https://tenant.kzoplatform.com/api/v2/roles HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
[ {
"id" : 12,
"name" : "admin",
"abilities" : [ "EVERYTHING" ]
} ]
The media object represents a single video. All other entities (such as closed captions, thumbnails, etc) belong to this
The URL used for uploading video or audio
Whether the video has completed uploading
start time of the caption in milliseconds
end time of the caption in milliseconds
in kbps
Chapter title
Start time in milliseconds
Auto-generated
Auto-generated. Whether or not this is the root of the container tree
Auto-generated
Whether or not this container should be visible and displayed to the end user. This is helpful when using containers for organization
The name of the container. Only needed if visible
is set to true
The “playlist” of the container. Displays an ordered list of videos and other containers
Optional description for the container
defines the order and various properties of the container
Either a child_container_id must be supplied OR a media_id, not both.
Either a child_container_id must be supplied OR a media_id, not both.
enum(‘original’, ‘view-only’, ‘admin’) needs work
Abstraction used by playlist model to represent either a container or media object
A mapping between roles, groups, and containers
CREATE CONTENT
total number of matches
everything, slides, closed_captions, comments
All comments belonging to the media
that match the search query
All chapters belonging to the media
that match the search query
All closed captions belonging to the media
that match the search query
All slides belonging to the media
that match the search query
Individual slide that belongs to a slide_deck
What page in the slide deck this represents
The text contained on the slide