Appearance
API
Base address: https://app.kealink.co.nz. Requests and replies are JSON. Times are UTC in ISO 8601.
| Method and path | Auth | Purpose |
|---|---|---|
POST /api/v1/machines/{id}/data | Machine id and password, HTTP Basic | Send readings |
GET /api/v1/machines | API key | Machines, their readings and latest values |
GET /api/v1/machines/{id}/readings | API key | History of one reading |
GET /api/v1/alerts | API key | Alerts |
GET /api/status | None | Service health, for uptime monitors |
API keys
Ask your Kealink contact for an API key. It reads one company's data and cannot send data. Machine passwords cannot read.
Authorization: Bearer kl_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxA key is kl_, 8 characters, _, then 32 more. It is shown once. A revoked key stops working on the next request.
Machines
GET /api/v1/machinesjson
{
"machines": [
{
"id": "01j9x4n7k2b3q8r5t6v7w8x9y0",
"name": "CNC 3",
"location": "Workshop",
"status": "online",
"lastSeenAt": "2026-10-24T02:15:30.000Z",
"intervalSeconds": 30,
"points": [
{
"key": "spindle_temp",
"label": "Spindle temperature",
"unit": "°C",
"kind": "number",
"lowLimit": null,
"highLimit": 90,
"warningLow": null,
"warningHigh": 80,
"latest": { "time": "2026-10-24T02:15:30.000Z", "value": 41.2 }
}
]
}
]
}| Field | Values |
|---|---|
status | online (Reporting), stale (Late), offline (Not reporting, or never reported when lastSeenAt is null) |
kind | number, state (on and off) or text |
latest | null if nothing has arrived. value is a string for a text reading. |
Readings
GET /api/v1/machines/{id}/readings?point=<key>&from=<time>&to=<time>&resolution=<raw|hour|day>| Parameter | Default | Notes |
|---|---|---|
point | Required | The reading's key, lowercase as set up |
from | 24 hours before to | Included |
to | Now | Not included |
resolution | raw | raw covers up to 31 days per request; hour and day up to 400 days |
sh
curl -H 'Authorization: Bearer <api key>' \
'https://app.kealink.co.nz/api/v1/machines/<machine-id>/readings?point=spindle_temp&resolution=hour&from=2026-10-01T00:00:00Z'json
{
"machine": "01j9x4n7k2b3q8r5t6v7w8x9y0",
"point": { "key": "spindle_temp", "label": "Spindle temperature", "unit": "°C", "kind": "number" },
"resolution": "hour",
"from": "2026-10-01T00:00:00.000Z",
"to": "2026-10-24T02:20:00.000Z",
"truncated": false,
"readings": [
{ "time": "2026-10-01T00:00:00.000Z", "value": 40.8, "min": 39.9, "max": 41.6, "count": 120 }
]
}- Raw rows have
timeandvalue. Hourly and daily rows are averages, withmin,maxandcount. - Oldest first, up to 50,000 rows. A larger range returns the first 50,000 with
truncated: true; ask again withfromjust after the lasttime. - Number and on and off readings only. Text readings are not returned here.
Alerts
GET /api/v1/alerts
GET /api/v1/alerts?open=trueThe most recent 200 alerts, open ones first. open=true returns only those still open.
json
{
"alerts": [
{
"id": "01j9x5a1b2c3d4e5f6g7h8j9k0",
"kind": "high",
"active": true,
"openedAt": "2026-10-24T02:15:00.000Z",
"closedAt": null,
"machine": { "id": "01j9x4n7k2b3q8r5t6v7w8x9y0", "name": "CNC 3" },
"point": { "label": "Spindle temperature", "unit": "°C", "lowLimit": null, "highLimit": 90 },
"triggerValue": 92.4
}
]
}kind is high, low or offline. point is null for an offline alert.
Status
GET /api/status200 with "ok": true when Kealink is receiving data; 503 otherwise. Contains no company data.