FlowerHub API Documentation
This document describes the API endpoints including the complete data structures returned by each endpoint.
Base URL
https://api.portal.flowerhub.se
Authentication
All API requests (except login) require authentication via HTTP cookies set during login.
Cookie Handling
- The API authenticates via HTTP cookies (
AuthenticationandRefresh) set by thePOST /auth/loginresponse usingSet-Cookieheaders. - Clients should use an HTTP client that maintains a cookie jar (e.g.,
requests.Sessionoraiohttp.ClientSession) rather than manually copying cookie values. - Cookies are set with
HttpOnly,Secure, andSameSiteattributes;HttpOnlymeans the cookie cannot be read by scripts and should be sent automatically by the HTTP client. - For cross-site scenarios, servers may require the
Origin: https://portal.flowerhub.seheader andcredentialsenabled (cookie-based requests).
curl example:
curl \
-H "Origin: https://portal.flowerhub.se" \
-H "Cookie: Authentication=<ACCESS_TOKEN>; Refresh=<REFRESH_TOKEN>" \
"https://api.portal.flowerhub.se/asset-owner/{assetOwnerId}/withAssetId"
Notes
- The
Refreshcookie is generallyHttpOnlyand used by the server to mint a new access token; clients should not send it manually beyond relying on the cookie jar. - A
401 Unauthorizedmay trigger a refresh flow (the client can re-call/auth/refresh-token);
POST /auth/login
Authenticate a user and receive JWT tokens.
Request Body:
{
"username": "string",
"password": "string"
}
Response:
{
"user": {
"id": <number>,
"email": <string>,
"role": <number>,
"name": <string|null>,
"distributorId": <number|null>,
"installerId": <number|null>,
"assetOwnerId": <number>
},
"refreshTokenExpirationDate": <ISO-8601 datetime string>
}
Notes: IDs and roles are numeric; date-time values are ISO-8601 UTC.
Cookies Set:
- Authentication: JWT access token
- Refresh: JWT refresh token
GET /auth/refresh-token
Refresh the access token using the refresh token cookie.
Response:
{
"id": <number>,
"email": <string>,
"role": <number>,
"name": <string|null>,
"distributorId": <number|null>,
"installerId": <number|null>,
"assetOwnerId": <number>
}
Asset Owner Endpoints
GET /asset-owner/{assetOwnerId}
Get complete asset owner details including installer, distributor, asset, and compensation information.
Response:
{
"id": <number>,
"firstName": <string>,
"lastName": <string>,
"installer": {
"id": <number>,
"name": <string>
},
"distributor": {
"id": <number>,
"name": <string>
},
"asset": {
"id": <number>,
"serialNumber": <string>,
"assetModel": {
"id": <number>,
"name": <string>,
"manufacturer": <string>
}
},
"compensation": {
"status": <string>,
"message": <string>
},
"bessCompensationStartDate": <string>
}
Notes: compensation.status is typically "Qualified"; dates are in ISO format (YYYY-MM-DD).
GET /asset-owner/{assetOwnerId}/withAssetId
Get asset owner information including associated asset ID.
Response:
{
"id": <number>,
"assetId": <number>,
"firstName": <string>
}
GET /asset-owner/{assetOwnerId}/electricity-agreement
Fetch electricity agreement information for the specified asset owner.
Response:
{
"consumption": {
"stateCategory": <string>,
"stateId": <number>,
"siteId": <number>,
"startDate": <ISO-8601 datetime string>,
"terminationDate": <ISO-8601 datetime string|null>
},
"production": {
"stateCategory": <string>,
"stateId": <number>,
"siteId": <number>,
"startDate": <ISO-8601 datetime string>,
"terminationDate": <ISO-8601 datetime string|null>
}
}
Notes: stateCategory is a status label (e.g., "Active")
GET /asset-owner/{assetOwnerId}/invoice
Fetch invoice information for the specified asset owner.
Response:
An array of invoices. Invoices can contain nested sub_group_invoices (group invoice + per-site invoices) and detailed line items:
[
{
"id": <string>,
"due_date": <datetime string>,
"ocr": <string>,
"invoice_status": <string>,
"invoice_status_id": <string>,
"invoice_period": <string>,
"total_amount": <string>,
"remaining_amount": <string>,
"invoice_lines": [
{"item_id": <string>, "name": <string>, "description": <string|null>, "price": <string>, "volume": <string>, "amount": <string>, "settlements": <array|object>}
],
"invoice_pdf": <string>,
"invoice_type": <string>,
"site_id": <string>,
"sub_group_invoices": [
{
"id": <string>,
"invoice_status": <string>,
"invoice_period": <string>,
"total_amount": <string>,
"invoice_lines": [
{"item_id": <string>, "name": <string>, "price": <string>, "volume": <string>, "amount": <string>, "settlements": <array|object>}
],
"invoice_pdf": <string>,
"invoice_type": <string>,
"site_id": <string>
}
]
}
]
Notes: IDs/ocr/site_id are numeric strings; monetary and volume fields arrive as strings; invoice_pdf is a URL string; invoice_period names a month/year in natural language.
The async client returns the parsed list under the invoices key as Invoice dataclasses (with InvoiceLine children).
GET /asset-owner/{assetOwnerId}/consumption
GET /asset-owner/{assetOwnerId}/profile
Fetch profile details for the specified asset owner.
Response:
{
"id": <number>,
"firstName": <string>,
"lastName": <string>,
"mainEmail": <string>,
"contactEmail": <string|null>,
"phone": <string>,
"address": {
"street": <string>,
"postalCode": <string>,
"city": <string>
},
"accountStatus": <string>,
"installer": {
"id": <number>,
"name": <string>,
"address": {
"street": <string>,
"postalCode": <string>,
"city": <string>
}
}
}
Notes: id equals the asset owner id; typical accountStatus is "Verified".
Fetch consumption data for the specified asset owner.
Response: Array of historical readings and calculated values keyed by invoiced month:
[
{
"site_id": <string>,
"valid_from": <date string>,
"valid_to": <date string|null>,
"invoiced_month": <date string>,
"volume": <string|number>,
"type": <string>,
"type_id": <string|number>
},
{
"site_id": <string>,
"valid_from": <date string>,
"valid_to": <date string|null>,
"invoiced_month": <date string>,
"volume": <string|number>,
"type": <string>,
"type_id": <string|number>
}
]
Notes: site_id is a numerical string; valid_from/valid_to and invoiced_month are date strings (YYYY-MM-DD); type is a label (e.g., "Reading", "Calculated").
Asset Endpoints
GET /asset/{assetId}/revenue
Fetch revenue summary for the asset's last invoice.
Response:
{
"id": <number>,
"minAvailablePower": <number>,
"compensation": <number>,
"compensationPerKW": <number>
}
Notes: minAvailablePower is in kW; compensation fields are numeric and represent the last invoice’s revenue values.
GET /asset/{assetId}
Get detailed information about a specific asset including hardware specifications and status.
Response:
{
"id": <number>,
"inverter": {
"manufacturerId": <number>,
"manufacturerName": <string>,
"inverterModelId": <number>,
"name": <string>,
"numberOfBatteryStacksSupported": <number>,
"capacityId": <number>,
"powerCapacity": <number>
},
"battery": {
"manufacturerId": <number>,
"manufacturerName": <string>,
"batteryModelId": <number>,
"name": <string>,
"minNumberOfBatteryModules": <number>,
"maxNumberOfBatteryModules": <number>,
"capacityId": <number>,
"energyCapacity": <number>,
"powerCapacity": <number>
},
"fuseSize": <number>,
"flowerHubStatus": {
"status": <string>,
"message": <string>
},
"isInstalled": <boolean>
}
GET /asset-uptime/available-months/{assetId}
List months for which uptime info is available for the asset.
Response: An array of objects, one per available month:
[
{"value": <string>, "label": <string>}
]
Notes: value is in YYYY-MM format (e.g., "2025-03"); label is a human-readable month name and year (e.g., "March 2025"). Uptime measurement appears to start around March 2025, and the last element is the current month.
GET /asset-uptime/bar-chart/history/{assetId}
List monthly uptime ratios (percent) per month for the asset.
Response: An array of objects:
[
{"date": <string>, "uptime": <number>}
]
Notes: date is in YYYY-MM format; uptime is a percentage (0–100). Values may vary by month; examples include values like 100, 99, 92.
GET /asset-uptime/pie-chart/{assetId}?period=YYYY-MM
Get uptime distribution (in seconds) for the specified period.
Response: An array of objects:
[
{"name": "uptime", "value": <number>},
{"name": "downtime", "value": <number>},
{"name": "noData", "value": <number>}
]
Notes: period is required and must be in YYYY-MM format. value is measured in seconds for each category.
System Notification Endpoints
GET /system-notification/{active-flower}
Fetch a system notification
Response: - 200 OK with an empty body.
GET /system-notification/{active-zavann}
Fetch a system notification
Response: - 200 OK with an empty body.
Data Types and Status Values
FlowerHub Status Values
"Connected": System is online and functioning"Disconnected": System is offline- Other status values may exist
Error Handling
- 401 Unauthorized: Authentication required or token expired (triggers automatic refresh)
- 304 Not Modified: Resource not changed since last request
- 404 Not Found: Resource does not exist
- 500 Internal Server Error: Server error
Caching
The API uses ETag headers for caching optimization. Clients should include If-None-Match headers with subsequent requests to leverage 304 Not Modified responses.