Body worn integration API


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.


BWMBody worn manager
BWSBody worn system
CDContent destination


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:

Connection APISetup the connection to the content destination.
Capability APIPublish supported capabilities from a content destination to a JSON file.
Device and user APIManage devices and users.
File upload APIFile transfer.
Access token APIUpload 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 operationEndpointDescriptionNormal responsesError responses
Get/auth/v1.0Retrieves an auth token.200 OK401 Unauthorized
Get/v1/{account}/System/{object}(1)Retrieves an object and metadata.
Put/v1/{account}/{container}Creates a container 201 Created, 202 Accepted400 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 Content400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error
Put/v1/{account}/{container}/{object}Creates an object201 Created400 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 Accepted400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error
  1. Put and Post is also done on this endpoint, but covered by their respective patterns further down in the table.

Error response descriptions

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:

  • the timestamp is out of bounds

  • the clip has no duration

  • a user id or device id doesn’t exist

401 UnauthorizedShould be returned by content destination integration when user credentials are invalid or auth token missing
402 PaymentRequiredReturned when attempting to create a body worn camera or user in content destination but there are no more licenses.
403 ForbiddenReturned when user permissions are insufficient for a specific resource
500 InternalServerErrorAny other error
503 ServiceUnavailableReturned 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 InsufficientStorageReturned 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.

JSON file format
  "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

HTTPSCertificateMakes 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.
WantEncryptionDefault value is false.
PublicKeyRequired if WantEncryption is set.
PublicKeyIdRequired if WantEncryption is set.
ContainerTypeDefault value is mkv (optional).
FullStoreAndReadSupportDefault 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:

JSON file 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 called Users/. 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 called Devices/. 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.


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>.

BWCSerialNumberStringThe serial number of the device that captures the video in the container.
SCUSerialNumberStringThe serial number of the device that received the recording from the BWC.
FirmwareVersionStringThe firmware version of the BWC for when the video was recorded.
UserIDStringThe user that was assigned to the device when the video was recorded.
TriggerOnStringWhy the camera started a recording.
TriggerOffStringWhy the camera stopped a recording.
TriggerOnTimeEpoch (String in the UTC)The time when the trigger was issued.
TriggerOnTimeISOStringThe time when the trigger was issued in the ISO8601–format (UTC).
TriggerOnLocationString [64]<lat><long><accuracy><epoch>
TriggerOffTimeEpoch (String in the UTC)The time when the recording was stopped.
TriggerOffTimeISOStringThe time when the recording was stopped in the ISO8601–format (UTC).
TriggerOffLocationString [64]<lat><long><accuracy><epoch>
BWCModelStringThe BWC model that was used when recording.
StatusStringTransferring|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.

CategoryIDStringThe category ID.
CategoryNameStringThe string for this category.
TagsStringA semicolon separated string of tags.
StartTimeStringTimestamp for the description in RFC3339 (UTC). If not set by the user, it will start at the beginning of the recording.
EndTimeStringTimestamp 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>

StartTimeStringThe time when the clip was created.
StartTimeISOStringThe time when the clip was created in the ISO8601–format (UTC)
StopTimeStringThe time when the clip is finished.
StopTimeISOStringThe time when the clip was finished in the<RFC3339 string> format (UTC).
ContainerTypeStringThe 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.

ConnectionIdString [100]The connection ID for this system.
SystemNameString [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

NameString [100]Nice name of the user, is not unique
UserIDString [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>

NameString [100]The nice name of the device.
ModelStringDevice model (e.g. W100)