Skip to Content

Endpoints

Health (Available)

MethodPathGateDescription
GET/healthzpublicLiveness. { "status": "ok", "version": "0.1.0", "env": "prod" }
GET/readyzpublicReadiness (checks the database). { "status": "ok" | "degraded", "database": bool, "jobs": "postgres" | "disabled" }

Every route lists its gate (admin / tenant / user / public); see Authentication → gates.

Keys (Available)

MethodPathGateDescription
GET/v1/keys/scopestenant · keys:manageValid scope names
POST/v1/keystenant · keys:manageIssue a key (name, scopes default all, expiresAt) → plaintext once
GET/v1/keys?q=&cursor=&limit=&includeRevoked=tenant · keys:manageList (search name/prefix)
GET / PATCH / DELETE/v1/keys/{id}tenant · keys:manageRead / update name-scopes-expiry / revoke

Users (Available)

MethodPathGateDescription
POST/v1/userstenant · users:writeCreate (tenantKey, displayName, email?, phone?, locale?, timezone?, units?); 409 on duplicate tenantKey
GET/v1/users?q=&cursor=&limit=&includeDisabled=tenant · users:readList (search tenantKey / name / email)
GET/v1/users/by-key/{tenantKey}tenant · users:readLookup by your id
GET / PATCH / DELETE/v1/users/{id}tenant · users:read / users:writeRead / update (changing email or phone resets its verification) / hard delete
POST/v1/users/{id}/disable · /enabletenant · users:writeDisable (revokes sessions, blocks minting) / re-enable
POST / GET/v1/users/{id}/session-tokenstenant · users:writeMint (token once) / list
DELETE/v1/session-tokens/{id}tenant · users:writeRevoke a pending token

Auth (Available)

MethodPathGateDescription
POST/v1/auth/sessionpublicExchange session token → cookie + Me
GET/v1/auth/meuser (exact)Current user / tenant / session
POST/v1/auth/logoutuser (exact)Revoke session, clear cookie
GET / DELETE/v1/auth/sessions[/{id}]user (exact)Own sessions

Tiles (Available)

MethodPathGateDescription
GET/v1/tilesuserLatest tile versions visible to the tenant (platform + own); ?allVersions=true
GET/v1/tiles/{id}userTile definition (no script)
GET/v1/tiles/{id}/specuserSelf-describing spec: flattened params[] + ui + paramsSchema; see Tiles

Sources (Available)

MethodPathGateDescription
POST/v1/sourcesuser · keys sources:writeRegister a source: displayName, hint (open lower-kebab string: area, sensor, weather-station, or your own), optional tenantKey (your stable id, unique per owner), boundary (closed [lng,lat] ring), location ({lat,lng}; derived centroid when only a boundary is sent), timezone, metadata
GET/v1/sourcesuser · keys sources:readList (paginated, q over displayName/tenantKey/hint, ?hint=, ?status=, tenant callers ?userKey=); a user session sees only its own
GET / PATCH / DELETE/v1/sources/{id}user · keys sources:read / sources:writeRead / update (incl. clearBoundary/clearLocation/clearTenantKey) / delete

Bind a flow with targets: [{ "sourceId": "…" }]. The Engine resolves the name, location (or boundary centroid) and timezone at run time; deleting a bound source makes later runs fail with a clear error until the flow is re-saved.

Flows & runs (Available)

MethodPathGateDescription
POST/v1/flowsuser · keys flows:writeCreate (tiles validated against their schemas; tileKey or pinned id/version; tenant callers may pass ownerUserKey; sources and contact lists must belong to the owner)
GET/v1/flowsuser · keys flows:readList (paginated, q, ?status=, tenant callers ?userKey=); a user session sees only its own
GET / PATCH / DELETE/v1/flows/{id}user · keys flows:read / flows:writeRead / update (tiles or targets bump version) / delete
POST/v1/flows/{id}/runuser · keys flows:runRun now: 202 with the queued run (targets run in parallel; poll /v1/runs/{id}; 409 while a run is unfinished); body { "now": ISO } optional
GET/v1/flows/{id}/runsuser · keys flows:readRun history (summaries; ?includeResults=true)
GET/v1/runs/{id}user · keys results:readOne run with per-target, per-tile results

Adapters (Available)

