Webhooks

Webhooks

Eliq’s webhook solution allows event delivery to Utility API via custom endpoints

Webhooks

Introduction

Eliq offers a webhook solution which enables Eliq to send events to Utility API. To enable this, the utility would need to implement custom endpoints that Eliq can send webhook events to. The various types of webhook events can either be sent to the same endpoint, or to different endpoints. All webhook events are sent using POST.

Security

Endpoints must use HTTPS and can optionally use Basic HTTP Authentication or OAuth2.

Signature verification

Eliq signs all webhook events and sends the signature in the X-Eliq-Signature HTTP header. This allows your application to verify that Eliq generated the event. The X-Eliq-Signature HTTP header contains a timestamp and a signature. Timestamp is prefixed with t= and signature prefixed with the scheme used for signing the data. The current supported scheme is SHA256, and will be prefixed with sha256.

X-Eliq-Signature:
t=1591091590,
sha256=c39a4c26da13cba4258b698a3f849242af7d2e7b7559c50d0a94917355ff9532

Note: The signature is a hash-based message authentication code (HMAC) with SHA-256.

Verify signature

Eliq will generate a secret which is shared with the utility. That secret can be used to verify the signature. Below shows how the verification is done.

Step 1: Create signed payload

The signature includes the timestamp available in the X-Eliq-Signature HTTP header and the JSON string payload from the request body. To verify the signature, the timestamp and JSON string should be joined as follows:

{timestamp}.{json_payload}
Step 2: Compute expected signature

Compute an HMAC with the SHA256 hash function. Use your secret as the key and sign the payload generated in step 1.

Step 3: Compare expected signature

Compare signature received in X-Eliq-Signature HTTP header and your computed signature.

Retry policy

Eliq will retry to send events for a few times, with decreasing frequency, until the endpoint returns a 2xx status code within 10 seconds or until 24 hours have passed. A new timestamp and hash for the signature is generated for every retry. The Utility API must be able to handle duplicate events. Duplicate events can be detected by storing which event ids have been received.

Event payload

All events sent in the request body will have the same model structure. The event object will always include id, created_date (in UTC), type and object. The event.type defines how the event.object will look and how it should be parsed.

{
    "id": "a7b76b9f-ea64-4fd0-94db-624787fcb734",
    "created_date": "2020-01-01T21:23:00Z",
    "type": "{event_type}",
    "object": {
        ...
    }
}

Notification created

Notifications are defined as notifications that should be sent to the end user. In a white label solution, this is handled by sending push, SMS or email messages to the end user. In an API solution, Eliq does not have the ability to contact end users directly. However, the notifications that should have been sent out can be sent to the utility. The event.type for these events are notification_created.

The structure of the notification_created object model always includes a location_id, location_ext_ref, type and object. The notification_created.type defines how the notification_created.object will look and how it should be parsed.

{
    "id": "a7b76b9f-ea64-4fd0-94db-624787fcb734",
    "created_date": "2020-01-01T21:23:00Z",
    "type": "notification_created",
    "header": "{notification_header}",
    "content": "{notification_content}",
    "object": {
        "client_id": 123456789,
        "location_id": 1234,
        "location_ext_ref": "{location_ext_ref}",
        "type": "{notification_type}",
        "object": {
            ...
        }
    }
}
Field Type Description
client_id Number Id of client
location_id Number Id of location
location_ext_ref String External reference of location
type String Type of notification
header String Top level of the event, next to type. Title of the notification in the location's language, based on the client's configured notification texts
content String Top level of the event, next to type. Text of the notification in the location's language, based on the client's configured notification texts.
object Object Dynamic object changes depending on type of notification

‍

Event types

The following event types are supported.

Every event is a notification_created event. object.type tells you which notification it is and how to read the inner object.

