In addition to pulling HTTPS JSON feeds, ProbeHarbor accepts push ingest from ESP32, Pico W, or Arduino devices and can fan alert notifications out to Discord, SMS, web push, and generic HTTPS webhooks for IFTTT or Home Assistant. For endpoint summaries and OpenAPI download, see the HTTP API reference.
Push ingest
From Dashboard → Devices, create a push device and copy the ingest key from the callout (30 minutes, survives refresh). Sensors auto-import on first POST; manual mapping under Advanced is optional. Full walkthrough: Adding push and pull devices. Send readings with:
POST /api/ingest/<device-key>
Content-Type: application/json Classic Arduino JSON
{
"temp": {
"0": { "c": 18.5, "f": 65.3, "h": 42 },
"1": { "c": 19.0, "f": 66.2, "h": 40 }
}
} Typed multi-sensor payload
{
"sensors": [
{ "key": "garage_temp", "kind": "temperature", "value": 65.3, "unit": "F" },
{ "key": "garage_rh", "kind": "humidity", "value": 42, "unit": "%" },
{ "key": "door1", "kind": "door", "bool": true },
{ "key": "co2", "kind": "co2", "value": 820, "unit": "ppm" },
{ "key": "pm25", "kind": "pm25", "value": 12, "unit": "µg/m³" },
{ "key": "sump", "kind": "level", "value": 22, "unit": "%" }
],
"battery": 87,
"rssi": -62
}
Supported kinds: temperature, humidity, co2,
pressure, pm25, voc, level,
energy, door, power, flood,
motion, generic.
Optional top-level battery / battery_pct and rssi update device health metadata.
Sample CircuitPython, MicroPython, Arduino, Zephyr C, WCHNET C, and GNU AVR assembly sketches for DS18B20 / MAX31855 / MAX6675, plus Uno + W5100
(ethernet_dht22_ingest, classic temp JSON):
sketches/.
The Ethernet shield cannot TLS: pair it with
push_https_forward.py
on a LAN host.
SenML (RFC 8428)
If your firmware or gateway already publishes SenML JSON, POST the array directly, no wrapper object required.
ProbeHarbor auto-detects SenML when native temp / sensors[] shapes are absent.
Temperature uses unit Cel or degF; humidity uses %RH. Probe keys come from the SenML name (last path segment).
[
{ "bn": "probeharbor/garage/", "n": "0", "u": "Cel", "v": 18.5 },
{ "n": "0", "u": "%RH", "v": 42 },
{ "n": "door", "vb": true }
] Live sample: example SenML feed. Pull feeds accept the same array when the configured JSON root is missing.
Home Assistant REST sensor JSON
A single REST sensor response: state plus attributes.unit_of_measurement: is also auto-detected on push ingest and pull feeds.
Map probe key state (or the entity suffix for multi-entity payloads) on Devices.
{
"state": "65.3",
"attributes": {
"unit_of_measurement": "°F",
"friendly_name": "Garage temperature"
}
} Live sample: example HA REST feed. For full HA setup (HACS, MQTT bridge, indoor reference), see Home Assistant integration.
Outbound alert webhooks
Pro accounts can enable an outbound webhook in alert settings. Each alert POSTs JSON:
{
"title": "Garage temperature alert",
"body": "Probe 1 is 31.2°F …",
"kind": "threshold",
"sent_at": "2026-08-25T12:00:00.000Z"
} kind may be threshold, rate, outage,
forecast, rule, digest, or generic.
When a webhook secret is set, the request includes
X-Signature as a hex HMAC-SHA256 of the raw body. Use that in Home Assistant
or IFTTT Webhooks to verify authenticity.
Home Assistant
Install the official HACS integration for share-link sensors and snooze/vacation services. For alerts into HA, use the outbound HTTPS webhook (Pro) or import the blueprint. For MQTT readings into ProbeHarbor, see the MQTT bridge recipe.
automation:
- alias: ProbeHarbor webhook
trigger:
- platform: webhook
webhook_id: probeharbor_alerts
allowed_methods:
- POST
local_only: false
action:
- service: notify.persistent_notification
data:
title: "{{ trigger.json.title }}"
message: "{{ trigger.json.body }}"
Point your ProbeHarbor outbound webhook URL at
https://<your-ha-host>/api/webhook/probeharbor_alerts
(or a Cloudflare Tunnel / Nabu Casa URL). Verify X-Signature in a template condition if you set a secret.
For MQTT, have Home Assistant (or Node-RED) receive the webhook and publish to your broker, that keeps MQTT local while ProbeHarbor stays on HTTPS. The blueprint includes an optional MQTT topic input for that path.
Grafana / Prometheus metrics
Pro accounts can create dashboard API keys (Dashboard → Share) and scrape:
GET /api/v1/metrics
Authorization: Bearer gtm_… Or use a Pro share link with the Metrics scope:
GET /api/share/<token>/readings?format=prometheus
Or ?format=grafana for a simple JSON datapoints array. History share scope returns a 7-day chart on the public page.
Alert channels
- Email and Discord (all plans)
- Telegram bot token + chat id (your credentials)
- Slack Incoming Webhook URL (your credentials)
- Browser and Android push (every plan)
- Twilio SMS, outbound webhook (Pro)
Alerts also support forecast freeze risk, quiet hours, and composite AND rules (for example door open + temperature drop). See Dashboard → Alerts.
Email alerts remain available on all plans. Weekly digests can be enabled independently of freeze/humidity threshold alerts. Opt-in city aggregates appear on /freeze-map.
Related guides
- HTTP API documentation OpenAPI download, ingest, metrics, and inbound webhooks
- Kit QR onboarding encode your ingest URL on a hardware sticker
- ESP32 OTA and battery reporting
firmware updates plus
battery/rssifields - Zapier and Make.com recipes outbound alert webhooks and inbound snooze automations
FAQ
Do I need a public IP on the Arduino?
No. Push ingest posts outbound to ProbeHarbor with a device key. Pull feeds need a reachable HTTPS JSON URL if you use that path instead.
What belongs in an ingest payload?
Temperature (and humidity) keyed by probe index, plus optional door/power fields, battery, and RSSI. Native shapes are flat keys, a temp object, or sensors[]. SenML (RFC 8428) arrays and Home Assistant REST state JSON are also auto-detected. Keep keys stable so dashboard mappings stay valid.