Ingest API and alert webhooks

Push sensor readings into ProbeHarbor with the ingest API: native JSON, SenML, or Home Assistant REST, and send alerts to Discord, IFTTT, or Home Assistant.

Close-up of white Cat-5e Ethernet cables with RJ45 connectors
Probe JSON usually leaves the LAN over Ethernet or a nearby relay, not the public internet directly. Photo: DiscDepotDundee.co.uk. CC BY-SA 4.0

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.

Download HA blueprint (YAML)

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

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.