Skip to main content

Notifications Reference

The complete contract for messages Podero delivers to your endpoint, and the APIs for managing your webhooks and reading notification content.

Webhook Management API

All endpoints require an admin API token and are scoped to a single organization. Base URL: https://api.podero.com/api/partners/v2.0/org/{org_id}/notifications/webhooks

Create a webhook

POST /webhooks Register an HTTPS endpoint and subscribe it to the given topics. The response includes a signing secret — returned once and never retrievable again.
Each call creates a new, independent webhook. A retried POST with the same URL creates a second webhook with its own secret — guard retries on your side to avoid duplicates.
Request body
string
required
The HTTPS URL to receive notifications. Must be publicly reachable with a valid TLS certificate.
string[]
default:"[]"
Topics to subscribe to. An empty list creates the webhook with no subscriptions.
Example request
201 Created

List webhooks

GET /webhooks Returns all webhooks registered for the organization, paginated (50 per page). The signing secret is never included.
200 OK

Retrieve a webhook

GET /webhooks/{webhook_id} Returns a single webhook. A webhook belonging to another organization returns 404.
200 OK

Update a webhook

PATCH /webhooks/{webhook_id} Update a webhook’s enabled state and/or its subscribed topics. Only the fields present in the request change. The endpoint URL is immutable — delete and recreate to change it.
boolean
Set to false to pause deliveries, true to resume. While disabled, messages for this webhook are dropped, not queued.
string[]
Replaces the entire subscription set. Pass an empty list to unsubscribe from all topics.
Example request
200 OK

Delete a webhook

DELETE /webhooks/{webhook_id} Remove a webhook permanently. No further deliveries are made and the webhook disappears from the listing. Response: 204 No Content

Rotate a webhook’s signing secret

POST /webhooks/{webhook_id}/rotate-secret Mint a fresh signing secret, superseding the previous one. The next delivery is signed with the new secret. The new secret is returned once in this response — store it immediately.
200 OK
After rotating, update your endpoint’s verification code to use the new secret before the next delivery arrives.

Send a test message

POST /webhooks/{webhook_id}/test Send a synthetic sample for one subscribed topic to the webhook and return the delivery outcome synchronously. The topic must be one the webhook is currently subscribed to.
string
required
The topic to test. Must be in the webhook’s current subscription set.
Example request
200 OK
string
delivered — your endpoint accepted the test (check status_code). failed — transport error (detail explains). cancelled — the webhook is disabled or was removed (detail explains).
integer | null
The HTTP status code your endpoint returned, present only when outcome is delivered.
string | null
Error or cancellation reason, present when outcome is failed or cancelled.
The HTTP response is always 200 regardless of the delivery outcome — branch on outcome, not the HTTP status.

Notification Content API

A webhook message tells you that something happened; these read endpoints tell you what is currently pending. When a device.action_required or device.information message arrives, call these to fetch the actual items to surface to your users. See acting on a notification for the integration pattern. Base URL: https://api.podero.com/api/partners/v2.0/org/{org_id}/notifications All three endpoints accept an optional owner_id query parameter. An admin token may pass any user in the organization (or omit it for org-wide results); a non-admin token is always scoped to its own user. The two list endpoints additionally filter by device_id and device_type — all three filters match the fields a webhook message’s data carries, so you can pass them straight through.

Get notification status

GET /status Counts of pending action items and unread information notifications, grouped by device type. Useful for badge counts and for deciding which list to fetch.
string (UUID)
Restrict counts to a single user’s devices. Omit for org-wide counts (admin only).
200 OK
All four device types are always present, so the shape is predictable regardless of which devices the organization owns. action_required counts pending action items (the same semantic as the per-device action_needed flag); information_available counts unread information notifications.

List pending actions

GET /actions The organization’s pending user-facing actions, newest first — every item a user still needs to act on, plus unread information notices, merged into one list. This is the endpoint to call when a device.action_required webhook message arrives.
string (UUID)
Restrict to a single user’s actions. Omit for org-wide results (admin only).
string (UUID)
Restrict to a single device’s actions.
string
Restrict to one device type: electric_vehicle, heat_pump, inverter, or wallbox.
integer
default:"50"
Page size, 1–100.
integer
default:"0"
Items to skip.
Each item is discriminated by its code:
200 OK
string
The action type. reauthenticate — the user must re-authenticate their device against the manufacturer. information — a message to show the user, carried in metadata.message.
string (UUID) | null
The device the action belongs to.
string | null
The device’s type key (electric_vehicle, heat_pump, inverter, wallbox) — the same vocabulary the status roll-up and the webhook data.device_type use.
How to resolve the action. url is the relative URL to call — it already carries the item’s ID and a signed secret query parameter bound to the notification’s owner. required_parameters names the body fields you must supply when calling it (empty for information items, which are resolved by the call alone).
The secret in a resolution link expires one hour after the response is issued. Fetch actions when you need them rather than storing resolution links.

List information notifications

