API
Everything the app does, it does through a REST API you can use directly. Useful for bulk device creation, for provisioning from your own tooling, or for pulling counts into a dashboard of your own.
The interactive reference
The full, always-current specification is served by the API itself:
| What | Where |
|---|---|
| Swagger UI | /docs on the API host |
| OpenAPI JSON | /docs-json |
| OpenAPI YAML | /docs-yaml |
Running locally that is localhost:3000/docs.
It is generated from the API's own code, so it cannot drift from what the server
actually serves. Every endpoint carries a summary, its parameters, its success
response and the errors it can return. Point a client generator at /docs-json
to get a typed SDK.
Authenticating
POST /auth/login with your credentials returns an access token and a refresh
token. Send the access token on every other request:
Authorization: Bearer <access token>
When it expires, POST /auth/refresh trades the refresh token for a new pair.
POST /auth/logout exists for symmetry — the API keeps no session state, so
logging out is your client discarding its tokens.
Choosing a tenant
Almost every endpoint acts inside one tenant, named by a header:
x-tenant-id: <tenant uuid>
Omitting it on a tenant-scoped route is a 400. The exceptions are auth,
health and the ingest endpoints, which take no tenant.
GET /auth/me lists the tenants your token can use.
404, never 403 — a 403 would confirm the id
exists. If an id you are certain about returns 404, check the x-tenant-id you
sent before you doubt the id.Pagination
List endpoints take page (from 1) and limit (1–100, default 20):
GET /api/v1/devices?page=2&limit=50
and answer with the data and its counts:
{
"data": [ ... ],
"meta": { "page": 2, "limit": 50, "total": 384, "totalPages": 8 }
}
Errors
One envelope for every failure, keyed by a stable code. See
Error codes.
Note that unknown properties in a request body are rejected, not ignored — which turns a silent typo into an immediate, obvious error.
The ingest endpoints are different
The ingest group is the public left side — the URLs a device network posts to.
Three things set them apart:
- No Center token. Each source authenticates its own payload through its adapter. See Connect a source.
- Not only JSON. They accept
application/json,application/xml,text/xmlandtext/plain, up to 1 MB. - Two live outside the API prefix.
POST /i/{slug}andPOST /i/s/{slug}sit at the domain root, so a link you paste into someone else's console stays short.
Plan before you apply
Provisioning endpoints come in pairs. The plan variant is a dry run: it
returns the exact requests that would be sent to the provider and changes
nothing. The apply variant sends them, is gated by deployment configuration,
and is idempotent — re-running reconciles rather than duplicating.
Call plan first from scripts too, and log what it returns. It is the cheapest
audit trail you will get.