PumpFuse Platform — REST API Reference

Platform-level REST endpoints available on every PumpFuse product.
These cover device identity, configuration, relay control, power monitoring, telemetry, and OTA firmware updates.

For product-specific REST endpoints, see the product's own REST API Reference (e.g., Watchdog REST API).

VersionDateNotes
1.02026-02-11Initial release


Base URL

http://<device-ip>/api/v1

All endpoints accept and return application/json unless otherwise noted. No authentication.


Endpoints

MethodPathDescription
GET/api/v1/infoDevice identity
GET/api/v1/statusFull runtime snapshot
GET/api/v1/configConfiguration snapshot
POST/api/v1/configUpdate configuration
GET/api/v1/relayRelay state
POST/api/v1/relaySet relay state
GET/api/v1/powerLatest power reading
GET/api/v1/telemetryTelemetry settings
POST/api/v1/telemetryUpdate telemetry settings
POST/api/v1/otaPush firmware binary

GET /api/v1/info

Returns device identity. Available in both normal and recovery modes.

Response

{
  "product": "pf-watchdog",
  "firmware": "1.0.0",
  "mac": "AA:BB:CC:DD:EE:FF",
  "ip": "192.168.40.114",
  "uptime": 3600
}
FieldTypeDescription
productstringProduct identifier (e.g., "pf-watchdog", "pf-sump")
firmwarestringFirmware version from esp_app_desc
macstringWiFi station MAC address, colon-separated uppercase hex
ipstringCurrent IP address on the WiFi network
uptimeintegerSeconds since boot

GET /api/v1/status

Returns a full runtime snapshot including connectivity, relay, power, and telemetry state.

Response

{
  "product": "pf-watchdog",
  "firmware": "1.0.0",
  "uptime": 3600,
  "ip": "192.168.40.114",
  "wifi_connected": true,
  "mqtt_connected": true,
  "relay": true,
  "power_w_last": 12.345,
  "power_sample_ts_ms": 1739260200000,
  "telemetry_active": true,
  "telemetry_interval_s": 5
}
FieldTypeDescription
productstringProduct identifier
firmwarestringFirmware version
uptimeintegerSeconds since boot
ipstringCurrent IP address
wifi_connectedbooleanWiFi station connected
mqtt_connectedbooleanMQTT broker connected
relaybooleantrue = closed (power on)
power_w_lastfloatMost recent power sample in watts
power_sample_ts_msintegerTimestamp of power sample (milliseconds since boot epoch)
telemetry_activebooleanWhether telemetry streaming is enabled
telemetry_interval_sintegerTelemetry publish interval in seconds

GET /api/v1/config

Returns current device configuration.

Response

{
  "device_name": "test-board",
  "wifi_ssid": "MyNetwork",
  "mqtt_broker": "192.168.40.164",
  "mqtt_port": 1883,
  "mqtt_topic": "pumpfuse/test-board",
  "mqtt_user": "mqtt",
  "mqtt_pass": "secret123"
}
FieldTypeDescription
device_namestringDevice display name
wifi_ssidstringStored WiFi SSID (read-only here; set via BLE provisioning)
mqtt_brokerstringMQTT broker hostname or IP
mqtt_portintegerMQTT broker port
mqtt_topicstringMQTT base topic prefix
mqtt_userstringMQTT username
mqtt_passstringMQTT password

POST /api/v1/config

Update device configuration. All fields are optional — include only the fields you want to change. Changes are persisted to NVS immediately.

Request

{
  "device_name": "living-room",
  "mqtt_broker": "10.0.0.5",
  "mqtt_port": 1883,
  "mqtt_topic": "pumpfuse/living-room",
  "mqtt_user": "mqtt",
  "mqtt_pass": "newpass"
}
FieldTypeRequiredValidation
device_namestringNoNon-empty, max 32 characters
mqtt_brokerstringNoNon-empty, max 128 characters
mqtt_portintegerNo1–65535, must be whole number
mqtt_topicstringNoNon-empty, max 128 characters
mqtt_userstringNoMax 64 characters (empty string allowed)
mqtt_passstringNoMax 64 characters (empty string allowed)