GET /information The organization’s information notification history, newest first — including already-dismissed items. This is the endpoint to call when a device.information webhook message arrives.
string (UUID)
Restrict to a single user’s notifications. Omit for org-wide results (admin only).
string (UUID)
Restrict to a single device’s notifications.
string
Restrict to one device type: electric_vehicle, heat_pump, inverter, or wallbox.
integer
default:"50"
Page size, 1–100.
integer
default:"0"
Items to skip.
200 OK
boolean
Whether the user has already dismissed the notification. Call the resolution_link to dismiss it.
string (UUID) | null
The device the notification relates to, if any.
string | null
The device’s type key (electric_vehicle, heat_pump, inverter, wallbox), matching the webhook data.device_type vocabulary.

Request

Each notification is delivered as a single HTTP POST with a JSON body.

Headers

string
Always application/json.
string
Always Podero-Notifications/1.0. Identifies deliveries originating from Podero.
string
The HMAC-SHA256 signature and timestamp for the request body. Format: t=<unix_seconds>,v1=<hex sha256>. See Signatures.

Message envelope

The request body is a JSON object with the following fields:
string (UUID)
required
A stable identifier for this message. Constant across redeliveries of the same message — use it as your idempotency key to dedupe.
string
required
The topic this message belongs to, e.g. device.action_required. Branch your handling on this value. Test messages carry podero.test.
integer
required
The version of the data schema for this message_type. Within a version, data is additive — new fields may be introduced without a version bump. A breaking change to a topic’s shape is published as a new version.
string (ISO 8601)
required
When the originating event occurred, in UTC. Use this for ordering rather than the arrival time.
object
required
The topic-specific payload. Its shape depends on message_type and schema_version — see Topics.
Internal identifiers are deliberately not exposed on the wire. You will not receive Podero’s internal notification or endpoint IDs.

Topics

A topic is both what you subscribe to and the message_type carried on the wire. Topics are stable, coarse categories; the specific event rides inside data. The boundary between the two topics is who resolves the issue: an action a partner can drive to resolution through Podero’s API rides device.action_required; everything else — advisory notices, and issues the user resolves at the manufacturer — rides device.information. For both topics, data carries the device as the subject, its owner, and a reason discriminator:
string (UUID)
required
The device the message is about. Feed it straight into the Notification Content API’s device_id filter.
string
required
The kind of device: electric_vehicle, heat_pump, inverter, or wallbox — the same keys the status roll-up uses and the device_type filter accepts.
string (UUID)
required
The user who owns the device — the person who must act. Feed it straight into the Content API’s owner_id filter, or use it to deep-link the right user in your own app.
string
required
The reason discriminator — action on device.action_required, notice on device.information. See the value catalogues below.
A device needs an action that is resolvable through Podero’s API before Podero can keep steering or monitoring it. On receipt, fetch the pending items with GET /notifications/actions and resolve them via their resolution links. See the action catalogue.

action values (device.action_required)

notice values (device.information)

New action and notice values may be introduced within a schema version — treat an unknown value as “something needs attention” and fall back to the Notification Content API, which always carries ready-to-display message text and resolution links.

Signatures

Every delivery is signed so you can prove it originated from Podero and was not altered in transit.

Header format

integer
The unix timestamp (seconds) at which the request was signed. Also included in the signed string.
string
The hex-encoded HMAC-SHA256 digest. v1 names the scheme version so a future scheme can be added alongside it.

Signing scheme

The digest is computed over the timestamp and the exact request body:
To verify, recompute v1 over the raw body bytes you received and compare using a constant-time comparison. Reject the request if the timestamp is more than 300 seconds from your current time. See the Integration Guide for working code.
Always verify against the raw bytes as received — not a re-serialized copy of the parsed JSON.

Responding

Acknowledged
Any 2xx marks the delivery as successful. Only the status code is read; the response body is ignored.
Failed attempt
A non-2xx status, a redirect, a timeout, or a connection error marks the delivery as a failed attempt.
Respond within a few seconds. Podero applies short connect and read timeouts and reads only enough of your response to obtain the status code.

Delivery semantics

A message is delivered at least once. You may occasionally receive a duplicate; dedupe on message_id. See handling duplicates.
Each message is delivered on its own. Do not assume messages arrive in the order their events occurred — use occurred_at.
A message is only ever delivered to endpoints registered under the organization that owns the source event.
Deliveries go only to HTTPS endpoints with a valid certificate. Podero resolves and validates the destination on every delivery and refuses private, loopback, link-local, carrier-grade NAT, multicast, and cloud-metadata addresses.

Endpoint lifecycle

Create a webhook to register your HTTPS endpoint. The signing secret is returned once in the response — store it immediately.
Each webhook subscribes to a set of topics. A message is delivered only if the webhook is subscribed to that message’s topic. Update the webhook to change subscriptions at any time.
Update the webhook with enabled: false to pause deliveries. While disabled, messages are dropped rather than queued — they are not flushed when re-enabled. Subscriptions are preserved.
Rotate the secret to mint a fresh signing key. The new secret is returned once; update your verification code before the next delivery arrives.
Delete the webhook to stop all deliveries permanently. The webhook is removed from the listing and cannot be recovered.