Skip to content

API

API reference

Base URL: http://127.0.0.1:18086 (or https://… when EDGE_TLS=1).

When EDGE_API_TOKEN is set, send Authorization: Bearer <token> (or X-Edge-Token / ?token= for SSE) on /v1/*. /healthz, /readyz, /version, /metrics, and /ui/* stay public. See PRODUCTION.md.

When EDGE_RATE_LIMIT_RPS is set (0 = disabled, the default), requests over the per-client-IP token-bucket limit get 429 {"error":"rate limited"} with a Retry-After header — checked ahead of auth, so it also throttles repeated bad-token attempts.

← Docs hub


All paths return JSON unless noted (SSE for */stream endpoints).

Health

Method Path Response
GET /healthz { "status": "ok", …, "tls": true/false, "auth_required": true/false, "modules": [...] }
GET /readyz 200 when stores + publish target configured; else 503 { "status": "not_ready", "reason": "…" }
GET /version { "product": "relay-edge", "version": "…" }
GET /metrics Prometheus text (prometheus/client_golang-backed): relay_edge_up, relay_edge_uptime_seconds, relay_edge_http_requests_total, relay_edge_http_errors_total, relay_edge_publishes_total, relay_edge_http_request_duration_seconds (histogram, labeled by method/route pattern), plus standard go_*/process_* runtime series
GET /v1/admin/config Runtime publish wiring + TLS/meta (tokens masked as *_set; includes auth_required)
PUT /v1/admin/config Update gateway/relay URLs, tokens, project, relay_tls_insecure (persisted)
GET /v1/admin/logs?n=200 Recent process log lines
POST /v1/admin/probe Probe edge path + gateway /healthz + Relay /healthz

Modules include seasons, sites, zones, devices, contacts, telemetry, stages, firewater, remote-edge, fleet, ui (simulator modules respect EDGE_ENABLED_FAMILIES).


Stamping pipeline

Every publish (farm season API or simulator) runs resolveEnrich → stampData before Relay sees the payload.

Resolution order: season → site (via season.site_id) → contact (site routing: farmer → operator → agronomist → ehs → control_room) → zone (zone_id or code/name match) → device (device_id or first device in zone).

Fields added to data:

Field When
season_id, season_name, crop, stage Always
site, site_id Season linked to site
zone, zone_id Zone resolved
device_id, fasal_device_id Device resolved
recipient, sms_recipient, email_recipient From routed contact; fallback demo-device-token
label_{key} From season labels
verification_probe From zone telemetry when not already set
recommended_action When command present — { target, command, payload }
sim_domain Simulator publishes only

Action targets: farm-controller, firewater-controller, remote-edge-controller, fleet-controller.

Implementation: internal/httpapi/server.go, internal/httpapi/sim_publish.go.


Farm domain

Sites & zones

Method Path Notes
GET/POST /v1/sites List / create
GET/PUT/DELETE /v1/sites/{id} CRUD
PUT /v1/sites/{id}/routing { "routing": { "farmer": "contact_id", … } }
GET/POST /v1/sites/{id}/zones Zones under site
GET /v1/zones All zones (?site_id= filter)
GET/PUT/DELETE /v1/zones/{id} Zone CRUD
GET/PUT/DELETE /v1/zones/{id}/telemetry Verification probe for Act

Devices & contacts

Method Path Notes
GET/POST /v1/devices ?zone_id= filter
GET/PUT/DELETE /v1/devices/{id} Includes external_id, commands
GET/POST /v1/contacts FCM, SMS, email
GET/PUT/DELETE /v1/contacts/{id}

Seasons

Method Path Notes
GET/POST /v1/seasons Prefer site_id
GET/PUT/DELETE /v1/seasons/{id}
POST /v1/seasons/{id}/open → active, publishes advisory
POST /v1/seasons/{id}/close → closed
POST /v1/seasons/{id}/stage { "stage": "vegetative" }
POST /v1/seasons/{id}/advisories Typed advisory publish
POST /v1/seasons/{id}/events Critical event — season must be active

Critical event body

{
  "type": "irrigation.required",
  "severity": "critical",
  "command": "irrigation.start",
  "zone_id": "zone_abc",
  "device_id": "dev_valve",
  "data": { "duration_minutes": 15 }
}

Firewater

Method Path Purpose
GET /v1/firewater/catalog 47 sensor point definitions
GET /v1/firewater/snapshot Live readings
GET /v1/firewater/events Recent derived events log
GET /v1/firewater/stream SSE ticks + events
POST /v1/firewater/seed Idempotent plant inventory + shared season season_fw_watch
POST /v1/firewater/config { "publish", "interval_ms", "scenario", "telemetry_always", … }
POST /v1/firewater/start / stop / tick / scenario Simulator control
GET /v1/firewater/ready System ready + why not
GET /v1/firewater/topology Pipe graph
GET /v1/firewater/matrix Cause-and-effect rules
POST /v1/firewater/act { "command": "pump.start" }
GET /v1/firewater/verify?command=… Post-act probe
GET /v1/firewater/alarms Standing alarms
POST /v1/firewater/alarms/{id}/ack Ack alarm
POST /v1/firewater/alarms/{id}/shelve { "minutes": 15 }
GET /v1/firewater/sparkplug Sparkplug B NDATA
GET /v1/firewater/modbus Holding registers from 40001
POST /v1/firewater/weekly-test NFPA 25 evidence

Remote edge

Method Path Purpose
GET /v1/remote-edge/catalog Asset catalog
GET /v1/remote-edge/snapshot Readings + link mode + publish state
GET /v1/remote-edge/config Current { publish, interval_ms }
GET /v1/remote-edge/events Recent derived events log
GET /v1/remote-edge/stream SSE live ticks + events
POST /v1/remote-edge/config { "publish": true, "interval_ms": 2000 }
POST /v1/remote-edge/tick / start / stop / scenario Simulator control

Scenarios: nominal, sat_down, offline, gpu_hot, drone_patrol, intrusion, flood, p5g_load.


Fleet

Method Path Purpose
GET /v1/fleet/catalog Classes + device list
GET /v1/fleet/snapshot Readings by class + publish state
GET /v1/fleet/config Current { publish, interval_ms }
GET /v1/fleet/events Recent derived events log
GET /v1/fleet/stream SSE live ticks + events
POST /v1/fleet/config { "publish": true, "interval_ms": 2000 }
POST /v1/fleet/tick / start / stop / scenario Simulator control

Scenarios: nominal, blackout, intrusion, spill, amr_lost, ot_storm, heatwave, flood.


Web UIs

Path Description
GET /ui Fire-water control room
GET /ui/remote-edge.html Remote edge fleet
GET /ui/fleet.html Master edge catalog (77 devices / 18 classes)
GET /ui/docs.html Documentation & stack test summary

Static assets are embedded in the binary (web/embed.go).


Configuration

All environment variables → Configuration reference.