Response: Updated config JSON (same schema as GET).

Errors

StatusBodyCause
400invalid_bodyRequest body unreadable or too large
400invalid_jsonBody is not valid JSON object
400unknown_keyBody contains unrecognized key
400invalid_device_nameEmpty string or exceeds max length
400invalid_mqtt_brokerEmpty string or exceeds max length
400invalid_mqtt_portNot a number, fractional, or out of range
400invalid_mqtt_topicEmpty string or exceeds max length
400invalid_mqtt_userExceeds max length
400invalid_mqtt_passExceeds max length
400missing_mqtt_requiredMQTT change leaves broker or topic empty
500save_errorNVS write failure

Side effects:


GET /api/v1/relay

Returns current relay state.

Response

{
  "relay": true
}
FieldTypeDescription
relaybooleantrue = relay closed (power flowing), false = relay open

POST /api/v1/relay

Set relay state.

Request

{
  "relay": false
}
FieldTypeRequiredDescription
relaybooleanYestrue = close relay (power on), false = open relay (power off)

Response: Same schema as GET.

Errors

StatusBodyCause
400invalid_bodyBody unreadable
400invalid_payloadMissing relay field or not boolean

Side effects:


GET /api/v1/power

Returns the most recent power reading.

Response

{
  "power_w": 12.345,
  "ts_ms": 1739260200000
}
FieldTypeDescription
power_wfloatPower in watts (3 decimal places)
ts_msintegerSample timestamp in milliseconds (device uptime epoch)

GET /api/v1/telemetry

Returns current telemetry settings.

Response

{
  "active": true,
  "interval_s": 5
}
FieldTypeDescription
activebooleanWhether power telemetry is being published via MQTT
interval_sintegerPublish interval in seconds

POST /api/v1/telemetry

Update telemetry settings. Both fields are optional.

Request

{
  "active": true,
  "interval_s": 10
}
FieldTypeRequiredValidation
activebooleanNoMust be boolean
interval_sintegerNo1–60, must be whole number

Response: Updated telemetry JSON (same schema as GET).

Errors

StatusBodyCause
400invalid_bodyBody unreadable
400invalid_jsonNot valid JSON object
400invalid_activeactive field is not boolean
400invalid_intervalNot a number, fractional, or out of range 1–60
500save_errorRuntime state save failure

Side effects:


POST /api/v1/ota

Push a firmware binary for over-the-air update.

Request

curl -s http://192.168.40.114/api/v1/ota \
  -X POST \
  -H "Content-Type: application/octet-stream" \
  --data-binary @build/pf-watchdog_1.0.0.bin

Response: "OK" (plain text), then the device reboots.

Side effects:


Recovery Mode

When the device enters recovery mode (failed boot or forced recovery), it starts a WiFi access point and exposes a minimal set of endpoints.

Access Point: SSID ppp (hidden), IP 192.168.4.1, open authentication.

MethodPathDescription
GET/HTML page showing product name and firmware version
GET/hotspot-detect.htmliOS captive portal redirect → /
GET/api/v1/infoSame JSON schema as normal mode (IP is always 192.168.4.1)
POST/api/v1/otaPush firmware binary (same handler as normal mode)

Recovery mode is designed for the ota-flash tool to discover and reflash unresponsive devices.


Notes

Content-Type

All JSON endpoints respond with Content-Type: application/json. The OTA endpoint expects application/octet-stream.

Error format

Error responses use plain text bodies (not JSON). The HTTP status code indicates the error class (400 for client errors, 500 for server errors), and the body contains a brief machine-readable error identifier.

Rate limiting

No rate limiting. The device processes requests serially on the HTTP server thread.

WiFi SSID

The wifi_ssid field in config is read-only via REST. WiFi credentials can only be set via BLE provisioning.