AUTHORITATIVE COPY — This is the canonical
API.mdfor the LISYclock project. A mirrored read-only copy exists in../config_editor/API.md. When updating the API, edit this file first, then run../sync_api.ps1to sync both repos.
API Version: 2 Firmware Version: v2.43 Server Port: 8080
This file is the Single Source of Truth for the HTTP API between the LISYclock firmware and the Config Editor. Both projects reference this document.
When a breaking change is made:
- Increment
API_VERSIONhere - Increment
HTTP_API_VERSIONinLISYclock/main/httpserver.h - Update the Config Editor to handle the new version
- Update this document
| Version | Change |
|---|---|
| 1 | Initial versioned API. /status response includes api_version field. |
| 2 | Added /reboot, /update, GET /files, GET /files/<name>, /rename. Config Editor: "Connect Clock" button, Reboot/Update/SD-Files UI. GET /files response includes mtime (Unix timestamp). Added POST /time, DELETE /files/<name>. Added USB serial commands for config/file transfer with data framing. Unified IP/USB communication in Config Editor Clock tab. |
Connection test and firmware info.
Response: 200 OK, application/json
{
"status": "ok",
"version": "v2.42",
"api_version": 2
}version: Firmware version string (hardware-version-dependent, set ingpiodefs.h)api_version: Integer. Incremented only on breaking API changes.
Download the current config.txt from the SD card.
Response:
200 OK,text/plain— file contents (chunked transfer)404 Not Found— ifconfig.txtdoes not exist on the SD card
Upload a new config.txt to the SD card. Overwrites the existing file.
Request body: text/plain — full config file contents
Response:
200 OK,application/json:{"status":"ok"}500 Internal Server Error— if the file cannot be written
Upload an arbitrary file to the SD card root. Used for audio files etc.
URL parameter: <filename> — percent-encoded filename (no path separators, no ..)
Request body: raw file bytes
Response:
200 OK,application/json:{"status":"ok"}400 Bad Request— invalid or empty filename500 Internal Server Error— if the file cannot be written
Delete a file from the SD card root.
URL parameter: <filename> — percent-encoded filename (no path separators, no ..)
Response:
200 OK,application/json:{"status":"ok"}400 Bad Request— invalid or empty filename404 Not Found— file does not exist500 Internal Server Error— delete operation failed
Reboot the clock. Requires confirmation to prevent accidental reboots.
Request body: application/json: {"confirm":"reboot"}
Response:
200 OK,application/json:{"status":"ok"}— clock reboots immediately after response400 Bad Request— missing or wrong confirmation value
Upload a firmware binary to the SD card as update.bin, then reboot. CheckFWUpdate() applies the update on next boot.
Request body: raw binary (.bin file)
Response:
200 OK,application/json:{"status":"ok"}— clock reboots immediately after response500 Internal Server Error— if the file cannot be written
Set the system clock and RTC time from a Unix timestamp.
Request body: application/json
{"unix_timestamp": 1234567890}Response:
200 OK,application/json:{"status":"ok"}400 Bad Request— missing or invalidunix_timestamp
List all files in the SD card root directory.
Response: 200 OK, application/json
{
"files": [
{"name": "config.txt", "size": 1234, "mtime": 1741430400},
{"name": "update.bin", "size": 512000, "mtime": 0}
]
}mtime: Unix timestamp (seconds since epoch) of last modification.0if unavailable (RTC not set or filesystem limitation).
Download a file from the SD card root.
URL parameter: <filename> — percent-encoded filename (no path separators, no ..)
Response:
200 OK,application/octet-stream— file contents (chunked transfer)400 Bad Request— invalid or empty filename404 Not Found— file does not exist
Rename a file on the SD card.
Request body: application/json
{"old_name": "foo.txt", "new_name": "bar.txt"}Response:
200 OK,application/json:{"status":"ok"}400 Bad Request— missing fields or invalid filename (path separators,..)500 Internal Server Error— rename operation failed
CORS preflight handler. Returns 204 No Content with appropriate Access-Control-Allow-* headers.
All endpoints include CORS headers to allow access from file:// browser origins.
After USB connect, the editor sends 0x55 and waits for OK:READY\r\n.
| Command | Response |
|---|---|
WIFI:SET_SSID=<ssid> |
OK:SSID_SET |
WIFI:SET_PWD=<pwd> |
OK:PWD_SET |
WIFI:ENABLE |
OK:WIFI_ENABLED |
WIFI:DISABLE |
OK:WIFI_DISABLED |
WIFI:TEST |
OK:WIFI_CONNECTED=<ip> or ERR:WIFI_CONNECT_FAILED |
WIFI:STATUS |
OK:WIFI_STATUS=<yes|no>,<ssid>,<ip|none> |
TIME:SET=<unix_timestamp> |
OK:TIME_SET |
SYS:STATUS |
OK:STATUS=<version>,<api_version> |
SYS:REBOOT |
OK:REBOOTING (then ESP restarts) |
FILE:RENAME=<old>,<new> |
OK:FILE_RENAMED or ERR:RENAME_FAILED |
FILE:DELETE=<name> |
OK:FILE_DELETED or ERR:DELETE_FAILED |
| anything else | ERR:UNKNOWN_CMD |
These commands use a chunked framing protocol for multi-line/binary data transfer:
| Command | Response |
|---|---|
CONFIG:DOWNLOAD |
DATA:BEGIN=<size> ... lines ... DATA:END |
CONFIG:UPLOAD |
Expects DATA:BEGIN=<size> ... lines ... DATA:END from editor, then OK:CONFIG_SAVED or ERR:CONFIG_SAVE_FAILED |
FILE:LIST |
DATA:BEGIN=<size> ... JSON ... DATA:END |
FILE:DOWNLOAD=<name> |
BINDATA:BEGIN=<size> ... base64 lines ... BINDATA:END or ERR:FILE_NOT_FOUND |
FILE:UPLOAD=<name> |
Expects BINDATA:BEGIN=<size> ... base64 lines ... BINDATA:END from editor, then OK:FILE_SAVED or ERR:FILE_SAVE_FAILED |
Text data (config.txt, file listings):
Sender: DATA:BEGIN=<total_bytes>\r\n
<line of up to 192 bytes>\r\n (repeated)
DATA:END\r\n
Receiver: OK:DATA_RECEIVED\r\n
Binary data (SD card files):
Sender: BINDATA:BEGIN=<total_bytes>\r\n
<base64 line, up to 192 chars>\r\n (repeated, each ~144 raw bytes)
BINDATA:END\r\n
Receiver: OK:BINDATA_RECEIVED\r\n
Flow control: After every 8 lines, the receiver sends OK:CHUNK_ACK\r\n. The sender waits for this ACK before continuing (~1.5 KB per cycle, safe for ESP32 RAM).
Base64 encoding uses mbedtls (firmware) and btoa/atob (browser).
- Config.txt (~3 KB): < 1 second
- Small files (<50 KB): ~10 seconds
- Large files (>100 KB): Warning shown in UI, suggest IP mode instead
- wifi_manager is no longer used; port 80 is now free. The REST API remains on port 8080 for compatibility.
- WiFi credentials are configured in the General tab of the Config Editor and stored in
config.txtasWIFI_ENABLE,WIFI_SSID,WIFI_PWD. The "Test WiFi Connection" button in the Clock tab (USB mode) reads these values fromstate.wifiand sends them via USB. - All HTTP responses include CORS headers (
Access-Control-Allow-Origin: *). - The Config Editor warns the user if the connected firmware's
api_versiondoes not match the expected version. unix_timestamp: Seconds since 1970-01-01 00:00:00 UTC. Sets both the ESP32 system clock (settimeofday) and the DS3231 RTC (if present).