Connected Workers Work Requests

A work request (a note in the product's earlier vocabulary, and still in the API's alias paths) is what a person in the field raises: something here needs attention. It is the reporting half of Connected Workers. Its complement is the work order — the planned, scheduled job that answers a request.

A work request carries content (title, description, status, priority, dates, assignee, form values, attachments) and, crucially, where it is: it anchors to a location, and optionally to an asset and a department.

  • Anchored by business key — you send your codes (a functional-location code, an asset's primary-key value, a department name), not Treedis ids. Nothing to configure per work request, nothing to look up first.
  • Create or update in one endpoint — omit id to create, include it to update.
  • Attachments inline — up to 10 files, 20 MB each, as multipart/form-data or base64 in JSON.

Base URL & auth

The workspace-level endpoint is the one to integrate against:

https://api.treedis.com/v2/api/workspaces/{workspaceId}/workRequests

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.

Authentication How to obtain and send an OAuth2 access token.

Three spellings, one endpoint. Every path below answers on /workRequests, /work-requests and /notes alike (…/export and …/import included). /notes is the original name and /work-requests its first rename; both are kept so integrations do not have to switch in lockstep with a deploy. New work should use /workRequests — the camelCase form is the house convention for URL paths.

Endpoints

Method Path Purpose
POST /v2/api/workspaces/{workspaceId}/workRequests Create or update a work request
GET /v2/api/workspaces/{workspaceId}/workRequests/export Export every work request as portable JSON
POST /v2/api/workspaces/{workspaceId}/workRequests/import Import portable JSON into this workspace

There is also a project/tour-level pair under /v1/api for integrations that anchor to a Treedis tag rather than a CW location — see Tour-level work requests below.

Creating a work request

location is the only required field: the location row's primary-key value — the code your own system uses. Treedis finds that row and files the request against it.

curl -X POST "https://api.treedis.com/v2/api/workspaces/7/workRequests" \
  -H "Authorization: Bearer your-access-token" \
  -H "Content-Type: application/json" \
  -d '{
    "location": "R400-20-FL-1001",
    "title": "Pump leak",
    "description": "There is a leak in the pump, needs immediate attention.",
    "status": "open",
    "priority": "high"
  }'
{
  "success": true,
  "code": 200,
  "message": "Success",
  "data": {
    "note": { "id": 9001, "title": "Pump leak", "status": "open", "priority": "high" }
  }
}

Anchors

Field Required What it is
location Yes The location row's primary-key value (e.g. its functional-location code).
assetKey No The asset table slug the asset value lives in (e.g. assets). Required when asset is sent.
asset No The asset row's primary-key value — links the request to that physical asset.
department No The department's title (its human name) — files the request against that department.

All three can be combined on one request. A value that matches no row returns 404; asset without assetKey returns 400.

curl -X POST "https://api.treedis.com/v2/api/workspaces/7/workRequests" \
  -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",
    "department": "Maintenance",
    "title": "Pump leak",
    "status": "open",
    "priority": "high"
  }'

See the Locations, Assets and Departments guides for how those rows and their primary keys are defined.

Content fields

Field Type Notes
id integer Omit to create. Include to update — it must be a work request in this workspace, otherwise 404.
title string Work request title.
description string Body / details.
status string e.g. open, in_progress.
priority string e.g. high.
assignee string Identifier of the user it is assigned to.
reporter string Identifier of the user reporting it.
scheduledDate date-time ISO 8601.
dueDate date-time ISO 8601.
customFields object Form field values, keyed by field — captured through the work request's form template.

Attachments

Up to 10 files, 20 MB each, image / audio / video / PDF only. Two transports, identical result:

multipart/form-data — best for large files:

curl -X POST "https://api.treedis.com/v2/api/workspaces/7/workRequests" \
  -H "Authorization: Bearer your-access-token" \
  -F 'location=R400-20-FL-1001' \
  -F 'title=Pump leak' \
  -F 'status=open' \
  -F 'files=@photo.jpg'

