Back

Device API · v1

M5Stack occupancy protocol

Each doorway reports persistent cumulative directional totals. DoorSync calculates only the new difference and returns the authoritative building occupancy plus the next check-in interval.

Base URL

https://project--d4ce00fd-3456-4c2e-aee0-07b3bfb30a56.lovable.app

Authentication

Every counter shares one system key, shown on the operator dashboard. Send it as a Bearer token on every request and identify the individual unit with device_id.

Authorization: Bearer occ_your_system_key
Content-Type: application/json

A device_id that has never been seen is registered automatically on its first report; the operator can rename it and set its doorway afterwards. Use a stable per-unit value such as the ESP32 MAC/UUID.

POST/api/public/v1/device/report

Report cumulative counters

Send after a person is counted and at every scheduled check-in. Both counters are totals since the device was first seen or last reset.

{
  "device_id": "m5-AABBCCDDEEFF",
  "entries": 123,
  "exits": 118,
  "firmware_version": "1.0.0",
  "rssi": -61
}

200 response

{
  "occupancy": 42,
  "checkin_time": 30,
  "accepted": { "entries": 1, "exits": 0 },
  "counter_reset": false,
  "registered": false,
  "server_time": "2026-09-11T00:00:00.000Z"
}
FieldTypeRule
device_idstringRequired, stable hardware UUID/MAC
entriesintegerRequired, cumulative, ≥ 0
exitsintegerRequired, cumulative, ≥ 0
firmware_versionstringOptional, max 40 chars
rssiintegerOptional, −150 to 10 dBm
GET/api/public/v1/device/state?device_id=…

Get current state

Use at boot, after reconnecting Wi-Fi, or any time the display needs a proactive refresh. No request body is required; the optional device_id query parameter records the check-in.

{
  "occupancy": 42,
  "checkin_time": 30,
  "server_time": "2026-09-11T00:00:00.000Z"
}

Required firmware behavior

  • Persist both cumulative counters in NVS/Preferences before sending.
  • Reuse unchanged totals when retrying. Duplicate reports are idempotent.
  • Replace the local polling interval with every valid checkin_time response.
  • Update the local display from the returned occupancy.
  • Use exponential backoff for network failures and 5xx responses.
  • Stop repeated retries on 400, 401, or 422 and surface a device error.
  • If counters decrease after a device reset, the server accepts them as a new baseline and sets counter_reset: true.

Status codes

200 accepted · 400 malformed payload · 401 invalid system key or disabled counter · 422 invalid counter or safety-limit rejection · 500 temporary server failure.

Prompt for Claude

Copy this implementation brief into Claude with your sensor and display details.

Write production Arduino/C++ firmware for an M5Stack people counter using WiFiClientSecure and ArduinoJson. Every device is flashed with the SAME shared system key; each device identifies itself with a stable device_id derived from its hardware UUID (e.g. the ESP32 efuse MAC formatted as "m5-AABBCCDDEEFF"). The server auto-registers an unknown device_id on its first report, so no manual provisioning is needed. Persist cumulative unsigned 64-bit entries and exits in Preferences/NVS so retries and reboots are safe. POST to https://project--d4ce00fd-3456-4c2e-aee0-07b3bfb30a56.lovable.app/api/public/v1/device/report with Authorization: Bearer SYSTEM_API_KEY and Content-Type: application/json. The JSON body is {"device_id":"m5-AABBCCDDEEFF","entries":123,"exits":118,"firmware_version":"1.0.0","rssi":-61}. Read occupancy and checkin_time from every successful response. Also GET https://project--d4ce00fd-3456-4c2e-aee0-07b3bfb30a56.lovable.app/api/public/v1/device/state?device_id=m5-AABBCCDDEEFF with the same Authorization header to proactively synchronize. Use the server-provided checkin_time in seconds, never reset cumulative totals after a successful request, retry with exponential backoff on network/5xx errors, do not retry 400/401/422 indefinitely, validate TLS, and never log the API key.