This API exposes a small sub-set of Edit Board's functionality. Principally it allows you to do the following actions programmatically:
All the urls in this API documented here are relative to this base url:
https://editboard.app/api/v1
Requests to and responses from this API are formatted as json.
These are the available API endpoints:
POST /login - Authentication
GET /organisations - List your organisations
GET /organisations/<organisation-id> - Get an organisation
GET /organisations/<organisation-id>/collections - List collections
POST /organisations/<organisation-id>/collections - New collection
GET /collections/<collection-id> - Get a collection
POST /collections/<collection-id>/uploads - Upload a video file
GET /collections/<collection-id>/nodes - List a collection's nodes
POST /collections/<collection-id>/nodes - Create a new directory node
POST /collections/<collection-id>/nodes - Create a new video node
POST /collections/<collection-id>/annotations - Add an annotation
GET /nodes/<node-id> - Get a node
GET /tasks/<task-id> - Get a task
If you have suggestions for extending the API please let us know what you would like to do.
To use this API you need to first generate an API key. You can do this on your home page.
Login to the API using your email address and this API key with basic auth. The response will contain an access token and when the token will expire.
POST /login
example response:
{ "expires": "21-06-07T15:50:07", "token": "l76c39u5w3ixjvsfegpr5mpbb7l3ip1vhce6ymr2jvezgzxlei" }
Use this access token to call the other endpoints in the API by giving it as a bearer token in the Authorization header, like this:
Authorization: Bearer l76c39u5w3ixjvsfegpr5mpbb7l3ip1vhce6ymr2jvezgzxlei
Once this token has expired using it will cause a 401 error and you will have to login again to create a new one. You do not have to wait for the token to expire and can create new ones as often as you like.
This will return a list of the organisations that you are a member of.
GET /organisations
example response:
{ "organisations": [ { "id": "organisation_569732aa-54e1-431a-b025-9c8e792b4c10", "name": "glowinthedark" }, { "id": "organisation_7c33e66c-0c6a-470d-8a04-d306d512cd97", "name": "Another Organisation" } ] }
This will return the details of a single organisation.
GET /organisations/<organisation-id>
example response:
{ "organisations": [ { "id": "organisation_569732aa-54e1-431a-b025-9c8e792b4c10", "name": "glowinthedark" } ] }
This will return a list of the organisation's collections that you are a member of.
GET /organisations/<organisation-id>/collections
example response:
{ "collections": [ { "id": "collection_2B1FC2F7-8B8B-4B13-A59D-D1C735BEDC04, "name": "collection one", "organisation-id": "organisation_569732aa-54e1-431a-b025-9c8e792b4c10" }, { "id": "collection_840A3A66-EC8F-4FF2-BAE7-39312195F970, "name": "collection two", "organisation-id": "organisation_569732aa-54e1-431a-b025-9c8e792b4c10" }, ] }
This will create a new collection in the given organisation, you must provide the name of the new collection.
POST /organisations/<organisation-id>/collections
params:
example request:
{ "name": "A new collection" }
example response:
{ "collections": [ { "id": "collection_72d8bcb4-8745-4d9f-9697-d3783b051ed7", "name": "A new collection", "organisation-id": "organisation_569732aa-54e1-431a-b025-9c8e792b4c10" } ], "message": "Collection created successfully" }
This will return the details of a single collection.
GET /collections/<collection-id>
example response:
{ "collections": [ { "id": "collection_72d8bcb4-8745-4d9f-9697-d3783b051ed7", "name": "A collection", "organisation-id": "organisation_569732aa-54e1-431a-b025-9c8e792b4c10" } ], }
This will generate an authenticated upload url that you can use to upload a file:
POST /collections/<collection-id>/uploads
params:
To upload a file you must first use this endpoint to get an authenticated upload url. The response will contain both the url and an "upload-id" that can be used, once you have sucessfully upload the file, with the endpoint below to add video to a collection.
We are using google's cloud storage for these uploads so we will give you back a url which will allow you to upload your file to a cloud storage bucket. This upload is resumable, which is useful if you have any interuptions when uploading a large file. You can read the docs on google's resumable file upload:
example request:
{ "file-name": "test_video.m4v", "length": 45673834 }
example response:
{ "message": "Upload your file to this url", "uploads": [ { "id": "72d8bcb4-8745-4d9f-9697-d3783b051ed7/test_video.m4v", "url": "https://www.googleapis.com/upload/storage/v1/b/....." } ] }
This will return a list of the collection's nodes, this is a tree like structure made up of directories, videos, images and text:
GET /collections/<collection-id>/nodes
example response:
{ "nodes": [ { "id": "node_9938bcb4-8745-4d9f-9697-d3783b036492", "name": "A collection", "node-type": "dir", "parent-id": None, "collection-id": "collection_72d8bcb4-8745-4d9f-9697-d3783b051ed7" }, { "id": "node_9938bcb4-8745-4d9f-9697-d3783b036555", "name": "video one", "node-type": "video", "parent-id": "node_9938bcb4-8745-4d9f-9697-d3783b036492", "collection-id": "collection_72d8bcb4-8745-4d9f-9697-d3783b051ed7" } ] }
This will create a new directory node in the collection.
POST /collections/<collection-id>/nodes
params:
You can give either the full path of the new directory in the collection. This will automatically create any intermediate directory nodes that don't already exist. (Node names, and hence paths, are not unique, unlike directory names in a file system, ie running this request twice would create two sibling folders both called two):
request:
{ "node-type": "dir", "path": "one/two" }
Or you can give the parent node-id and a name for the new node:
request:
{ "node-type": "dir", "parent-id": "node_9938bcb4-8745-4d9f-9697-d3783b036492", "name": "one" }
example response:
{ "message": "Node created successfully", "nodes": [ { "id": "node_9938bcb4-8745-4d9f-9697-d3783b036555", "name": "one", "node-type": "dir", "parent-id": "node_9938bcb4-8745-4d9f-9697-d3783b036492", "collection-id": "collection_72d8bcb4-8745-4d9f-9697-d3783b051ed7" } ] }
This will add the video that you supply to the collection:
POST /collections/<collection-id>/nodes
params:
Like the directory node above, the location of the video in the collection can either be given with a full path or the parent node's id and a name.
"url" and "upload-id" are alternative ways of sending the video file itself. The file can either be uploaded first using the uploads endpoint in this api, in which case you must give the upload-id, or you can supply a url from which the file can be downloaded directly.
If uploading proxy video directly you must tell us by setting proxy to true, so that we don't bother transcoding it again. These video proxies should be 1080p h264 with a short gop of 12 frames.
We will read the creation time from the video's metadata to determine the time of day of the start of the video, you can override this by setting start directly here as a timestamp.
The response will contain both the details of the newly created node and those of an ingest task that will run in the background to analyse and transcode the video file and add it to the node. You can check the status of this task using the tasks endpoint below.
example requests:
{ "node-type": "video", "path": "video one", "upload-id": "876tyf5wuietjdg54a8b6osliys6vk5cd47vrb6" }
or:
{ "node-type": "video", "parent-id": "node_9938bcb4-8745-4d9f-9697-d3783b036492", "name": "video one", "url": "https://example.com/a/file/download/url" }
example response:
{ "message": "Node and video ingest task created", "nodes": [ { "collection-id": "collection_72d8bcb4-8745-4d9f-9697-d3783b051ed7", "id": "node_9938bcb4-8745-4d9f-9697-d3783b036555", "name": "video one", "media-id": "video_3336bcb4-8745-4d9f-9697-d3783b036492", "node-type": "waiting", "parent-id": "node_9938bcb4-8745-4d9f-9697-d3783b036492" } ], "tasks": [ { "collection-id": "collection_72d8bcb4-8745-4d9f-9697-d3783b051ed7", "id": "task_65756745-8745-4d9f-9697-d3783b051ed7", "name": "ingest", "status": "queued" } ] }
This lets you add a text comment to a collection at a particular time:
POST /collections/<collection-id>/annotations
params:
This adds a text annotation and/or a set of tags to the collection given. All annotation must have a start and duration and refer to a portion of the video.
example request:
{ "media-id": video_3336bcb4-8745-4d9f-9697-d3783b036492, "text": "test message", "tags": "one, two, three", "start": 24, "duration": 10 }
example response:
{ "annotations": [ { "author-id": "person_569732aa-54e1-431a-b025-9c8e792b4c10", "created": "21-04-30T12:00:00", "duration": "10:1:1", "start": "24:1:1", "media-id": "video_3336bcb4-8745-4d9f-9697-d3783b036492", "tags": ["one", "two", "three"], "text": "test message" } ], "message": "Annotation added sucessfully" }
You can also add several annotations at the same time by providing a list of them like this:
{ "annotations": [ { "media-id": video_3336bcb4-8745-4d9f-9697-d3783b036492, "text": "test message", "tags": "one, two, three", "start": 24, "duration": 10 }, { "media-id": video_3336bcb4-8745-4d9f-9697-d3783b036492, "text": "another message", "tags": "four, two", "start": 56, "duration": 20 } ] }
Which will return something like this:
{ "annotations": [ { "author-id": "person_569732aa-54e1-431a-b025-9c8e792b4c10", "created": "21-04-30T12:00:00", "duration": "10:1:1", "start": "24:1:1", "media-id": "video_3336bcb4-8745-4d9f-9697-d3783b036492", "tags": ["one", "two", "three"], "text": "test message" }, { "author-id": "person_569732aa-54e1-431a-b025-9c8e792b4c10", "created": "21-04-30T12:00:00", "duration": "20:1:1", "start": "56:1:1", "media-id": "video_3336bcb4-8745-4d9f-9697-d3783b036492", "tags": ["four", "two"], "text": "another message" } ], "message": "Annotation added sucessfully" }
This will return the details of a single node:
GET /nodes/<node-id>
example response:
{ "nodes": [ { "id": "node_9938bcb4-8745-4d9f-9697-d3783b036555", "name": "video one", "node-type": "video", "parent-id": "node_9938bcb4-8745-4d9f-9697-d3783b036492", "collection-id": "collection_72d8bcb4-8745-4d9f-9697-d3783b051ed7" } ] }
This will return the details of a single task:
GET /tasks/<task-id>
example response:
{ "tasks": [ { "collection-id": "collection_72d8bcb4-8745-4d9f-9697-d3783b051ed7", "id": "task_65756745-8745-4d9f-9697-d3783b051ed7", "name": "ingest", "status": "queued" } ] }