Sensor API
Any device that can make an HTTPS request can post readings here: an ESP32 or Pico W, a Pi, a script on a laptop or an iPhone Shortcut. They're stored on the Pi in SQLite and charted on the Sensors page.
Send a reading
POST https://wiki-doc.com/api/write with a JSON body:
{"name": "garage_t", "value": 18.4, "api_key": "YOUR_KEY"}
| Field | Required | Notes |
|---|---|---|
name |
yes | 1-64 letters, digits, _, - or .. A new name makes a new sensor. |
value |
yes | A number. Strings like "18.4" are fine; 0 is fine. |
api_key |
yes | One of the keys in SENSOR_KEYS in the Pi's .env. It can go in an X-API-Key header instead. |
time |
no | When it was measured, as epoch seconds or ISO 8601 (2026-11-12T09:30:00-08:00; no zone means UTC). Leave it out to use the time the Pi receives it. |
Name sensors <place>_<what>, for example garage_t, garage_rh, greenhouse_bright, so related ones sort together.
Several readings at once
Send a readings list (up to 1000). Either all of them are saved or none are.
{
"api_key": "YOUR_KEY",
"readings": [
{"name": "garage_t", "value": 18.4},
{"name": "garage_rh", "value": 52},
{"name": "garage_t", "value": 18.1, "time": 1794506880}
]
}
Replies
| Status | Body | Meaning |
|---|---|---|
| 201 | {"status": true, "saved": 3} |
Stored |
| 400 | {"status": false, "error": "..."} |
Something in the body is wrong; the error says what |
| 401 | {"status": false, "error": "missing or unknown api_key"} |
Wrong or missing key |
Examples
curl
curl -X POST https://wiki-doc.com/api/write \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_KEY" \
-d '{"name": "test_t", "value": 21.5}'
A plain form post works too: curl -d name=test_t -d value=21.5 -d api_key=YOUR_KEY https://wiki-doc.com/api/write
Python
import requests
r = requests.post(
"https://wiki-doc.com/api/write",
json={"name": "office_t", "value": 21.5},
headers={"X-API-Key": "YOUR_KEY"},
timeout=10,
)
print(r.status_code, r.json())
MicroPython (Pico W, ESP32)
import network, time, urequests
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("WIFI_NAME", "WIFI_PASSWORD")
while not wlan.isconnected():
time.sleep(0.5)
def post(name, value):
try:
r = urequests.post(
"https://wiki-doc.com/api/write",
json={"name": name, "value": value, "api_key": "YOUR_KEY"},
)
r.close()
except Exception as e:
print("post failed", e)
while True:
post("pico_t", read_temperature()) # your sensor code
time.sleep(60)
Arduino (ESP32)
#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
void post(const char* name, float value) {
WiFiClientSecure client;
client.setInsecure(); // skips certificate checks; fine for a hobby sensor
HTTPClient http;
http.begin(client, "https://wiki-doc.com/api/write");
http.addHeader("Content-Type", "application/json");
http.addHeader("X-API-Key", "YOUR_KEY");
String body = String("{\"name\":\"") + name + "\",\"value\":" + String(value, 3) + "}";
int code = http.POST(body); // 201 = stored
http.end();
}
iPhone Shortcut
Add Get Contents of URL: URL https://wiki-doc.com/api/write, Method POST, Request Body JSON with the fields name (Text), value (Number) and api_key (Text). Run it from an automation, for example every morning, to log the phone's battery level. That's what greybatt is.
Tips
- How often: once a minute is plenty for temperature or humidity. Every reading is kept, and the charts average them for long ranges.
- Keep the key off the page. Keys live in
.envon the Pi (SENSOR_KEYS, comma-separated); add a new key there and restart the wiki to hand one to a new device. - Battery devices: collect readings and send them together with
timeset, so the radio is on once instead of every minute. - Reading the data back:
/api/sensorslists every sensor with its latest value,/api/series?names=garage_t,garage_rh&range=24hreturns chart data (ranges1h 6h 24h 7d 30d 1y all), and/api/sensors/<name>.csvdownloads everything one sensor has sent. - The old address
/api/influx/writestill works and does the same thing.