Body worn integration API
Description
The Body worn integration API makes it possible to integrate a third-party application as a content destination (CD) to the Body worn system (BWS). The application that implements the API will operate as the server, while the BWS will be the client that calls the API. The API itself is HTTPS-based and communication with the application is protected by certificates, which needs to be configured before the API can be used.
Terminology
Term | Description |
BWM | Body worn manager |
BWS | Body worn system |
CD | Content destination |
Overview
The API is modelled on top of the OpenStack Swift API, an open source S3–like object store API.
The Swift API implements 3 levels that can be used for addressing: Account
, Container
and Object
, the last one being a path with multiple slashes, while the account level corresponds to the login specified by a BlobAPIKey
and BlobAPIUserName
in the connection file.
Each Recording
from the BWS will create a corresponding Container
, which can be compared to a folder or directory on a computer and each Clip
in a Recording
will create an Object
in the Container
with the video as its content.
A Recording
consists of:
a list of N video files,
N > 0
.
Each file in the Recording
corresponds to an Object
in the Container
.
The Body worn Integration API is divided into the following parts:
API | Usage |
Connection API | Setup the connection to the content destination. |
Capability API | Publish supported capabilities from a content destination to a JSON file. |
Device and user API | Manage devices and users. |
File upload API | File transfer. |
Access token API | Upload URI and credentials. |
API endpoints
The following table catalogue the available endpoints. All except for the auth endpoint requires a valid auth token, while the auth endpoint itself requires both a username and key. This is the subset essential for 3rd party implementations. Everything else such as how to delete and copy objects or containers is not going to be used from the body worn system.
All user supplied strings are URL encoded utf-8 and can include any character except for control characters. Servers are expected to accept this, but may translate characters in their UI if they don’t support the full utf-8 set.
HTTPS operation | Endpoint | Description | Normal responses | Error responses |
---|---|---|---|---|
Get | /auth/v1.0 | Retrieves an auth token. | 200 OK | 401 Unauthorized |
Get | /v1/{account}/System/{object} (1) | Retrieves an object and metadata. | ||
Put | /v1/{account}/{container} | Creates a container | 201 Created , 202 Accepted | 400 Bad Request , 401 Unauthorized , 404 Not Found , 500 Internal Server Error |
Post | /v1/{account}/{container} | Creates or updates the container metadata, which also deletes the existing metadata. | 204 No Content | 400 Bad Request , 401 Unauthorized , 404 Not Found , 500 Internal Server Error |
Put | /v1/{account}/{container}/{object} | Creates an object | 201 Created | 400 Bad Request , 401 Unauthorized , 404 Not Found , 422 Object Corrupted , 500 Internal Server Error , 507 Insufficient Storage |
Post | /v1/{account}/{container}/{object} | Creates or updates the object metadata, which also deletes the existing metadata. | 202 Accepted | 400 Bad Request , 401 Unauthorized , 404 Not Found , 500 Internal Server Error |
- Put and Post is also done on this endpoint, but covered by their respective patterns further down in the table.
Error response descriptions
Code | Description |
---|---|
400 BadRequest | Returned when the content destination can’t store (and never will be able to store) the recording. It gets status Recording not transferred in AXIS Body Worn Manager, and becomes available for download. Can be used when:
|
401 Unauthorized | Should be returned by content destination integration when user credentials are invalid or auth token missing |
402 PaymentRequired | Returned when attempting to create a body worn camera or user in content destination but there are no more licenses. |
403 Forbidden | Returned when user permissions are insufficient for a specific resource |
500 InternalServerError | Any other error |
503 ServiceUnavailable | Returned when the content destination is busy and receives too many upload requests from the system controller, but wants the system controller to try again soon. |
507 InsufficientStorage | Returned when content destination is out of disk space/disk quota. |
Set up a connection to the content destination
In order to set up a connection, as well as the Body worn system, a JSON connection file needs to be created for the Body worn manager (BWM), which is the web based management application for the BWS. The connection file should contain all configurations that are required to connect to the content destination, including installation-specific settings such as encryption and the supported container format for the content destination.
Every application that implements the Body worn integration API must be able to provide this file, but it can also be made from the ground up.
Please note that when a system is configured for the first time, it must also be assigned a System ID. This ID is stored on the BWS and set on the content destination. It also makes it possible to check that the system is communicating with the expected endpoint.
Setup procedure
The connection file is a JSON file with attribute names, value types and lengths, as shown in the template below. The maximum size of a connection file should always be smaller than 64 kB.
{
"ConnectionFileVersion": "1.0",
"SiteName": "<string:64>",
"ApplicationName": "<string:256>",
"ApplicationVersion": "<version-string:64>",
"ContentDestinationAsNTPServer": <bool>,
"AuthenticationTokenURI": [ "<URI:512>", "<URI:512>", ... x 10 ],
"HTTPSCertificate": [ "<Base64 encoded X509 Certificate:16k>", "<Base64 encoded X509 Certificate:16k>", ... x 10 ],
"BlobAPIKey": "<Password:64>",
"BlobAPIUserName": "<UserName:64>",
"ContainerType": "<mkv | mp4>",
"FullStoreAndReadSupport": <bool>,
"WantEncryption": <bool>,
"PublicKey": "<Base64 encoded PEM RSA PublicKey:2048>",
"PublicKeyId": "<string:128>"
}
Optional attributes
Parameter | Description |
HTTPSCertificate | Makes the SCU able to verify the server certificate of the CD and create a secure connection with HTTPS . If the certificate cannot be validated, the connection setup will fail and if no certificate have been set, HTTP will be used instead. |
WantEncryption | Default value is false . |
PublicKey | Required if WantEncryption is set. |
PublicKeyId | Required if WantEncryption is set. |
ContainerType | Default value is mkv (optional). |
FullStoreAndReadSupport | Default value is false (optional). |
Changeable attributes
The following attributes can be modified after the initial setup has been completed:
ConnectionFileVersion
SiteName
ApplicationName
ApplicationVersion
ContentDestinationAsNTPServer
AuthenticationTokenURI
HTTPSCertificate
BlobAPIKey
BlobAPIUserName
WantEncryption
PublicKey
PublicKeyId
Content destination capabilities
The Capability API makes it possible for a connected content destination to publish its supported features. The supported capabilities will be published in a JSON file named Capabilities.json , which will be located in the System/
container. To reach the file, the BWS will do a GET
request to System/Capabilities.json
.
File content
Please note that all capabilities are considered unsupported if the file is missing or wrongly formatted. This is also true if capability isn’t present or set to false
. The file is published in a standard JSON format:
{
"StoreAndRead": {
"<CAPABILITY1>": <bool>,
"<CAPABILITY2>": <bool>
}
}
Connection file
The connection file includes the attribute FullStoreAndReadSupport
, typically set for a standard swift content destination, and thus not requiring any configurations of the new capabilities, as they will appear when standard swift commands are supported. In cases where you want to limit what is stored on a swift server, don’t set the new attribute, just enable the capabilities you want to use.
Capability naming
Store
is used as prefix when either POST
or PUT
support is required, while Read
is used as prefix when either GET
and HEAD
support is required. In cases where both are required, they are added as a prefix, i.e. StoreRead
.
Current capabilities
StoreBookmarks
StoreReadSystemID
StoreUserIDKey
Implementation details
When responding to a request the Etag header, which contains the md5 hash of the JSON file, must be set, as it used as a checksum. A typical log error from the SCU if cases where the header is incorrect is “object corrupt”.
Manage devices and users
The Device and user API should be used once one of the following actions are taken by an admin:
When a user has been registered in the BWM. An object named with the
UserID
of the user will then be created in the container calledUsers/
. The nice name of the user will be stored as metadata on the object.When a user’s nice name is updated. The metadata for that user object will then be updated.
When a Body worn camera is registered in the BWM. An object named with the
BWCSerialNumber
of the Body worn camera will then be created in the container calledDevices/
. The nice name of the device will be stored as metadata on the object.When a Body worn camera’s nice name is updated. The metadata for that camera object will then be updated.
A recording will carry the essential information and map it to a UserID
and a BWCSerialNumber.
. If the information in the recording does not match existing users or devices a 400 Bad Request
error response will be returned.
File transfer
The File upload API is used when the Body worn system uploads a recording created in a Body worn camera. Doing this will create a corresponding recording container, which will get a name according to this template: <UserID>_<BWCSerialNumber>_<TriggerOnTime>.
.
A recording consists of a list of N
video files, where N > 0
.
Every clip in the recording corresponds to an object in the container, where the clips are named <StartTime>_<RecordingID>.<ContainerType>
. Please note that RecordingID
is a short, random number for the recording that shouldn’t be relied upon for identification purposes.
File metadata
The metadata in the Body worn integration API is sent as an HTTP header in the requests. All metadata is presented in strings, while time is specified in UTC. See the Metadata for further instructions.
File upload URI and credentials
The Access token API is used by the BWS to retrieve and use a token with the PUT
and POST
methods. Openstack swift has support for multiple auth systems, one of them being their own Keystone, which is the method that should be used in the Body worn integration API.
Swift security relies on auth tokens being passed with each request. A token is retrieved when the BWS send both an Auth-Key
and X-Auth-User
in the header of a GET
request to the BaseURL
, which is supplied by the JSON connection file. The content destination must then respond with an X-Auth-Token
and the X-Storage-Url
, which are then used during the upload.
Metadata
All metadata header keys will have the prefix X-Object-Meta
or X-Container-Meta
as X-<type>-Meta-Key
in the HTTP request. All characters will be lowercase except the first letter as well as any letter that follows a hyphen. The values are presented in the URL-encoded UTF8-format, where characters outside of US ASCII and reserved HTTP characters are %XX
encoded. Please note that string attributes can’t be larger than 32 bytes except when noted, such as the device name, user name and location attributes, which can be up to 64 bytes. Strings supplied by the user may include any character except control characters. Most applications are expected to accept this, but they may sometimes translate the characters in their individual user interface in cases where they don’t support the full utf-8 set.
Recording container
The name of the container is <UserID>_<BWCSerialNumber>_<TriggerOnTime>
.
Key | Type | Description |
BWCSerialNumber | String | The serial number of the device that captures the video in the container. |
SCUSerialNumber | String | The serial number of the device that received the recording from the BWC. |
FirmwareVersion | String | The firmware version of the BWC for when the video was recorded. |
UserID | String | The user that was assigned to the device when the video was recorded. |
TriggerOn | String | Why the camera started a recording. |
TriggerOff | String | Why the camera stopped a recording. |
TriggerOnTime | Epoch (String in the UTC) | The time when the trigger was issued. |
TriggerOnTimeISO | String | The time when the trigger was issued in the ISO8601–format (UTC). |
TriggerOnLocation | String [64] | <lat><long><accuracy><epoch> |
TriggerOffTime | Epoch (String in the UTC) | The time when the recording was stopped. |
TriggerOffTimeISO | String | The time when the recording was stopped in the ISO8601–format (UTC). |
TriggerOffLocation | String [64] | <lat><long><accuracy><epoch> |
BWCModel | String | The BWC model that was used when recording. |
Status | String | Transferring|Complete : The status of the Container. When the container metadata becomes Complete , there won’t be any more updates or uploads to either the container or metadata. |
Bookmark object metadata
The name of the object is bookmark_<Timestamp>_<ID>
.
This object is stored only if StoreBookmark
capability is set.
The content of the object is the free text description, in utf-8. As there is a timestamp, multiple descriptions can be added. This object can also work as a bookmark. Then the content and all metadata is empty, except for the timestamp.
Key | Type | Description |
CategoryID | String | The category ID. |
CategoryName | String | The string for this category. |
Tags | String | A semicolon separated string of tags. |
StartTime | String | Timestamp for the description in RFC3339 (UTC). If not set by the user, it will start at the beginning of the recording. |
EndTime | String | Timestamp for the description in RFC3339 (UTC). If not set by the user, it will start at the end of the recording. |
Video object metadata
The name of the object is <StartTime>_<RecordingID>.<ContainerType>
Key | Type | Description |
StartTime | String | The time when the clip was created. |
StartTimeISO | String | The time when the clip was created in the ISO8601–format (UTC) |
StopTime | String | The time when the clip is finished. |
StopTimeISO | String | The time when the clip was finished in the<RFC3339 string> format (UTC). |
ContainerType | String | The clips’ file type (.mkv, .mp4, etc.) |
System container metadata
The container name is System
.
This container is created if the StoreReadSystemID
capability is set.
System object metadata
Object name is <SystemID>
, a UUID.
This object is stored only if the StoreReadSystemID
capability is set.
Multiple system objects can exist if several discrete BWS are connected to the same content destination.
All data is stored by the body worn system. Only the SystemName
is intended for end user consumption, and can be updated at any time from the body worn system. The ConnectionID
is set when the object is created and will never change.
Key | Type | Description |
ConnectionId | String [100] | The connection ID for this system. |
SystemName | String [100] | The nice name of the body worn system installation. |
User container metadata
The container name is Users
.
User object metadata
Object name is <UserUUID>
, an internal UUID
Key | Type | Description |
Active | String | True /False |
Name | String [100] | Nice name of the user, is not unique |
UserID | String [100] | A user supplied ID, is empty or unique. Only stored if StoreUserIDKey capability is set. |
Name is not unique. We recommend that you display Name (UserID).
Devices container metadata
The container name is Devices
Device object metadata
Object name is <BWCSerialNumber>
Key | Type | Description |
Active | String | True /False |
Name | String [100] | The nice name of the device. |
Model | String | Device model (e.g. W100) |