Connected Workers Locations
The Connected Workers Locations API lets you build the structured, table‑like location data sets your workers navigate — typically a functional‑location hierarchy. A location table models any set of places as rows, with your own columns.
- Location table — a table. Has a
name, akey, and rows. Can be nested into a hierarchy. - Column — a field definition on the table (name, key, data type, ordering, display behavior).
- Item — a row: an object mapping each column's
keyto its value ({ "tplnr": "FL-1001", "name": "Pump Station A" }). Rows belong to the table.
Workspace 7
└── Location table 15 "Functional Locations" (key: functional-locations)
├── Columns: TPLNR (key: tplnr, text, title) · Name (key: name, text)
└── Items (rows):
{ "id": 1001, "tplnr": "FL-1001", "name": "Pump Station A" }
{ "id": 1002, "tplnr": "FL-1002", "name": "Pump Station B" }
Locations are the entity worker features attach to — notes, forms, checklists, and flows are filed against a location row. Assets can link to a location, and tours/spaces can be tagged to one. See the Assets guide and the Lists guide for the other two CW table entities.
Base URL & auth
Every endpoint is scoped to a workspace and served under:
https://api.treedis.com/v2/api/workspaces/{workspaceId}/cw/locations
All endpoints require authentication (OAuth2 Bearer token or API key), and the caller must have access to the workspace. workspaceId is always a numeric ID. An API key is bound to a single workspace and can only address its own.
Keys — address tables and columns by id or slug
Tables and columns each have a key — a URL‑safe slug (lowercase, no spaces), generated automatically from the name on create (or passed). Keys are unique within their scope and never all‑numeric.
- Anywhere a path takes
{tableId}or{columnId}, pass either the numeric id or the key (e.g.…/cw/locations/functional-locations/columns/tplnr). A purely numeric value is an id; anything else is a key. - Rows reference columns by key — the property names in a row object are column keys.
- Items (rows) have no key — address them by their numeric
id.
Endpoints
Locations is a single per-workspace table. Unlike assets and lists (where you manage many tables), every workspace has exactly one Locations table, so there is no
GET /{tableId}— retrieve the table withGETon the collection.{tableId}in the sub-resource paths below always refers to that one table, addressable by its id or the keylocations.
| Method | Path (under /v2/api/workspaces/{workspaceId}/cw/locations) |
Purpose |
|---|---|---|
GET / POST |
`` (collection) | Get the Locations table / create a table |
POST |
/bulk |
Batch insert tables |
PUT / DELETE |
/{tableId} |
Update / delete the table |
POST |
/{tableId}/bulk |
Batch insert into a table (columns + rows) |
GET / POST |
/{tableId}/columns |
List columns / create a column |
GET / PUT / DELETE |
/{tableId}/columns/{columnId} |
Get / update / delete a column |
GET / POST |
/{tableId}/items |
List rows / insert a row |
GET / PUT / DELETE |
/{tableId}/items/{itemId} |
Get / update / delete a row |
POST |
/{tableId}/items/truncate |
Truncate items (delete all rows) |
List endpoints return shallow objects (no
columns/items); read the table'scolumnsanditemsfrom their sub-resource endpoints below.
Location tables
Create takes no table id — the id and key are assigned and returned.
GET/POST/v2/api/workspaces/{workspaceId}/cw/locationsPUT/DELETE/v2/api/workspaces/{workspaceId}/cw/locations/{tableId}
| Field | Type | Notes |
|---|---|---|
name |
string | Required. Table name. |
key |
string | URL‑safe slug. Auto‑generated from name if omitted; unique within the workspace; never all‑numeric. |
status |
active | inactive |
Required. |
parentId |
number | string | null | Parent table — id or key. Tables themselves can be nested into a hierarchy. |
curl -X POST "https://api.treedis.com/v2/api/workspaces/7/cw/locations" \
-H "Authorization: Bearer your-access-token" \
-H "Content-Type: application/json" \
-d '{ "name": "Functional Locations", "status": "active" }'
GET on the collection returns the single Locations table as a shallow object — read its columns from /{tableId}/columns and its items from /{tableId}/items:
{
"success": true,
"code": 200,
"message": "Success",
"data": [
{
"id": 15,
"key": "functional-locations",
"name": "Functional Locations",
"status": "active",
"parentId": null,
"itemsCount": 2
}
]
}
Columns
Define the fields of the table. Create takes no column id; the key is derived from the name (or pass your own, unique within the table).
GET/POST/v2/api/workspaces/{workspaceId}/cw/locations/{tableId}/columnsGET/PUT/DELETE…/columns/{columnId}
| Field | Type | Notes |
|---|---|---|
name |
string | Required. Column name — unique within the table. |
key |
string | URL‑safe slug; auto‑generated from name if omitted. Used as the property name in rows. |
type |
enum | Required. See the column types below. |
order |
number | Display order. |
isRequired |
boolean | Whether a value is required. |
settings |
object | Type‑specific settings (e.g. maxLength, pattern). |
status |
active | inactive |
Column status. |
isTitle |
boolean | Marks the column shown as the row's display title in the worker view (e.g. the human-readable name). Display only. |
isPrimaryKey |
boolean | Marks the table's primary key — the column whose value uniquely identifies a row across the workspace (e.g. a plant-prefixed TPLNR like R400-20-FL-1001). Used to address a row when filing a note by business key. |
isVisible |
boolean | Whether the column shows in the UI. |
Column types (type): text · number · date · checkbox · hierarchyParent (links a row to a parent row — used to build the location tree) · reference (links to another table/entity) · locationTag (ties the value to a tour location/tag) · space (a space/environment) · tagStatus (a status tag).
curl -X POST "https://api.treedis.com/v2/api/workspaces/7/cw/locations/functional-locations/columns" \
-H "Authorization: Bearer your-access-token" \
-H "Content-Type: application/json" \
-d '{ "name": "TPLNR", "type": "text", "isRequired": true, "status": "active", "isVisible": true }'
Hierarchy
Build a parent/child tree of location rows with a hierarchyParent column — its value on a row points at the parent row (by the parent's primary‑key value). Treedis rejects a parent assignment that would create a circular reference (400).
Items (rows)
An item is a row — an object mapping each column's key to its value. Responses add the row id. Rows belong to the table.
GET/POST/v2/api/workspaces/{workspaceId}/cw/locations/{tableId}/itemsGET/PUT/DELETE…/items/{itemId}
# insert a row
curl -X POST "https://api.treedis.com/v2/api/workspaces/7/cw/locations/functional-locations/items" \
-H "Authorization: Bearer your-access-token" \
-H "Content-Type: application/json" \
-d '{ "tplnr": "FL-1001", "name": "Pump Station A" }'
{
"success": true,
"code": 200,
"message": "Item created successfully",
"data": { "id": 1001, "tplnr": "FL-1001", "name": "Pump Station A" }
}
A PUT on …/items/{itemId} updates the row's values; send only the columns you want to change. List rows with ?filter[swerk]=R400-20, ?page / ?limit, and ?sortBy / ?sortOrder.
Batch insert
Columns are matched by name/key within their table — an existing column is reused, only a new name creates a new column. A key is optional on tables and columns (omit to auto‑generate from the name).
Batch insert into a table
POST /v2/api/workspaces/{workspaceId}/cw/locations/{tableId}/bulk — optionally define columns, then insert rows.
curl -X POST "https://api.treedis.com/v2/api/workspaces/7/cw/locations/functional-locations/bulk" \
-H "Authorization: Bearer your-access-token" \
-H "Content-Type: application/json" \
-d '{
"columns": [
{ "name": "TPLNR", "key": "tplnr", "type": "text" },
{ "name": "Name", "type": "text" }
],
"items": [
{ "tplnr": "FL-1001", "name": "Pump Station A" },
{ "tplnr": "FL-1002", "name": "Pump Station B" }
]
}'
Batch insert tables
POST /v2/api/workspaces/{workspaceId}/cw/locations/bulk — create multiple tables at once, each with its columns and rows. This is the call an integrator uses to push a whole functional‑location export in one request.
curl -X POST "https://api.treedis.com/v2/api/workspaces/7/cw/locations/bulk" \
-H "Authorization: Bearer your-access-token" \
-H "Content-Type: application/json" \
-d '{
"locations": [
{
"name": "Functional Locations", "key": "functional-locations", "status": "active",
"columns": [ { "name": "TPLNR", "key": "tplnr", "type": "text", "isPrimaryKey": true }, { "name": "Name", "type": "text" } ],
"items": [
{ "tplnr": "FL-1001", "name": "Pump Station A" },
{ "tplnr": "FL-1002", "name": "Pump Station B" }
]
}
]
}'
Each surface uses its own batch envelope key —
locationshere,assetsfor the Assets surface,listsfor the Lists surface.
Batch insert by type
One endpoint for every surface: if a single integration pushes to more than one surface, you can send everything in one call instead of fanning out across paths. POST /v2/api/workspaces/{workspaceId}/cw/bulk takes a tables array where each table carries its own type — location, asset, or list — alongside its columns and rows. One request can mix all three. It is equivalent to posting each table to its surface's own /bulk.
curl -X POST "https://api.treedis.com/v2/api/workspaces/7/cw/bulk" \
-H "Authorization: Bearer your-access-token" \
-H "Content-Type: application/json" \
-d '{
"tables": [
{
"type": "location",
"name": "Functional Locations", "key": "functional-locations", "status": "active",
"columns": [ { "name": "TPLNR", "key": "tplnr", "type": "text", "isPrimaryKey": true }, { "name": "Name", "type": "text" } ],
"items": [
{ "tplnr": "FL-1001", "name": "Pump Station A" },
{ "tplnr": "FL-1002", "name": "Pump Station B" }
]
},
{
"type": "asset",
"name": "Assets", "key": "assets", "status": "active",
"columns": [ { "name": "EQUNR", "key": "equnr", "type": "text", "isPrimaryKey": true }, { "name": "Name", "type": "text" } ],
"items": [
{ "equnr": "EQ-5001", "name": "Centrifugal Pump" }
]
},
{
"type": "list",
"name": "Priorities", "key": "priorities", "status": "active",
"columns": [ { "name": "PRIOK", "key": "priok", "type": "text", "isPrimaryKey": true }, { "name": "Name", "type": "text" } ],
"items": [
{ "priok": "1", "name": "Emergency" },
{ "priok": "2", "name": "High" }
]
}
]
}'
Each table is routed to its surface by its type, so you can create locations, assets, and lists together — or send a single table when that's all you need.
Filing notes against a location
Locations are the anchor for worker features. Create a note at the workspace and address the location by location — the location's primary‑key value (its name / code). Treedis finds that location row and files the note against it. Optionally link an asset with assetKey (the asset table) + asset (that asset row's primary‑key value). The note is sent as application/json; attachments go under files as base64 objects.
curl -X POST "https://api.treedis.com/v2/api/workspaces/7/notes" \
-H "Authorization: Bearer your-access-token" \
-H "Content-Type: application/json" \
-d '{
"location": "R400-20-FL-1001",
"assetKey": "assets",
"asset": "R400-20-FL-1001-EQ",
"title": "Pump leak",
"status": "open",
"priority": "high",
"files": [
{ "filename": "photo.jpg", "contentType": "image/jpeg", "data": "/9j/4AAQSkZJRgABAQ..." }
]
}'
See the Migration Guide for the full notes workflow.
Delete & truncate
- Delete a single record —
DELETE …/locations/{tableId},…/columns/{columnId}, or…/items/{itemId}. - Truncate items —
POST …/locations/{tableId}/items/truncateremoves all rows, keeping the table and its columns.
curl -X POST "https://api.treedis.com/v2/api/workspaces/7/cw/locations/functional-locations/items/truncate" \
-H "Authorization: Bearer your-access-token"
Truncate responses report how many rows were removed (data.deleted).
Errors
Errors use the same envelope with success: false and an optional details object:
{
"success": false,
"code": 400,
"message": "Cannot create a hierarchical loop",
"details": {
"error": "A table cannot have a parent that would create a circular reference"
}
}
| Status | When |
|---|---|
400 |
Validation failed, circular hierarchy, duplicate single‑use column type, or a key/column that can't be resolved |
404 |
Table, column, or item not found |
See the Connected Workers Locations tag in the API Reference for the full request and response schemas.