object.typeFeatureSent whenInner object
budget_weeklyBudgetsA weekly budget ends under budget, is exceeded, or is forecast to be exceededThe budget, as in the Insights API
budget_monthlyBudgetsThe same, for a monthly budgetThe budget, as in the Insights API
daily_anomalyAnomaliesYesterday’s consumption was unusually high or lowAnomaly type, fuel and status
monthly_anomalyAnomaliesThis month’s consumption is unusually highAnomaly type, fuel and status
market_price_next_day_avg_priceMarket PricesTomorrow’s average price is unusually low or high. Sent at 17:00 Stockholm timePrice level, average price, and the highest and lowest hour
market_price_next_day_high_peakMarket PricesTomorrow has a price peak. Sent at 17:00 Stockholm timeThe peak hour and its price
market_price_next_day_le_zeroMarket PricesTomorrow has prices at or below zero. Sent at 17:00 Stockholm timeThe date and type
monthly_insightMonthly ReportLast month’s consumption is available for the locationFuel and period. The wrapper also has sent_language and message, and no client_id
connection_action_requiredEliq ConnectA connection needs the user to actThe connection id
connection_first_data_receivedEliq ConnectThe first data has arrived for a new connectionThe connection id

Notifications reach your endpoint only for the types enabled for your client. To enable a type, or if you receive a type not listed here, contact Eliq.

Handling events

  • Verify the X-Eliq-Signature header before you trust the payload.
  • Return a 2xx within 10 seconds, then process the event asynchronously.
  • Store event ids: Eliq retries for up to 24 hours, so the same event can arrive more than once.
  • Ignore types you do not handle, so new types never break your endpoint.

The sections below show a full example payload for each type.

Budget notification

budget_weekly and budget_monthly are sent in three cases: the budget is exceeded, the period ends under budget, or the forecast shows the budget will go over the limit (at most once per period). The payload is the same for all three. Read status.result in the budget object to tell them apart: above, completed_below or forecasted_above.budget_weekly and budget_monthly. This is sent when a weekly or monthly budget is either completed and under budget, or if budget exceeds the limit. A notification can also be sent if the forecast indicates that the user will exceed the limit.

The budget object will be the same as in API V3 and will look as follows:

{
    "id": "a7b76b9f-ea64-4fd0-94db-624787fcb734",
    "created_date": "2025-06-25T06:00:00Z",
    "type": "notification_created",
    "header": "You stayed below your weekly budget",
    "content": "Well done! Your electricity costs last week were 97% below your budget.",
    "object": {
        "client_id": 123456789,
        "location_id": 1234,
        "location_ext_ref": "{location_ext_ref}",
        "type": "budget_weekly",
        "object": {
            "enabled": true,
            "type": "budget_weekly",
            "fuel": "elec",
            "resolution": "week",
            "unit": "cost",
            "limit": 15.0,
            "suggested_limit": 0.38,
            "status": {
                "code": "ok",
                "value": 0.38,
                "forecast": 0.38,
                "period_start": "2025-06-23T00:00:00",
                "period_end": "2025-06-30T00:00:00",
                "data_until": "2025-06-25T00:00:00",
                "result": "currently_below"
            }
        }
    }
}

Anomaly notification

There are two possible notification types: daily_anomaly and monthly_anomaly. The notifications are sent if we detect that a location’s yesterday’s consumption was lower/higher than what we expect it to be or if we detect that a location’s consumption for the current month is unusually high.

The anomaly object schema looks like the following:

{
    "id": "a7b76b9f-ea64-4fd0-94db-624787fcb734",
    "created_date": "2020-01-01T21:23:00Z",
    "type": "notification_created",
    "header": "Unusually high electricity use",
    "content": "Yesterday you used more electricity than you normally do. Check the app to see what might have caused it.",
    "object": {
        "client_id": 123456789,
        "location_id": 1234,
        "location_ext_ref": "{location_ext_ref}",
        "type": "daily_anomaly",
        "object": {
            "type": "daily_anomaly",
            "fuel": "elec",
            "status": {
                "data_until": "2020-04-08T00:00:00.000",
                "result": "high"
            }
        }
    }
}

Market Price notifications

The three possible notification types for this feature are market_price_next_day_avg_price, market_price_next_day_high_peak and market_price_next_day_le_zero. They are generated and sent at 17:00 Stockholm time if there are any price alerts for the next day to send out.

