Tempivo Help

Cellular

Cellular add-on: device registry, remote config, and outbound measurement webhooks.

REST API-översikt

GET
/devices/config-profiles

List profiles in the human-readable shape (temperatureAlerts, schedule, intervals). Use slug with GET/PUT and PUT …/apply.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Response Body

application/json

curl -X GET "https://example.com/devices/config-profiles"
{
  "profiles": [
    {
      "slug": "frozen-probe",
      "name": "Frozen goods probe",
      "schedule": {
        "always": true
      },
      "temperatureAlerts": [
        {
          "type": "range",
          "channel": "probe",
          "lowC": -30,
          "highC": -10,
          "hysteresisC": 0.5,
          "transmitOnBreach": true,
          "transmitOnReturn": true
        }
      ]
    }
  ]
}
Empty
POST
/devices/config-profiles

Create a profile with temperatureAlerts and optional schedule / intervals. Tempivo compiles to on-device rules.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Create a profile. Provide slug and/or name plus temperatureAlerts and/or schedule and/or intervals.

Response Body

application/json

curl -X POST "https://example.com/devices/config-profiles" \  -H "Content-Type: application/json" \  -d '{    "slug": "frozen-probe",    "name": "Frozen goods probe",    "schedule": {      "always": true    },    "temperatureAlerts": [      {        "type": "range",        "channel": "probe",        "lowC": -30,        "highC": -10,        "hysteresisC": 0.5,        "transmitOnBreach": true,        "transmitOnReturn": true      }    ]  }'
{
  "profile": {
    "slug": "string",
    "name": "string",
    "measurementIntervalMinutes": 1,
    "transmissionIntervalSeconds": 3600,
    "schedule": {
      "always": true
    },
    "temperatureAlerts": [
      {
        "type": "range",
        "channel": "ambient",
        "lowC": 0,
        "highC": 0,
        "minC": 0,
        "maxC": 0,
        "hysteresisC": 0,
        "transmitOnBreach": true,
        "transmitOnReturn": true
      }
    ]
  }
}
Empty
Empty
Empty
GET
/devices/config-profiles/{slug}

Read a profile by slug in the human-readable shape.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

slug*string

Response Body

application/json

curl -X GET "https://example.com/devices/config-profiles/string"
{
  "profile": {
    "slug": "frozen-probe",
    "name": "Frozen goods probe",
    "schedule": {
      "always": true
    },
    "temperatureAlerts": [
      {
        "type": "range",
        "channel": "probe",
        "lowC": -30,
        "highC": -10,
        "hysteresisC": 0.5,
        "transmitOnBreach": true,
        "transmitOnReturn": true
      }
    ]
  }
}
Empty
Empty
PUT
/devices/config-profiles/{slug}

Partial update using temperatureAlerts / schedule / intervals.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

slug*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Create or update body. For PUT, slug is in the path; send only fields to change.

Response Body

application/json

curl -X PUT "https://example.com/devices/config-profiles/string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "profile": {
    "slug": "string",
    "name": "string",
    "measurementIntervalMinutes": 1,
    "transmissionIntervalSeconds": 3600,
    "schedule": {
      "always": true
    },
    "temperatureAlerts": [
      {
        "type": "range",
        "channel": "ambient",
        "lowC": 0,
        "highC": 0,
        "minC": 0,
        "maxC": 0,
        "hysteresisC": 0,
        "transmitOnBreach": true,
        "transmitOnReturn": true
      }
    ]
  }
}
Empty
Empty
Empty
GET
/devices/{serial}/config

Read pending configuration (after profile apply) and the latest configuration reported by the device. Use syncStatus to see whether profile settings have been applied: poll until pendingConfig is null and syncStatus is applied (or no_device_report if the device has not reported config yet).

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

serial*string

Device serial number

Response Body

application/json

curl -X GET "https://example.com/devices/string/config"

{
  "serialNumber": "SN001",
  "assetId": "asset-123",
  "assetName": "Hot water, Building A",
  "pendingConfig": null,
  "deviceConfig": {
    "measurementPeriodBase": 3600,
    "measurementPeriodFactor": 1,
    "transmissionInterval": 21600
  },
  "deviceConfigReceivedAt": "2026-03-17T10:00:00.000Z",
  "syncStatus": "applied"
}

