Creating a Data Bundle
Before you upload capture data, you need an empty data bundle tied to a specific capture device. Creation is a two-step flow: fetch the data bundle device input tree, then create the bundle with the fully resolved dbuPath of the leaf device you selected. The input tree is returned in a single call; walk it locally (by name and children) until you reach a leaf. Leaf nodes carry the dbuPath string you pass at creation time; branch nodes have dbuPath: null.
Endpoints
Section titled “Endpoints”| Method | Path | Scope | Purpose |
|---|---|---|---|
GET | /v1/organization/{organizationId}/data-bundle-input-tree | read:bundle | Fetch the device input tree |
POST | /v1/nodes/{parentId}/bundle | write:bundle | Create a data bundle |
Step 1: fetch the input tree
Section titled “Step 1: fetch the input tree”GET {api_url}/v1/organization/{organizationId}/data-bundle-input-treeAuthorization: Bearer {access_token}The response is a nested tree. Each node includes:
| Field | Meaning |
|---|---|
name | Stable identifier used to build paths |
label | Human-readable display name |
isLeaf | true when the node is a selectable capture device |
dbuPath | Fully resolved device path on leaf nodes; null on branches |
children | Child nodes (empty array on leaves) |
Example (truncated):
{ "nodes": [ { "name": "POINTCLOUD", "label": "Point Cloud", "isLeaf": false, "dbuPath": null, "children": [ { "name": "ZF", "label": "ZF", "isLeaf": false, "dbuPath": null, "children": [ { "name": "ZFSLAM", "label": "ZF SLAM", "isLeaf": true, "dbuPath": "POINTCLOUD/ZF/ZFSLAM", "children": [] } ] } ] } ]}Walk the tree until isLeaf is true, then copy dbuPath (here POINTCLOUD/ZF/ZFSLAM).
Step 2: create the bundle
Section titled “Step 2: create the bundle”Create the bundle under a parent node you have permission on (typically a site or folder). Pass the bundle name and the leaf dbuPath from step 1.
POST {api_url}/v1/nodes/{parentId}/bundleAuthorization: Bearer {access_token}Content-Type: application/json
{ "name": "ZF capture 2026-06-01", "dbuPath": "POINTCLOUD/ZF/ZFSLAM" }{ "id": "a6f75b3c-f261-4b27-9a2a-9a6cc1234c53", "name": "ZF capture 2026-01-01", "dbuPath": "POINTCLOUD/ZF/ZFSLAM"}Use the returned id as bundleId for upload, processing, and download steps.
Error cases
Section titled “Error cases”| Status | Cause |
|---|---|
400 Bad Request | dbuPath is unknown, not a leaf, or not available |
403 Forbidden | No permission on the parent node, or no content access |
Full example
Section titled “Full example”import requests
API_URL = "https://<your-regional-api-url>"TOKEN = "<access_token>"ORG_ID = "<organization_id>"PARENT_ID = "<site-or-folder-id>"
headers = {"Authorization": f"Bearer {TOKEN}"}
tree = requests.get( f"{API_URL}/v1/organization/{ORG_ID}/data-bundle-input-tree", headers=headers,).json()
# Walk the tree to find the ZF SLAM leaf (your navigation logic may differ).def find_dbu_path(nodes, *path): node = nodes for segment in path: node = next(n for n in node if n["name"] == segment) node = node["children"] leaf = node[0] assert leaf["isLeaf"] return leaf["dbuPath"]
dbu_path = find_dbu_path(tree["nodes"], "POINTCLOUD", "ZF", "ZFSLAM")
bundle = requests.post( f"{API_URL}/v1/nodes/{PARENT_ID}/bundle", headers=headers, json={"name": "ZF capture 2026-01-01", "dbuPath": dbu_path},).json()
bundle_id = bundle["id"]print(f"Created bundle {bundle_id} for device {bundle['dbuPath']}")Next step
Section titled “Next step”With a bundleId in hand, continue to Uploading Data to a Data Bundle.