The market price objects will be the same as in Insights API and will look as follows:

{
    "id": "a7b76b9f-ea64-4fd0-94db-624787fcb734",
    "created_date": "2022-11-05T13:00:00Z",
    "type": "notification_created",
    "header": "Low electricity prices tomorrow",
    "content": "Tomorrow's average price is 0,35 kr/kWh. The cheapest hour is 23:00-00:00 at 0,22 kr/kWh.",
    "object": {
        "client_id": 123456789,
        "location_id": 1234,
        "location_ext_ref": "{location_ext_ref}",
        "type": "market_price_next_day_avg_price",
        "object": {
            "level": "low",
            "abs_percentage_difference": 53,
            "avg_price_kwh": "0.3517083333333333333333333333",
            "highest_price_kwh": {
                "period_start": "2022-11-06T17:00:00",
                "price_kwh": "0.544240"
            },
            "lowest_price_kwh": {
                "period_start": "2022-11-06T23:00:00",
                "price_kwh": "0.215760"
            },
            "type": "market_price_next_day_avg_price",
            "date": "2022-11-06"
        }
    }
}
{
    "id": "a7b76b9f-ea64-4fd0-94db-624787fcb734",
    "created_date": "2022-11-03T13:00:00Z",
    "type": "notification_created",
    "header": "Price peak tomorrow",
    "content": "Electricity is most expensive tomorrow between 19:00-20:00, at 2,32 kr/kWh. Try to move your usage to another time.",
    "object": {
        "client_id": 123456789,
        "location_id": 1234,
        "location_ext_ref": "{location_ext_ref}",
        "type": "market_price_next_day_high_peak",
        "object": {
            "highest_price_period_start": "2022-11-04T19:00:00",
            "highest_price_kwh": "2.323090",
            "type": "market_price_next_day_high_peak",
            "date": "2022-11-04"
        }
    }
}

Monthly Report notifications

Monthly Insights Notifications provide a concise summary of last month's energy usage. The only notification type for this feature is monthly_insight. They are generated and sent once the previous month’s consumption is available for a given location.

‍

The notification objects looks like the following:

{
    "id": "882656c3-f4bd-4b75-a954-b45c68185fba",
    "created_date": "2024-02-01T03:23:00Z",
    "type": "notification_created",
    "header": "Your consumption in January",
    "content": "You consumed 3456 kWh in January which is about the same as the same month last year. The consumption decreased 45 kWh compared to December. Check out all your insights in the app.",
    "object": {
        "location_id": 123,
        "location_ext_ref": "EXT_REF",
        "type": "monthly_insight",
        "sent_language": "sv-SE",
        "message": {
          "language":{
            "sv-SE": {
              "header": "Your consumption in January",
              "content": "You consumed 3456 kWh in January which is about the same as the same month last year. The consumption decreased 45 kWh compared to December. Check out all your insights in the app."
            }
          }
        },
        "object": {
            "type": "monthly_insight",
            "fuel": "elec",
            "period_start": "2024-01-01T00:00:00.000",
            "period_end": "2024-02-01T00:00:00.000"
        }
    }
}

Connection status updates

Eliq Connect clients are provided with two possible notification types for this feature: connection_action_required and connection_first_data_received. They are sent when the status of a connection changes.

connection_action_required
{
  "client_id": 123456789,
  "location_id": 1234,
  "location_ext_ref": "{location_ext_ref}",
  "type": "connection_action_required",
  "object": {
    "connection_id": "3AA8FC59-607E-EE11-8925-000D3A241A52",
    "type": "connection_action_required"
  }
}
connection_first_data_received
{
  "client_id": 123456789,
  "location_id": 1234,
  "location_ext_ref": "{location_ext_ref}",
  "type": "connection_first_data_received",
  "object": {
    "connection_id": "3AA8FC59-607E-EE11-8925-000D3A241A52",
    "type": "connection_first_data_received"
  }
}
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Updated on: 
Oct 23, 2026