How to set up a content destination connection for the body worn system (BWS)
This guide covers the first task in any body worn integration: connecting a BWS to your content destination. You'll generate the connection file, implement the authentication endpoint, and publish your capabilities. Once this is done, the system controller can start pushing recordings to your application.
The full reference and example server are in the body worn content destination API repository. This guide covers the connection workflow and links there for the full attribute and capability reference.
Prerequisites
- A content destination server you control. It acts as the server; the BWS is the client.
- The ability to serve HTTPS with a certificate the system controller can validate. Use plain HTTP only for local development.
- Administrator access to AXIS Body Worn Manager to import the connection file.
- A basic understanding of the body worn content destination API, which is modeled on the OpenStack Swift object store API.
How the connection works
Your application receives recordings by implementing a small subset of the Swift API. Before any recording can transfer, three things have to be in place:
- A connection file that tells the BWS where and how to reach you.
- An authentication endpoint that issues tokens for upload requests.
- A capabilities file that declares which optional features you support.
Step 1: Generate the connection file
The connection file is a JSON document that holds every setting the BWS needs to reach your content destination. Your application must be able to produce this file, because an administrator uploads it into AXIS Body Worn Manager during setup.
{
"ConnectionFileVersion": "1.0",
"SiteName": "Evidence store - district 4",
"ApplicationName": "Acme Evidence Manager",
"ApplicationVersion": "3.2.0",
"ContentDestinationAsNTPServer": false,
"AuthenticationTokenURI": ["https://cd.example.com/auth/v1.0"],
"HTTPSCertificate": ["<Base64-encoded X.509 certificate>"],
"BlobAPIKey": "s3cr3tAPIk3y",
"BlobAPIUserName": "bwsintegration",
"ContainerType": "mkv",
"FullStoreAndReadSupport": false,
"WantEncryption": false
}
The example above is illustrative. To get started, focus on these key attributes:
| Attribute | Purpose |
|---|---|
AuthenticationTokenURI | Where the BWS requests an auth token. |
BlobAPIUserName and BlobAPIKey | The credentials the BWS presents to your auth endpoint. |
HTTPSCertificate | One or more Base64-encoded X.509 certificates so the system controller can validate your server and connect over HTTPS. If you omit it, the connection falls back to HTTP. Always set it in production. |
WantEncryption | Set to true to enable end-to-end encryption. |
For the full attribute reference, including every optional field, its data type, and which values you can change after setup, see the body worn content destination API README.
One behavior worth calling out: WantEncryption can only change from false to true, never back.
Encryption is a one-way door. Once a system enables encryption, it can't be disabled. A configuration that would turn encryption off is rejected.
Step 2: Implement the authentication endpoint
The BWS authenticates with a Swift Keystone-style flow. When it needs to upload, it sends a GET request to your AuthenticationTokenURI with the credentials from the connection file:
- curl
- HTTP
curl --request GET \
--anyauth \
--user "<username>:<password>" \
--http1.1 \
--header "X-Auth-User: bwsintegration" \
--header "Auth-Key: s3cr3tAPIk3y" \
http://cd.example.com/auth/v1.0
GET /auth/v1.0 HTTP/1.1
Host: cd.example.com
X-Auth-User: bwsintegration
Auth-Key: s3cr3tAPIk3y
Your server validates the credentials and responds with a token and the base storage URL:
HTTP/1.1 200 OK
X-Auth-Token: tk-9a4f2c8b1e3d
X-Storage-Url: https://cd.example.com/v1/AUTH_bwsintegration
The BWS includes X-Auth-Token in every PUT and POST request that follows. Validate the token on each request, and return 401 Unauthorized when it's missing or invalid.
This is the only endpoint that requires both a username and a key. Every other endpoint requires a valid token instead.
Step 3: Publish your capabilities
Your content destination advertises which optional features it supports by serving a Capabilities.json object in the System/ container. The BWS reads it with a GET request to System/Capabilities.json and adjusts its behavior to match.
{
"Read": {
"ReadCategories": true
},
"Store": {
"StoreReadSystemID": true,
"StoreBookmarks": true,
"StoreSignedVideo": false,
"StoreGNSSTrackRecording": true,
"StoreRejectedContent": true
}
}
Each field turns on one optional feature, such as reading recording categories, accepting bookmarks, or accepting GNSS location trails. Declare the ones your content destination supports and leave the rest out. For the full list of capabilities and what each one enables, see the body worn content destination API README.
Two rules matter when you serve this file:
- Set the
ETagheader to the MD5 hash of the JSON object. The system controller uses it as a checksum. If it's wrong, the controller logsobject corruptand treats the capability as unsupported. - A capability is permanent. Once you declare support, the BWS expects you to keep it. A missing or
falsecapability is treated as unsupported.
Step 4: Bind the system with a System ID
Enable StoreReadSystemID so the BWS can confirm it's always talking to the same content destination. When a system is configured for the first time, it's assigned a System ID that's stored both on the system and on your content destination. As long as the System ID matches, an administrator can change almost any other setting and the system still recognizes your destination.
Without a System ID, the system could be pointed at a different content destination, which opens the door to redirected evidence and robustness problems. This is why the capability is strongly advised for any production deployment.
Step 5: Import the connection file
Hand the generated connection file to an administrator, who imports it in AXIS Body Worn Manager during system setup. Once imported, the BWS is locked to your content destination. Switching to a different destination requires a full system reset, which is intentional: it stops evidence from being silently redirected.
After import, the BWS requests a token, reads your Capabilities.json, and begins uploading recordings as cameras dock. From here, see How to retrieve body worn recordings via the integration API to receive and download that content.
Verify the connection
After an administrator imports the file:
- Watch your auth endpoint for an incoming
GET /auth/v1.0. A successful token response confirms the credentials and URI are correct. - Confirm a
GET System/Capabilities.jsonrequest arrives and returns200 OKwith a correctETag. - Dock a camera and watch for container and object
PUTrequests as the first recording transfers.
If the connection setup fails immediately, the most common cause is a certificate the system controller can't validate. Re-check the HTTPSCertificate value. Use HTTP only in an isolated local development environment to isolate the problem.
Related resources
- How to retrieve body worn recordings via the integration API – receive, list, and download recordings once the connection is live.
- Axis body worn solution – how the system, system controller, and content destination fit together.
- Body worn content destination API specification and example server.