Managing Sensors API Guide
The LOCUS API allows authorized clients to create, retrieve, update, delete, import, export, and manage sensor records. This guide documents the endpoints defined under sensor-controller in the LOCUS OpenAPI specification.
API base URL: https://locus-api.tektelic.com
OpenAPI specification: LOCUS API documentation
Note: The request and response structures below are based on the provided OpenAPI 3.0.1 specification (API version 1.0). Examples use placeholder IDs and tokens and have not been executed against a live LOCUS environment. Field requirements may also depend on server-side validation rules that are not expressed in the schema.
The API defines HTTP Bearer authentication using a JWT. Include the token in the Authorization header for protected requests:
Authorization: Bearer <ACCESS_TOKEN>
The examples below use the environment variables BASE_URL and TOKEN:
export BASE_URL="https://locus-api.tektelic.com"
export TOKEN="<ACCESS_TOKEN>"
Obtain the JWT through your organization’s supported authentication workflow. Do not include credentials in documentation or shared logs.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/sensor |
Create a sensor |
POST |
/api/sensor/on-prem |
Create a sensor in an on-premises environment |
GET |
/api/sensor/id/{id} |
Retrieve a sensor by ID |
GET |
/api/sensor/id/{id}/details |
Retrieve detailed sensor information |
PUT |
/api/sensor |
Update a sensor |
PUT |
/api/sensor/id/{id}/details |
Edit sensor details on the map |
DELETE |
/api/sensor/id/{id} |
Delete a sensor |
DELETE |
/api/sensor/delete-bulk |
Delete multiple sensors |
POST |
/api/sensor/filter |
Search and filter sensors |
GET |
/api/sensor/unassigned |
Retrieve unassigned sensors |
POST |
/api/sensor/assign |
Assign a sensor to a floor plan |
PUT |
/api/sensor/unassign |
Unassign multiple sensors |
PUT |
/api/sensor/positions |
Update sensor position |
GET |
/api/sensor/parameters/all |
Retrieve available sensor parameters |
GET |
/api/sensor/parameters/id/{sensorId} |
Retrieve parameters for one sensor |
POST |
/api/sensor/parameters |
Query sensor parameters |
GET |
/api/sensor/csv/template |
Download a CSV import template |
POST |
/api/sensor/create/file |
Import sensors from CSV |
POST |
/api/sensor/create/onprem |
Import sensors from CSV for on-premises |
POST |
/api/sensor/get-csv |
Export filtered sensors as CSV |
POST /api/sensor
Send a JSON body matching CreateSensorRequest. The schema includes the following fields:
| Field | Type | Description |
|---|---|---|
name |
string | Sensor name |
deviceEui |
string | Device EUI |
sensorModelId |
string | Sensor model ID |
homeSiteId |
string | Home site ID |
inactivityTimeout |
integer | Inactivity timeout; verify applicable units in your deployment |
description |
string | Sensor description |
tags |
array of strings | Tag IDs |
buildingId |
string | Building ID |
floorPlanId |
string | Floor plan ID |
coordinateX, coordinateY |
number | Floor-plan coordinates |
latitude, longitude |
number | Geographic coordinates |
tcode, revision, serialNumber |
string | TEKTELIC device identification information |
The OpenAPI schema does not declare a required field list for CreateSensorRequest; actual validation can require a subset of these fields depending on the creation workflow.
Example:
curl -X POST "$BASE_URL/api/sensor" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Warehouse Temperature Sensor",
"deviceEui": "647FDA0000000000",
"sensorModelId": "aab62a49-a437-4ea2-83b1-43fce670dd0a",
"homeSiteId": "aab62a49-a437-4ea2-83b1-43fce670dd0b",
"inactivityTimeout": 60,
"description": "Installed in warehouse A"
}'
Responses: 200 — sensor created, returning SensorDto; 400 — invalid input or validation failure; 403 — insufficient permissions.
POST /api/sensor/on-prem accepts CreateSensorOnPremRequest. Its fields are similar to CreateSensorRequest, but the on-premises schema does not include tcode, revision, or serialNumber.
curl -X POST "$BASE_URL/api/sensor/on-prem" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "On-Premises Sensor",
"deviceEui": "647FDA0000000000",
"sensorModelId": "aab62a49-a437-4ea2-83b1-43fce670dd0a",
"homeSiteId": "aab62a49-a437-4ea2-83b1-43fce670dd0b"
}'
Responses: 200, 400, 403.
GET /api/sensor/id/{id} returns a SensorDto object.
curl "$BASE_URL/api/sensor/id/<SENSOR_ID>" \
-H "Authorization: Bearer $TOKEN"
The response schema includes id, deviceEui, name, sensorModel, status, battery, description, location fields, inactivityTimeout, tags, creation and modification timestamps, rssi, and psr. Not every field is guaranteed to be populated.
Responses: 200, 400, 403.
GET /api/sensor/id/{id}/details returns the Sensor Detail Response schema.
curl "$BASE_URL/api/sensor/id/<SENSOR_ID>/details" \
-H "Authorization: Bearer $TOKEN"
Responses: 200, 400, 403.
POST /api/sensor/filter accepts SensorFilterRequest and returns EntityListResponse.
| Field | Type | Purpose |
|---|---|---|
pageNumber |
integer | Page index (example: 0) |
pageSize |
integer | Requested page size |
searchValue |
string | Search text |
tagFilter |
string array | Tag IDs |
homeSiteFilter |
string array | Home site IDs |
buildingFilter |
string array | Building IDs |
floorPlanFilter |
string array | Floor plan IDs |
modelFilter |
string array | Sensor model IDs |
lastModifiedByFilter |
string array | Users who last modified sensors |
inactivityTimeoutFilter |
integer array | Inactivity timeout values, in minutes |
sortingParameters |
string array | Sort fields |
Supported sorting field names listed in the specification are deviceEui, homeSite, building, lastModifiedDate, sensorModel, id, name, createDate, floorPlan, and lastModifiedBy. The specification does not define a sorting-direction syntax.
curl -X POST "$BASE_URL/api/sensor/filter" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"pageNumber": 0,
"pageSize": 20,
"searchValue": "warehouse",
"sortingParameters": ["name"]
}'
Responses: 200, 400, 403. The OpenAPI description for 400 says “Internal server error”; treat the returned error message as authoritative rather than assuming its cause.
PUT /api/sensor accepts UpdateSensorRequest and returns an updated SensorDto. Unlike the create request, the update request includes an id field identifying the sensor.
curl -X PUT "$BASE_URL/api/sensor" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Updated Warehouse Sensor",
"description": "Moved to warehouse B"
}'
Responses: 200, 400, 403.
The specification does not state whether omitted update fields remain unchanged or are reset. Confirm partial-update behavior before sending a request containing only selected fields.
PUT /api/sensor/id/{id}/details accepts EditSensorOnMapRequest, with name, description, and tags fields. Its successful response is a boolean.
curl -X PUT "$BASE_URL/api/sensor/id/<SENSOR_ID>/details" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Updated Sensor Name","description":"Near main entrance"}'
Responses: 200, 400, 403.
POST /api/sensor/assign requires id and floorPlanId in the JSON body. An optional coordinates object contains x and y values.
curl -X POST "$BASE_URL/api/sensor/assign" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "123e4567-e89b-12d3-a456-426614174000",
"floorPlanId": "789e4567-e89b-12d3-a456-426614174999",
"coordinates": {"x": 154.23, "y": 89.77}
}'
Responses: 200 (boolean), 400, 403.
GET /api/sensor/unassigned supports an optional siteId query parameter.
curl "$BASE_URL/api/sensor/unassigned?siteId=<SITE_ID>" \
-H "Authorization: Bearer $TOKEN"
Responses: 200 (SimpleSensor schema as declared), 400, 403.
PUT /api/sensor/unassign accepts a JSON array of sensor UUID strings.
curl -X PUT "$BASE_URL/api/sensor/unassign" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '["123e4567-e89b-12d3-a456-426614174000"]'
Responses: 200 (boolean), 400, 403.
PUT /api/sensor/positions accepts SensorPositionRequest. The id field is required. Use coordinates for floor-plan x/y values or location for geographic lat/lng values, as applicable.
curl -X PUT "$BASE_URL/api/sensor/positions" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "123e4567-e89b-12d3-a456-426614174000",
"coordinates": {"x": 154.23, "y": 89.77}
}'
Responses: 200 (boolean), 400, 403.
The sensor controller also exposes the following endpoints:
| Method | Endpoint | Input / result |
|---|---|---|
GET |
/api/sensor/parameters/all |
Returns SensorParameterResponse |
GET |
/api/sensor/parameters/id/{sensorId} |
Returns SensorParameterResponse; optional viewMode query parameter: CHART or TABLE |
POST |
/api/sensor/parameters |
JSON body: sensorModels (string array) and/or search (string); returns FilterEntityResponse |
Example for a specific sensor:
curl "$BASE_URL/api/sensor/parameters/id/<SENSOR_ID>?viewMode=CHART" \
-H "Authorization: Bearer $TOKEN"
GET /api/sensor/csv/template requires the manufacturer query parameter and returns a downloadable file (application/octet-stream). The accepted manufacturer values are not enumerated in the specification.
curl -L "$BASE_URL/api/sensor/csv/template?manufacturer=<MANUFACTURER>" \
-H "Authorization: Bearer $TOKEN" \
-o sensor-template.csv
Use the downloaded template to determine the expected CSV columns instead of assuming a fixed column layout.
POST /api/sensor/create/file accepts multipart/form-data with a required binary form field named file.
curl -X POST "$BASE_URL/api/sensor/create/file" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@sensors.csv"
For on-premises deployments, use POST /api/sensor/create/onprem with the same multipart field:
curl -X POST "$BASE_URL/api/sensor/create/onprem" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@sensors.csv"
Both endpoints return CsvListUploadResponse with:
savedRowCount— number of successfully saved rows.errorMessageCodes— array of error-message objects for reported issues.
Responses: 200, 400, 401, 403 as documented in the OpenAPI specification. Check savedRowCount and errorMessageCodes even when the HTTP request succeeds.
POST /api/sensor/get-csv accepts SensorFilterRequest as JSON and returns a binary CSV download. Query parameters include:
| Parameter | Required | Description |
|---|---|---|
timezone |
Yes | Time zone string |
table |
No | Table option |
location |
No | Location option |
The specification does not enumerate supported values for these query parameters. The example uses UTC as a placeholder; verify the accepted timezone format in your deployment.
curl -X POST "$BASE_URL/api/sensor/get-csv?timezone=UTC" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"pageNumber":0,"pageSize":20}' \
-o sensors-export.csv
Responses: 200 (binary file), 400, 401, 403.
DELETE /api/sensor/id/{id} deletes the specified sensor.
curl -X DELETE "$BASE_URL/api/sensor/id/<SENSOR_ID>" \
-H "Authorization: Bearer $TOKEN"
Responses: 200 (boolean), 403, 404.
DELETE /api/sensor/delete-bulk accepts a JSON array of sensor IDs.
curl -X DELETE "$BASE_URL/api/sensor/delete-bulk" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '[
"123e4567-e89b-12d3-a456-426614174000",
"123e4567-e89b-12d3-a456-426614174001"
]'
Responses: 200, 400, 403. The specification declares ErrorMessage as the response schema even for HTTP 200; do not assume the response is a boolean or a list of deleted IDs.
Warning: Deletion operations may be irreversible. Verify the sensor IDs and permissions before executing them.
Many error responses use the ErrorMessage schema:
{
"message": "Something went wrong. Please try again or contact TEKTELIC Support."
}
The message above illustrates the schema format and is not a guaranteed response from a specific endpoint.
| HTTP status | Meaning in the specification |
|---|---|
200 |
Operation succeeded; inspect the endpoint-specific response body |
400 |
Invalid input, validation failure, or other documented request error |
401 |
Listed for some CSV operations; the specification describes it as a permissions error |
403 |
Access denied or insufficient permissions |
404 |
Sensor not found (documented for single-sensor deletion) |
For troubleshooting, record the endpoint, HTTP status, response message, and a sanitized request body. Never share Bearer tokens.