Empty
Empty
Empty
PUT
/devices/config-profiles/{slug}/apply

Merge the profile into pendingConfiguration for the given serial numbers or all active devices. Devices pick up changes on the next config poll.

Set queue: false when the settings were already written over BLE (e.g. @tempivo/sensor-beacon setConfigurationJson). The profile is then only linked to the device and nothing is queued. On the device's next complete config uplink the server compares the reported settings with the profile and queues the profile only if something differs.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

slug*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Apply a profile to devices. Provide serialNumbers (non-empty) or applyToAll true, not both.

Response Body

application/json

curl -X PUT "https://example.com/devices/config-profiles/string/apply" \  -H "Content-Type: application/json" \  -d '{    "serialNumbers": [      "SN001",      "SN002"    ]  }'
{
  "ok": true,
  "profileSlug": "weekday-low-temp",
  "appliedCount": 2,
  "applied": [
    "SN001",
    "SN002"
  ]
}
Empty
GET
/assets

List devices in your organization. Paginate with cursor / nextCursor. Device-first filters: tag (repeatable, AND), unassigned, country, model.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Query Parameters

limit?integer

Max items per page

cursor?string

Last asset's id from the previous page: the same value returned as nextCursor (pass verbatim).

model?string

Optional filter by sensor product line (alias: model-name).

model-name?string

Deprecated alias for model query param.

tag?array<string>

Filter by customer tag. Repeat for AND, e.g. tag=Sweden&tag=Freezer. Alias: tags.

unassigned?boolean

When true, only assets with no tags.

country?string