MethodPathGateDescription
POST/v1/adapterstenant · adapters:manageRegister an adapter: facet (series | weather | events | targets | comms, one each), displayName (+ optional tenantKey), TS/JS script, write-only env, allowedHosts
GET/v1/adapters[/{id}]tenant · adapters:manageList/read (env shown as envKeys only)
PATCH / DELETE/v1/adapters/{id}tenant · adapters:manageUpdate script/env/hosts/status / remove
POST/v1/adapters/{id}/testtenant · adapters:manageRun once with a sample request
POST/v1/adapters/{id}/synctenant · adapters:managetargets adapters only. 202: queue a source-catalog sync now (the hourly scheduler runs the same job); optional ?userKey=

Contacts & alerts

MethodPathGate · scopePurpose
POST / GET/v1/contactsuser · keys contacts:write / contacts:readCreate / list (cursor + q search, tenant callers ?userKey=); a contact needs email and/or phone; user-owned
GET / PATCH / DELETE/v1/contacts/{id}user · keys contacts:read / contacts:writeRead / update (address change resets its verification) / delete
POST / GET/v1/contact-listsuser · keys contacts:write / contacts:readCreate / list (tenant callers ?userKey=); members must belong to the list’s owner
GET / PATCH / DELETE/v1/contact-lists/{id}user · keysRead / rename + replace membership (contactIds) / delete
POST/v1/users/{id}/verificationstenant · users:writeStart a user’s address verification ({"channel": "email"|"sms"})
POST/v1/contacts/{id}/verificationsuser · keys contacts:writeStart a contact’s address verification; a user session verifies its own contacts
POST…/verifications/confirmsame as the start routeConfirm the 6-digit SMS code
GET/verify/{token}publicConsume the one-time email link

Sessions

MethodPathGate · scopePurpose
POST/v1/session-tokenstenant (any key; the session is frozen to ⊆ its scopes)Mint a tenant session token: the GUI logs in as the tenant itself (Me.kind: "tenant")

Alert config rides the flow (settings.alerts, validated); see Alerts & contacts. Manual runs pass {"suppressAlerts": false} to send alerts.

Reports (Available)

MethodPathGate · scopePurpose
GET/v1/flows/{id}/reportsuser · keys results:readThe flow’s report history (one row per send attempt, per-recipient outcomes inside)
POST/v1/flows/{id}/reports/send-nowuser · keys reports:sendFreeze a report from an existing succeeded run (runId optional, defaults to the latest) and email its link to contactListIds: 202 {reportId, token, link, expiresAt}; delivery runs on a worker, poll the history
GET/reports/{token}publicThe frozen report payload behind an emailed link (7-day expiry; 404 after)

Report schedules ride the flow (settings.reports, validated); see Reports.

Branding

MethodPathGate · scopePurpose
GET / PUT / DELETE/v1/brandingtenant · branding:manageThe tenant brand {name?, logo?, skin?} (PUT replaces whole)
GET / PUT / DELETE/v1/branding/meuser session onlyA permitted user’s personal brand (canOverrideBranding); overrides their own account per-field
PUT/v1/branding/skintenant · branding:manageReplace the tenant skin (compat view over branding.skin)
GET/v1/branding/skintenant · branding:manageRead back the stored skin ({"skin": null} when unset)
DELETE/v1/branding/skintenant · branding:manageClear (back to the platform default)
GET/v1/branding/themeuserThe caller-resolved brand: {name, logo, colorSchemes, shape}; see Branding

See Adapters for the script contract. The Engine keeps no copy of the data.

Pagination & search (Available)

Every list endpoint accepts limit (1–200, default 50), cursor (opaque, from the previous response’s nextCursor) and q (case-insensitive substring over the fields named above), and returns { "items": [...], "nextCursor": "…" | null }. Ordering is newest-first and stable.

Webhooks (Available)

MethodPathGateWhat
GET/v1/webhooks/eventstenant · webhooks:manageEvent catalog
POST / GET/v1/webhookstenant · webhooks:manageRegister (secret returned once) / list
GET / PATCH / DELETE/v1/webhooks/{id}tenant · webhooks:manageRead / update url, events, status / remove
POST/v1/webhooks/{id}/ping · /rotate-secrettenant · webhooks:manageTest event (202) · new secret (shown once)
GET/v1/webhooks/{id}/deliveries[/{deliveryId}]tenant · webhooks:manageDelivery log (?status=), one delivery with attempts + envelope
POST/v1/webhooks/{id}/deliveries/{deliveryId}/redelivertenant · webhooks:manageNew attempt chain (202)

See Webhooks for the event catalog and signature verification.

Everything else (Planned)

The remaining resource families (per-source status, tenant tile authoring) are documented here as they ship. Until then the API overview table is the roadmap.