application/json with base64 — best when your integration already produces JSON. Each file goes under files as { filename, contentType, data }:

curl -X POST "https://api.treedis.com/v2/api/workspaces/7/workRequests" \
  -H "Authorization: Bearer your-access-token" \
  -H "Content-Type: application/json" \
  -d '{
    "location": "R400-20-FL-1001",
    "title": "Pump leak",
    "files": [
      { "filename": "photo.jpg", "contentType": "image/jpeg", "data": "/9j/4AAQSkZJRgABAQ..." }
    ]
  }'

data may be raw base64 or a full data URI (data:image/jpeg;base64,/9j/4AAQ...); with a data URI, contentType is inferred when omitted. Omit files for a work request with no attachments. The whole JSON body must fit the 20 MB request limit, so prefer multipart/form-data for large attachments.

Export & import

Both endpoints move work requests between workspaces as portable JSON. Anchors travel as business keys, not ids — a location by its name, an asset by table key + primary-key value — so the same payload re-resolves in the destination workspace.

curl "https://api.treedis.com/v2/api/workspaces/7/workRequests/export" \
  -H "Authorization: Bearer your-access-token"
{
  "success": true,
  "code": 200,
  "message": "Success",
  "data": {
    "kind": "cw-notes",
    "version": 1,
    "notes": [
      {
        "title": "Pump leak",
        "status": "open",
        "priority": "high",
        "assignee": null,
        "reporter": null,
        "location": "R400-20-FL-1001",
        "assetKey": "assets",
        "asset": "R400-20-FL-1001-EQ",
        "dueDate": "2026-06-25T17:00:00.000Z",
        "scheduledDate": null,
        "customFieldValues": null
      }
    ]
  }
}

Post that same payload back to import it:

curl -X POST "https://api.treedis.com/v2/api/workspaces/9/workRequests/import" \
  -H "Authorization: Bearer your-access-token" \
  -H "Content-Type: application/json" \
  -d @export.json
{ "success": true, "code": 200, "message": "Success", "data": { "imported": 1, "skipped": 0 } }

Runtime state is deliberately dropped on export — ids, tour and tag, 3D position, form template id, messages and timestamps. What travels is the request itself, not where it happened to be pinned. A request whose location or asset cannot be resolved in the destination is skipped, not guessed at, and counted in skipped.

Import the target tables before the work requests: push Locations, Assets and Departments first, or every anchor will fail to resolve.

Tour-level work requests

For integrations anchored to a Treedis tag rather than a CW location, /v1/api carries the original pair:

Operation Endpoint
Create / update a work request POST /v1/api/workRequests
Add a message to a work request POST /v1/api/workRequests/messages
curl -X POST "https://api.treedis.com/v1/api/workRequests" \
  -H "Authorization: Bearer your-access-token" \
  -F 'title=Pump leak' \
  -F 'tagId=456' \
  -F 'status=in_progress' \
  -F 'files=@photo.jpg'
curl -X POST "https://api.treedis.com/v1/api/workRequests/messages" \
  -H "Authorization: Bearer your-access-token" \
  -F 'threadId=789' \
  -F 'description=Replaced the seal; monitoring.' \
  -F 'files=@after.jpg'

Attach to a project (projectId) and/or a tag (tagId)tourId is not used and should be dropped from your payload; the tour is resolved from the tag when needed. Both endpoints accept multipart/form-data and application/json with base64 files, exactly like the workspace endpoint above.

If you are still calling the unauthenticated POST /v1/public/saveThread or POST /v1/public/saveThreadMessage, move to these: the request body is unchanged — add an Authorization header and change the path.

Errors

Status When
400 location missing, or asset sent without assetKey
401 Missing or invalid credentials
403 The caller has no access to the workspace, or an API key addressing another workspace
404 No location (or asset row) matches the given value, or id is not a work request in this workspace

See the Work Requests tag in the API Reference for the full request and response schemas.