ISO country code from SIM/MCC (e.g. SE). Combined with tag filters.

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/assets"
{
  "items": [
    {
      "id": "asset-123",
      "recType": "asset",
      "name": "Unit 0042",
      "serialNumber": "DEVICE-123456789012",
      "status": "online",
      "signalStrength": "good",
      "batteryStatus": "ok",
      "model": "TS10-THT",
      "tags": [
        "Sweden",
        "DC"
      ],
      "lastReadingAt": "2026-03-17T10:00:00.000Z"
    }
  ],
  "totalItems": 1,
  "nextCursor": "asset-123"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
POST
/assets

Register a device (unique serialNumber among active assets). For integrator accounts, serialNumber and optional name are enough.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Register a device in your org. Cellular / integrator: omit buildingId when the org has a default building; use waterType automatic and floor 0 for a flat device list. Full REST (property): set buildingId (and optionally spaceId or floor) for building/room placement.

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/assets" \  -H "Content-Type: application/json" \  -d '{    "serialNumber": "DEVICE-123456789012",    "name": "Unit 0042",    "waterType": "automatic",    "floor": 0,    "model": "TS10-THT",    "tags": [      "Sweden",      "DC",      "LastMile"    ]  }'
{
  "id": "string"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
POST
/assets/bulk-assign-tags

Device-first. Set, add, or remove tags on many serial numbers. Catalog parents are not copied onto the asset.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X POST "https://example.com/assets/bulk-assign-tags" \  -H "Content-Type: application/json" \  -d '{    "serialNumbers": [      "282C0242F300",      "282C0242F301"    ],    "tags": [      "Sweden",      "DC"    ],    "mode": "add"  }'
{
  "updated": 0,
  "missing": [
    "string"
  ]
}
Empty
Empty
GET
/asset-tags

Device-first tag catalog: parentId hierarchy and optional place per tag. Asset assignment is still tags on each asset.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Response Body

application/json

curl -X GET "https://example.com/asset-tags"
{
  "tags": [
    {
      "id": "terminal a",
      "tag": "Terminal A",
      "parentId": "stockholm",
      "place": {
        "lat": 59.33,
        "lng": 18.06,
        "address": "Stockholm"
      }
    }
  ]
}
POST
/asset-tags

Create a tag in the catalog. Optional parentId (existing catalog id, max depth 3) and place (lat, lng, address).

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X POST "https://example.com/asset-tags" \  -H "Content-Type: application/json" \  -d '{    "tag": "Terminal A",    "parentId": "stockholm",    "place": {      "lat": 59.33,      "lng": 18.06,      "address": "Stockholm"    }  }'
{
  "id": "terminal a",
  "tag": "Terminal A",
  "parentId": "stockholm",
  "place": {
    "lat": 59.33,
    "lng": 18.06,
    "address": "Stockholm"
  }
}
GET
/asset-tags/{tag}

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

tag*string

Catalog id (lowercase tag name). Display name also accepted.

Response Body

application/json

curl -X GET "https://example.com/asset-tags/string"
{
  "id": "terminal a",
  "tag": "Terminal A",
  "parentId": "stockholm",
  "place": {
    "lat": 59.33,
    "lng": 18.06,
    "address": "Stockholm"
  }
}
Empty
PATCH
/asset-tags/{tag}

Set parentId (null = root; must be an existing catalog id) and/or place (null clears coordinates).

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

tag*string

Catalog id (lowercase tag name). Display name also accepted.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X PATCH "https://example.com/asset-tags/string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "terminal a",
  "tag": "Terminal A",
  "parentId": "stockholm",
  "place": {
    "lat": 59.33,
    "lng": 18.06,
    "address": "Stockholm"
  }
}
DELETE
/asset-tags/{tag}

Removes the tag from the catalog and from all assets in the organization.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

tag*string

Catalog id (lowercase tag name). Display name also accepted.

Response Body

application/json

curl -X DELETE "https://example.com/asset-tags/string"
{
  "updated": 0
}
GET
/assets/{assetId}

Retrieve one device by asset ID. Same API key as config profiles.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

assetId*string

Response Body

application/json

application/json

curl -X GET "https://example.com/assets/string"
{
  "id": "asset-123",
  "recType": "asset",
  "name": "Unit 0042",
  "serialNumber": "DEVICE-123456789012",
  "status": "online",
  "signalStrength": "good",
  "batteryStatus": "ok",
  "model": "TS10-THT",
  "tags": [
    "Sweden",
    "DC"
  ],
  "lastReadingAt": "2026-03-17T10:00:00.000Z"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
PATCH
/assets/{assetId}

Silence notifications (any org). Device-first also: name and tags. Alerts are still created and visible in the platform and via GET /alerts.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

assetId*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

PATCH /assets/{assetId}. Silence notifications on any org. Device-first also accepts name and tags.

Response Body

application/json

application/json

application/json

curl -X PATCH "https://example.com/assets/string" \  -H "Content-Type: application/json" \  -d '{    "tags": [      "Sweden",      "DC"    ],    "notificationsSilenced": true,    "notificationsSilencedUntil": "2026-09-29T12:00:00Z"  }'
{
  "id": "asset-1AbcDeF2GhiJkL",
  "recType": "asset",
  "name": "Kirurgavd. Handfat",
  "serialNumber": "DEMO-SN-019",
  "model": "TS10-THT",
  "status": "online",
  "signalStrength": "good",
  "batteryStatus": "ok",
  "tags": [
    "Sweden",
    "DC"
  ],
  "organizationId": "org_abc123",
  "buildingId": "bld_xyz",
  "spaceId": "space_101",
  "lastWaterTemperature": 56.8,
  "lastAmbientTemperature": 21.2,
  "lastRelativeHumidity": 45.2,
  "lastReadingAt": "2024-05-21T10:30:00.000Z",
  "nextTransmissionAt": "2024-05-21T12:30:00.000Z",
  "createdAt": "2024-01-15T08:00:00.000Z",
  "updatedAt": "2024-05-21T10:35:00.000Z"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
DELETE
/assets/{assetId}

Remove a device from your org (soft-delete: status → archived, assignments cleared). It disappears from list/get; measurement history is kept. No public restore — contact support if needed. Same API key as config profiles.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

assetId*string

Response Body

application/json

application/json

curl -X DELETE "https://example.com/assets/string"
{
  "deleted": true
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
POST
/assets/{assetId}/replace-hardware

Replace the physical device for an asset: set a new serial number and append the previous one to replacement history. All existing data (history, config, alerts) is kept. Cellular API organizations may use their API key here without the API integrations add-on (same key as config profiles).

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

assetId*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/assets/string/replace-hardware" \  -H "Content-Type: application/json" \  -d '{    "newSerialNumber": "DEVICE-987654321098"  }'
{
  "success": true,
  "serialNumber": "string"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
GET
/assets/{assetId}/calibration-certificate

Download the ILAC / laboratory calibration PDF for a registered asset (when Tempivo has uploaded one for that serial). Serial STOREVIEW001 always returns a bundled two-page sample PDF if no uploaded file exists.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

assetId*string

Response Body

application/pdf

application/json

curl -X GET "https://example.com/assets/string/calibration-certificate"
"string"
{
  "success": false,
  "message": "Invalid or inactive API key"
}
GET
/cellular-webhooks

List outbound Cellular measurement webhook endpoints. Multiple active URLs may be configured (e.g. production and development).

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Query Parameters

status?string

Response Body

application/json

curl -X GET "https://example.com/cellular-webhooks"
{
  "recType": "cellular-webhook-collection",
  "items": [
    {
      "id": "string",
      "recType": "cellular-webhook",
      "name": "string",
      "url": "http://example.com",
      "status": "active",
      "deliverConfigApplied": true,
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z",
      "delivery": {
        "lastDeliveredAt": "2019-08-24T14:15:22Z",
        "lastAttemptAt": "2019-08-24T14:15:22Z",
        "lastStatus": "delivered",
        "lastStatusCode": 0,
        "lastError": "string"
      }
    }
  ],
  "totalItems": 0
}
POST
/cellular-webhooks

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X POST "https://example.com/cellular-webhooks" \  -H "Content-Type: application/json" \  -d '{    "url": "http://example.com"  }'
{
  "id": "string",
  "recType": "cellular-webhook",
  "name": "string",
  "url": "http://example.com",
  "status": "active",
  "deliverConfigApplied": true,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "delivery": {
    "lastDeliveredAt": "2019-08-24T14:15:22Z",
    "lastAttemptAt": "2019-08-24T14:15:22Z",
    "lastStatus": "delivered",
    "lastStatusCode": 0,
    "lastError": "string"
  }
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
GET
/cellular-webhooks/{webhookId}

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

webhookId*string

Response Body

application/json

application/json

curl -X GET "https://example.com/cellular-webhooks/string"
{
  "id": "string",
  "recType": "cellular-webhook",
  "name": "string",
  "url": "http://example.com",
  "status": "active",
  "deliverConfigApplied": true,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "delivery": {
    "lastDeliveredAt": "2019-08-24T14:15:22Z",
    "lastAttemptAt": "2019-08-24T14:15:22Z",
    "lastStatus": "delivered",
    "lastStatusCode": 0,
    "lastError": "string"
  }
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
PATCH
/cellular-webhooks/{webhookId}

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

webhookId*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X PATCH "https://example.com/cellular-webhooks/string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "string",
  "recType": "cellular-webhook",
  "name": "string",
  "url": "http://example.com",
  "status": "active",
  "deliverConfigApplied": true,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "delivery": {
    "lastDeliveredAt": "2019-08-24T14:15:22Z",
    "lastAttemptAt": "2019-08-24T14:15:22Z",
    "lastStatus": "delivered",
    "lastStatusCode": 0,
    "lastError": "string"
  }
}
{
  "success": false,
  "message": "Invalid or inactive API key"
}
DELETE
/cellular-webhooks/{webhookId}

Authorization

ApiKeyAuth
AuthorizationBearer <token>

Bearer token with your API key. Example: Bearer sk_live_xxx

In: header

Path Parameters

webhookId*string

Response Body

application/json

curl -X DELETE "https://example.com/cellular-webhooks/string"
Empty
{
  "success": false,
  "message": "Invalid or inactive API key"
}

Var den här guiden bra?