Skip to content
Docs

Deploy, claim, connect.

Get an instance running in your own Cloudflare account, then point hardware at it over plain HTTPS. Everything below is the live API surface.

Deploy & claim

Deploy the platform to your Cloudflare account. The button provisions D1, R2, KV, and the Worker — there's nothing else to host.

  1. 1 Open your worker URL (e.g. nodrix.<your-subdomain>.workers.dev).
  2. 2 Register the first account with email + password. It's assigned the owner role, and a default project is created for you.
  3. 3 (Optional) Under Settings → Sign-in providers, add Google or GitHub OAuth credentials to light up social sign-in.

Tokens

Two kinds of bearer token, two audiences. Both are shown once on creation — copy them right away.

Project token

For hardware. Authorizes telemetry, control, and events on one project.

User token

For external apps. Authorizes the read-only API. Mint it under API tokens.

Device protocol

Authenticate every request with your project token: Authorization: Bearer <project_token>

Send telemetry

POST one or many metrics. Keys become variables, auto-created on first sight. Send metrics for a batch, or a single metric/value pair.

POST /v1/telemetry
{ "ts": 1715900000, "metrics": { "temperature": 23.4, "humidity": 61 } }
→ 204 No Content

Poll for control writes

Dashboard widgets queue value writes for your hardware. Fetch them, apply them, then ack so the platform stops resending.

GET /v1/control
 { "control": [ { "id": "ctl_x", "variable": "relay", "value": "on" } ] }

POST /v1/control/ack
{ "ids": ["ctl_x"] }
 { "acked": 1 }

…or stream over WebSocket

Skip polling: open a socket and receive control writes the instant a widget moves. Ack the same way, inline.

WSS /v1/control/ws?token=<project_token>
// incoming
{ "type": "control", "id": "ctl_x", "variable": "relay", "value": "on" }
// reply
{ "type": "ack", "ids": ["ctl_x"] }

Emit an event

Fire a named event to trigger any matching automation — a button press, a fault, a heartbeat.

POST /v1/events
{ "event": "door_opened", "payload": { "by": "front" } }
→ 204 No Content

Dashboards

Compose dashboards in a full-page, drag-and-drop editor: drop widgets onto a grid and bind each to a variable. Readings stream in live over a hibernating WebSocket, and control widgets write back — a toggle or slider becomes a control write your hardware picks up on its next poll. Seven framework-agnostic widgets ship in the box — value, gauge, chart, map, toggle, slider, and push, with a separate mobile layout (browse them →).

Publish any dashboard read-only at a secret share link — viewers need no account, live values arrive by polling, and nothing outside that dashboard's own widgets is ever exposed.

Read API

For external apps — Grafana, a dashboard of your own, a Pi screen. Authenticate with a user token: Authorization: Bearer <user_token>

# every variable in a project
GET /v1/projects/:proj/variables

# latest value of every variable (edge-cached)
GET /v1/projects/:proj/state

# recent time-series for one variable
GET /v1/projects/:proj/variables/:key/series?window=1h

window accepts values like 30s, 15m, or 6h and reads from the recent ring buffer.

Automations

Built in a visual flow editor in the admin UI — no extra code path for your hardware. Each automation is a graph: one or more triggers flow through optional conditions into actions, all evaluated at the edge.

Freezer guard — flow editor
Temperature> -15 °C
Eventdoor_opened
Time window09:00 – 17:00
Email opsintegration
Set buzzer = onset value
yes no
Triggers
Variable condition (threshold, equality, or change) · schedule · sunrise / sunset · custom event · manual run
Conditions
If-variable comparison (branches yes / no) · time window (within hours, by weekday)
Actions
Set a variable · call an integration (HTTP, email, or chat like Slack / Telegram / Discord) · emit an event

The HTTP service integration can HMAC-sign its request body with a shared secret, so the receiving end can verify the payload genuinely came from your instance.

MCP server for AI clients

Optional Model Context Protocol server. Off by default. The owner enables it from Settings → MCP server, exposing two endpoints on the same worker.

/v1/mcp

Bearer-token transport, for CLI and IDE clients (Claude Code, Cursor). Authenticates with a user token from Settings → Tokens.

/v1/mcp/oauth

OAuth 2.1 transport, for browser-based clients (claude.ai connectors). No token to manage — the user signs in and approves a consent screen.

What the server can do

Read tools are always on when MCP is enabled. Management tools require a second toggle — and even then, the connecting user must explicitly grant mcp:manage at consent time. No delete operations are ever exposed.

Read

  • • Browse projects, variables, dashboards
  • • Read current state and recent time-series
  • • View automations and integrations (secrets redacted)

Manage (opt-in)

  • • Create / update projects, variables, dashboards
  • • Create, update, and run automations
  • • Create / update integrations
  • • Send commands to hardware (set variable values)

Every MCP-driven write is recorded in the audit log when enabled, tagged as MCP-sourced so you can tell AI-initiated changes apart from web/API ones.

Ready to try it?

Deploy a fresh instance to your own account — it's pre-alpha, so keep it to accounts you're happy to experiment in.