FireRiskHere Watch — API & webhooks
Portfolio-plan accounts can read their Watch data from their own systems and receive an HTTP call the moment an alert fires — the same events that go out by email. Everything here is read-only and scoped to your own account: your key returns your places and your alerts, nothing else.
1. Get your API key
In the Watch app, open Notifications → API & webhooks and press Generate key. The key (frh_…) is shown once — store it in your own environment (a secrets manager or environment variable). We keep only a hash; if the key is lost, generate a new one (the old one stops working immediately). Treat it like a password: anyone holding it can read your portfolio.
2. Read your data
Send the key as a bearer token. Three endpoints, all JSON:
GET /api/v1/account— plan, location cap, current count.GET /api/v1/locations— every monitored place with its current status (clear | watch | threat), the nearest listed fire and the measured distance to it, ordered most-at-risk first (the same order the app shows).GET /api/v1/alerts— your alert history, newest first. Optional?since=<epoch ms>for incremental pulls and?limit=1..1000(default 100).
curl -s https://fireriskhere.com/api/v1/locations \
-H "Authorization: Bearer $FRH_API_KEY"curl -s "https://fireriskhere.com/api/v1/alerts?since=1756000000000&limit=200" \
-H "Authorization: Bearer $FRH_API_KEY"Statuses recompute every 15 minutes from the federal incident feed; polling more often than that returns the same picture. Data is measured and past-tense — no forecast is implied.
3. Receive webhooks
Save an https:// endpoint of yours in the same app panel and press Send test. From then on, whenever a Watch alert fires for your account we POST JSON to it at the same moment the email goes out:
{"event":"new_fire", "fire":{…}, "locations":[…]}— a new fire was reported inside your alert distance.{"event":"status_change", "transitions":[…]}— places moved between clear / watch / threat, with the driving fire, measured edge distance, and the rule that decided it.{"event":"test"}— sent by the test button.
4. Verify every delivery
Each POST carries x-frh-signature: sha256=<hex> — the HMAC-SHA256 of the exact request body, keyed with the signing secret shown in the app panel. Verify before trusting; unsigned or mis-signed calls are not from us.
// Node.js — verify a delivery before trusting it
const crypto = require("node:crypto");
function verify(rawBody, signatureHeader, secret) {
// signatureHeader is the x-frh-signature value: "sha256=<hex>"
const expected = "sha256=" +
crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signatureHeader), Buffer.from(expected));
}Delivery & limits
- One attempt per alert with a 5-second timeout; a failed delivery is logged, and the email for the same alert still goes out — email is the system of record, webhooks are the integration layer.
- The API is available while the account is on the Portfolio plan; on a downgrade it stops at the next request.
- Fair use: the data changes at most every 15 minutes — please poll accordingly.
Questions or a use case the API does not cover yet? Tell us — integrations get priority support on Portfolio.