π Getting started: household API keys
Everything below authenticates with a household API key β a token that machines (Home Assistant, scripts, calendar apps) use instead of your login.
- Go to Account β API keys (household admins only).
- Create a key β the full key (
hp_β¦) is shown once; store it in Home Assistant'ssecrets.yaml. - Send it as the
X-API-Keyheader (or?token=for the calendar feed). Keys are scoped to your household and can be revoked anytime.
π Home Assistant
One rest_command is enough for every webhook. Add to
configuration.yaml:
# secrets.yaml
homeplanner_api_key: hp_your_key_here
# configuration.yaml
rest_command:
homeplanner_metric:
url: "https://YOUR-APP/api/v1/integrations/home-assistant/metric"
method: POST
headers: { X-API-Key: !secret homeplanner_api_key }
content_type: "application/json"
payload: "{{ payload }}"
homeplanner_energy:
url: "https://YOUR-APP/api/v1/integrations/home-assistant/energy"
method: POST
headers: { X-API-Key: !secret homeplanner_api_key }
content_type: "application/json"
payload: "{{ payload }}"
homeplanner_device:
url: "https://YOUR-APP/api/v1/integrations/home-assistant/device-status"
method: POST
headers: { X-API-Key: !secret homeplanner_api_key }
content_type: "application/json"
payload: "{{ payload }}"
HomePlanner also exposes a flat sensor document back to HA β monthly cost, energy/water/solar this month, chores due, low batteries β for REST sensors:
sensor:
- platform: rest
name: HomePlanner
resource: https://YOUR-APP/api/v1/integrations/home-assistant/sensors
headers: { X-API-Key: !secret homeplanner_api_key }
value_template: "{{ value_json.monthly_cost_total }}"
json_attributes:
- energy_month_kwh
- water_month_l
- solar_month_kwh
- low_battery_devices
- chores_due
- next_renewal_name
- next_renewal_days
scan_interval: 900
β‘ Electricity & Nord Pool spot prices
- Pick your household's elomrΓ₯de (SE1βSE4) on the Economy tab β the daily cron fetches day-ahead spot prices for every area in use automatically.
- Push consumption from HA β each reading is priced from the spot price of its hour, and the dashboard chart follows:
- alias: "HomePlanner: hourly energy"
trigger: [{ platform: time_pattern, minutes: 0 }]
action:
- service: rest_command.homeplanner_energy
data:
payload: >-
{"kwh": {{ states('sensor.house_energy_hourly') }},
"entity_id": "sensor.house_energy_hourly"}
Manual refresh / price queries: see
API docs β energy (/energy/prices,
/energy/prices/current).
π§ Water, βοΈ solar, π runtime & π§ͺ air quality
The generic metric webhook takes any reading β one object or an array.
Kinds: water (liters), solar (kWh),
runtime (hours per appliance), radon, co2,
humidity, temperature.
- Water is costed from the household's Water price / mΒ³ (Economy tab β Housing costs). Usage between 00:00β05:00 raises a possible leak warning in the daily digest.
- Solar is valued at the Nord Pool spot price of the reading's hour.
- Air quality readings bind to a room by name β the room row and the Home sensors card show the latest values. A 7-day radon average over 200 Bq/mΒ³ (Swedish reference level) is warned about in the digest.
- Runtime per appliance sums up on the dashboard β real wear, not calendar years.
- alias: "HomePlanner: hourly water"
trigger: [{ platform: time_pattern, minutes: 0 }]
action:
- service: rest_command.homeplanner_metric
data:
payload: >-
{"kind": "water", "value": {{ states('sensor.water_hourly_l') }}, "unit": "L"}
- alias: "HomePlanner: radon in the basement"
trigger: [{ platform: time_pattern, hours: "/6" }]
action:
- service: rest_command.homeplanner_metric
data:
payload: >-
{"kind": "radon", "value": {{ states('sensor.airthings_radon') }},
"room": "KΓ€llare", "unit": "Bq/m3"}
- alias: "HomePlanner: dishwasher runtime"
trigger:
- platform: state
entity_id: binary_sensor.dishwasher_running
from: "on"
to: "off"
action:
- service: rest_command.homeplanner_metric
data:
payload: >-
{"kind": "runtime", "entity_id": "diskmaskin",
"value": {{ ((as_timestamp(now()) - as_timestamp(trigger.from_state.last_changed)) / 3600) | round(2) }}}
π¨ Smoke & leak detector batteries
Report battery health; anything under 20% shows red on the dashboard, lands in the daily digest and auto-creates a "Byt batteri" chore (re-armed once the battery recovers).
- alias: "HomePlanner: smoke detector battery"
trigger: [{ platform: time_pattern, hours: "/12" }]
action:
- service: rest_command.homeplanner_device
data:
payload: >-
{"entity_id": "smoke_hall", "name": "RΓΆkdetektor hallen",
"kind": "smoke", "battery_pct": {{ states('sensor.smoke_hall_battery') }}}
π·οΈ NFC tags & chores
- Register a tag on the Chores & NFC tab and link it to a chore (and optionally a default member).
- Any scan logs the chore and awards the points:
rest_command:
homeplanner_nfc:
url: "https://YOUR-APP/api/v1/nfc/scan"
method: POST
headers: { X-API-Key: !secret homeplanner_api_key }
content_type: "application/json"
payload: "{{ payload }}"
# HA tag reader
- alias: "HomePlanner: tag scanned"
trigger: [{ platform: tag }]
action:
- service: rest_command.homeplanner_nfc
data:
payload: '{"tag_id": "{{ trigger.tag_id }}"}'
Phone shortcuts work too β POST /api/v1/nfc/scan with
the tag id. Chores can also be completed by name via
/integrations/home-assistant/chore-event
({"chore": "Diska", "member": "Anna"}) from buttons or voice.
Who gets the points?
An NFC chip can't tell who tapped it β it only carries an id. Attribution happens one of two ways:
- A default member on the tag. When you register a tag you link it to a chore and (optionally) a member to credit β every scan of that tag credits that person. Best for "one tag per person" (e.g. each kid has their own tag for the same chore).
- A member named in the scan. Pass
"member"in the scan payload (id or name) to credit whoever actually did it β this overrides the tag default. Use it when the scanner knows the person (a per-user phone shortcut, or an HA automation that maps the scanning phone to a family member).
The scan itself is authenticated by the household API key, which
identifies the household, not the individual β so one of the two above must
supply the person. A scan with no default and no member is rejected.
π Food, recipes & barcode scanning
The Food tab keeps the family's favorite recipes (with links) and a food inventory by location (Kyl/Frys/Skafferi).
Scanning barcodes
- Tap π· Scan barcode and point the camera at an EAN code. Scanning uses the browser's built-in detector β Chrome/Edge on desktop and Android work; on iPhone use Enter EAN and type the digits instead.
- An item you already have gets +1 quantity; a new item is looked up on Open Food Facts (name, brand, package size, photo) and added with quantity 1.
- Not found online? The item is still added as
Vara <EAN>β rename it in the list.
Price checking
Swedish grocery stores don't offer public product APIs, so every inventory item links to a ready-made Willys and Coop search with the item name β one tap to compare prices.
Use-it-up reminders
Items with a bΓ€st fΓΆre date show red when 3 days remain, and the daily digest lists food to use up.
API: POST /api/v1/food/scan ({"barcode": "7310865004703"}),
GET /api/v1/food/lookup/{ean}, plus normal CRUD on
/api/v1/food and /api/v1/recipes β see API docs.
π Family calendar (iCal)
Chores due, contract renewals, loan rate-binding ends, warranty expirations and renovation end-of-life dates β one feed:
https://YOUR-APP/api/v1/calendar.ics?token=hp_your_key_here
- Google Calendar: Settings β Add calendar β From URL.
- Apple Calendar: File β New Calendar Subscription.
π Alerts: Discord & email
Every user picks their own channel on Account β Alerts. The daily digest (07:00 UTC) contains chores due, renewals within 14 days, expiring warranties, leak/radon/battery warnings and β on your chosen day of month β the "time to pay" cost split.
Discord per user
- In your Discord server: channel β Edit β Integrations β Webhooks β New webhook β copy URL.
- Paste it on Account β Alerts β Discord webhook.
- Admins can set a bot name and a fallback webhook in the admin panel.
Email admin setup
A superadmin configures the provider in the admin panel β Mail settings: Resend (API key), MailChannels, or a custom JSON endpoint. Mail also powers invites, password resets, email verification and property-transfer notifications.
π³ Billing (PayPal) optional Β· superadmin
- Create a PayPal app + subscription plan, then set the secrets:
PAYPAL_CLIENT_ID,PAYPAL_CLIENT_SECRET,PAYPAL_PLAN_ID,PAYPAL_WEBHOOK_ID(wrangler secret put β¦). - Point a PayPal webhook at
/api/v1/billing/webhook/paypal. - Flip billing on in the admin panel β instance settings; trials, per-household exemptions and comps are managed there too.
π API reference
Everything on this page is plain API calls β the interactive reference lives at
/docs (generated from
openapi.json). Authenticate with
Authorization: Bearer <jwt> or X-API-Key.