Data model
The body worn content destination API uses the OpenStack Swift addressing model with three levels: Account, Container, and Object.
For the full specification, see github.com/AxisCommunications/body-worn-content-destination-api.
Container and object structure
Account
├── System/
│ ├── <bwsid> (system object, if StoreReadSystemID)
│ ├── Capabilities.json (capability declarations)
│ └── Categories.json (category list, if ReadCategories)
├── Users/
│ └── <userid> (one object per registered user)
├── Devices/
│ └── <deviceid> (one object per registered BWC)
└── <UserID>_<BWCSerialNumber>_<TriggerOnTime>/ (recording container)
├── <StartTime>_<RecordingID>.<ContainerType> (video clip)
├── <StartTime>_<RecordingID>.key (encryption key, if encrypted)
├── bookmark_<Timestamp>_<ID> (bookmark, if StoreBookmarks)
└── <date>_<time>_<id>_<bwcid>_gpstrail.json (GNSS trail, if StoreGNSSTrackRecording)
Connection file
The connection file is a JSON file created by the content destination and imported into AXIS Body Worn Manager. Maximum size: 64 kB.
{
"ConnectionFileVersion": "1.0",
"SiteName": "<string:64>",
"ApplicationName": "<string:256>",
"ApplicationVersion": "<version-string:128>",
"ContentDestinationAsNTPServer": false,
"AuthenticationTokenURI": ["<URI:512>"],
"HTTPSCertificate": ["<Base64 encoded X509 Certificate:16k>"],
"BlobAPIKey": "<Password:64>",
"BlobAPIUserName": "<UserName:64>",
"ContainerType": "<mkv | mp4>",
"FullStoreAndReadSupport": false,
"WantEncryption": false,
"PublicKey": "<Base64 encoded PEM RSA PublicKey:2048>",
"PublicKeyId": "<string:128>"
}
Connection file attributes
| Attribute | Required at setup | Modifiable | Notes |
|---|---|---|---|
| ConnectionFileVersion | Yes | ||
| SiteName | Yes | ||
| ApplicationName | Yes | ||
| ApplicationVersion | Yes | ||
| ContentDestinationAsNTPServer | Yes | ||
| AuthenticationTokenURI | Yes | ||
| HTTPSCertificate | Yes | Yes | Enables HTTPS. If validation fails, connection setup fails. Omit only during development. |
| BlobAPIKey | Yes | ||
| BlobAPIUserName | Yes | ||
| ContainerType | Yes | Default: mkv. Optional. | |
| FullStoreAndReadSupport | Yes | Default: false. Can only change from false to true. | |
| WantEncryption | Yes | Default: false. Can only change from false to true. | |
| PublicKey | Yes | Required when WantEncryption is true. | |
| PublicKeyId | Yes | Required when WantEncryption is true. |
Recording container metadata
Container name format: <UserID>_<BWCSerialNumber>_<TriggerOnTime> (TriggerOnTime in UTC, format YYYYMMDDTHHMMSSZ).
All metadata is sent as HTTP headers with prefix X-Container-Meta-. Values are URL-encoded UTF-8. String attributes are limited to 32 bytes unless noted.
| Key | Type | Description |
|---|---|---|
| ContainerName | String | The container name |
| BWCSerialNumber | String | Serial number of the recording camera |
| SCUSerialNumber | String | Serial number of the system controller |
| FirmwareVersion | String | BWC firmware version at recording time |
| UserID | String | UUID of the user assigned to the camera |
| TriggerOn | String | Why the recording started |
| TriggerOff | String | Why the recording stopped |
| TriggerOnTime | String | Trigger time, epoch UTC |
| TriggerOnTimeISO | String | Trigger time, RFC 3339 (UTC) |
| TriggerOnLocation | String (64) | <lat><long><accuracy><epoch> |
| TriggerOffTime | String | Stop trigger time, epoch UTC |
| TriggerOffTimeISO | String | Stop trigger time, RFC 3339 (UTC) |
| TriggerOffLocation | String (64) | <lat><long><accuracy><epoch> |
| StartTime | String | Recording start (includes pre-buffer), epoch UTC |
| StartTimeISO | String | Recording start, RFC 3339 (UTC) |
| StopTime | String | Recording stop (includes post-buffer), epoch UTC |
| StopTimeISO | String | Recording stop, RFC 3339 (UTC) |
| TimeZone | String | IANA time zone of the BWC at recording time |
| BWCModel | String | Camera model (for example, W102) |
| Status | String | Transferring or Complete — no more updates after Complete |
Video object metadata
Object name format: <StartTime>_<RecordingID>.<ContainerType>
Headers use prefix X-Object-Meta-.
| Key | Type | Description |
|---|---|---|
| StartTime | String | Clip start time, epoch UTC |
| StartTimeISO | String | Clip start time, RFC 3339 (UTC) |
| StopTime | String | Clip end time, epoch UTC |
| StopTimeISO | String | Clip end time, RFC 3339 (UTC) |
| ContainerType | String | File type (mkv or mp4) |
Key object metadata
Object name format: <StartTime>_<RecordingID>.key
| Key | Type | Description |
|---|---|---|
| StartTime | String | Start time of the encrypted clip (or recording start for encrypted location data) |
| FileType | String | Always key |
Bookmark object metadata
Object name format: bookmark_<Timestamp>_<ID> (stored only if StoreBookmarks capability is set).
The object content is a free-text description in UTF-8. An empty bookmark with only a timestamp serves as a time marker.
| Key | Type | Description |
|---|---|---|
| CategoryID | String | Category identifier |
| CategoryName | String | Category display name |
| Tags | String | Semicolon-separated key:value pairs |
| StartTime | String | Bookmark time, RFC 3339 (UTC). Defaults to recording start if unset. |
| EndTime | String | End time, RFC 3339 (UTC). Absent if not set by user. |
| Location | String (64) | Location at bookmark time |
Location object metadata
Object name format: <date>_<time>_<RecordingID>_<bwcid>_gpstrail.json (stored only if StoreGNSSTrackRecording capability is set).
| Key | Type | Description |
|---|---|---|
| FileType | String | Always json |
See Capabilities — StoreGNSSTrackRecording for the JSON file format.
User object metadata
Container: Users/. Object name: <UserUUID>.
| Key | Type | Description |
|---|---|---|
| Active | String | True or False |
| Name | String (100) | Display name (not unique) |
| UserID | String (100) | User-supplied ID (empty or unique). Only stored if StoreUserIDKey capability is set. |
Name is not unique. Display as Name (UserID) to disambiguate users.
Device object metadata
Container: Devices/. Object name: <BWCSerialNumber>.
| Key | Type | Description |
|---|---|---|
| Active | String | True or False |
| Name | String (100) | Display name |
| Model | String | Device model (for example, W100) |
Object encryption
Encrypt
Set WantEncryption to true and provide PublicKey and PublicKeyId in the connection file.
- The corresponding private key is required for decryption.
PublicKeyIdis written to the key object so the CD knows which key to use.- Once encryption is enabled, it cannot be turned off.
Decrypt
When encryption is enabled, each content object is accompanied by a .key file. The key file contains an EncryptedKey attribute holding the content encryption key wrapped with the public key.
See the example server documentation for decryption details.
String encoding
All user-supplied strings are URL-encoded UTF-8 and can include any character except control characters. Content destinations should accept the full UTF-8 set but may translate characters in their UI if needed.