{
  "components": {
    "schemas": {
      "ApiErrorCode": {
        "enum": [
          "BAD_REQUEST",
          "VALIDATION_ERROR",
          "INVALID_UUID",
          "UNAUTHORIZED",
          "FORBIDDEN",
          "ORG_CONTEXT_REQUIRED",
          "ORG_MEMBERSHIP_REQUIRED",
          "INSUFFICIENT_ORG_PERMISSIONS",
          "SUPER_ADMIN_REQUIRED",
          "NOT_FOUND",
          "CONFLICT",
          "TOO_MANY_REQUESTS",
          "PAYLOAD_TOO_LARGE",
          "SERVICE_UNAVAILABLE",
          "INTERNAL_SERVER_ERROR",
          "INVITATION_TOKEN_MISSING",
          "INVITATION_NOT_FOUND",
          "INVITATION_EXPIRED",
          "INVITATION_ALREADY_ACCEPTED",
          "INVITATION_CONFIRMATION_REQUIRED",
          "INVITATION_CONFIRMATION_INVALID",
          "EMAIL_ALREADY_REGISTERED",
          "INVALID_CREDENTIALS",
          "ACCOUNT_LOCKED",
          "CANNOT_REVOKE_CURRENT_SESSION",
          "EMAIL_CHANGE_NOT_PENDING",
          "EMAIL_CHANGE_TOKEN_EXPIRED",
          "EMAIL_CHANGE_TOKEN_INVALID",
          "INVALID_CURRENT_PASSWORD",
          "PLANT_NOT_FOUND",
          "SITE_NOT_FOUND",
          "PLANT_ALREADY_EXISTS",
          "PLANT_INVALID_STATE",
          "ESM_NOT_CONFIGURED",
          "PLANT_NOT_LINKED_TO_ESM",
          "API_KEY_NOT_FOUND",
          "MEMBER_NOT_FOUND",
          "ORGANIZATION_NOT_FOUND",
          "TRADING_NOT_ENABLED",
          "TRADING_CONFIG_INCOMPLETE",
          "ESM_URL_NOT_ALLOWED",
          "SUB_DEVICE_NOT_FOUND",
          "SUB_DEVICE_EXTERNAL_ID_TAKEN",
          "SUB_DEVICE_EXTERNAL_ID_INVALID",
          "DEVICE_TEMPLATE_NOT_FOUND",
          "DEVICE_TEMPLATE_IN_USE",
          "DEVICE_TEMPLATE_SIGNAL_INVALID",
          "DEVICE_TEMPLATE_ACTION_INVALID",
          "DEVICE_TEMPLATE_SYSTEM_READONLY",
          "DEVICE_TEMPLATE_WRONG_LEVEL",
          "COMMAND_ACTION_NOT_IN_TEMPLATE",
          "COMMAND_PARAMS_INVALID",
          "VOKE_ESM_DISABLED",
          "VOKE_ESM_CLIENT_NOT_FOUND",
          "TOKEN_VERSION_MISMATCH",
          "REFRESH_TOKEN_EXPIRED",
          "REFRESH_TOKEN_REVOKED",
          "REFRESH_TOKEN_INVALID",
          "INVITATION_VERIFY_THROTTLED",
          "INVITATION_EMAIL_MISMATCH",
          "ACCEPT_INVITE_TOKEN_INVALID_FORMAT",
          "API_KEY_SCOPES_EMPTY",
          "API_KEY_SCOPE_INVALID",
          "API_KEY_CIDR_NOT_IMPLEMENTED",
          "API_KEY_VCP_SCOPES_NOT_SUPPORTED",
          "ORIGIN_MISMATCH",
          "CSP_VIOLATION_LOGGED",
          "EXTERNAL_PLANT_ID_INVALID_FORMAT",
          "MIRROR_PLANT_READ_ONLY"
        ],
        "type": "string"
      },
      "ApiErrorResponseDto": {
        "properties": {
          "code": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ApiErrorCode"
              }
            ],
            "example": "BAD_REQUEST"
          },
          "details": {
            "description": "Optional structured details for debugging or field-level validation errors",
            "nullable": true,
            "oneOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            ]
          },
          "error": {
            "description": "HTTP error class text",
            "example": "Bad Request",
            "type": "string"
          },
          "message": {
            "description": "Human-readable error message",
            "example": "Validation failed",
            "type": "string"
          },
          "statusCode": {
            "description": "HTTP status code",
            "example": 400,
            "type": "number"
          }
        },
        "required": ["statusCode", "message", "error", "code"],
        "type": "object"
      },
      "AssetType": {
        "description": "Partner-facing energy-system role — see CreateSubDeviceDto.",
        "enum": [
          "BESS",
          "FVE",
          "METER",
          "HEAT_PUMP",
          "EV_CHARGER",
          "THERMOSTAT",
          "INVERTER",
          "GENERIC"
        ],
        "type": "string"
      },
      "CanonicalTelemetryPayloadDto": {
        "properties": {
          "availableBatteryEnergyKwh": {
            "description": "Available battery energy, kWh.",
            "nullable": true,
            "type": "number"
          },
          "batteryPowerKw": {
            "description": "Battery active power, kW. Positive = charging, negative = discharging.",
            "nullable": true,
            "type": "number"
          },
          "batteryTemperatureCelsius": {
            "description": "Battery temperature, °C.",
            "nullable": true,
            "type": "number"
          },
          "consumptionPowerKw": {
            "description": "Site consumption, kW.",
            "nullable": true,
            "type": "number"
          },
          "currentOperatingMode": {
            "description": "Current operating mode of the site.",
            "enum": [
              "STANDARD",
              "ZERO_EXPORT",
              "MAX_EXPORT",
              "PEAK_SHAVING",
              "LOCAL_OPTIMIZATION",
              "GRID_TARGET",
              "LDS_SUPPORT"
            ],
            "type": "string"
          },
          "dataQuality": {
            "description": "Data freshness/quality indicator.",
            "enum": ["GOOD", "INTERPOLATED", "STALE", "MISSING"],
            "type": "string"
          },
          "devices": {
            "description": "Optional per-device array.",
            "items": {
              "$ref": "#/components/schemas/DeviceTelemetrySampleDto"
            },
            "type": "array"
          },
          "fvePowerKw": {
            "description": "Total PV (FVE) generated power, kW.",
            "nullable": true,
            "type": "number"
          },
          "gridPowerKw": {
            "description": "Grid power, kW (sum of phases). Negative = export.",
            "nullable": true,
            "type": "number"
          },
          "socPercent": {
            "description": "Battery state of charge, percent (0-100).",
            "nullable": true,
            "type": "number"
          }
        },
        "required": [
          "gridPowerKw",
          "fvePowerKw",
          "batteryPowerKw",
          "consumptionPowerKw",
          "socPercent",
          "availableBatteryEnergyKwh",
          "batteryTemperatureCelsius",
          "currentOperatingMode",
          "dataQuality"
        ],
        "type": "object"
      },
      "DeviceTelemetrySampleDto": {
        "properties": {
          "assetType": {
            "description": "Asset class of this sub-device.",
            "enum": [
              "BESS",
              "FVE",
              "METER",
              "HEAT_PUMP",
              "EV_CHARGER",
              "THERMOSTAT",
              "INVERTER",
              "GENERIC"
            ],
            "type": "string"
          },
          "availableCapacityKwh": {
            "type": "number"
          },
          "deviceId": {
            "description": "Sub-device external ID (operator-assigned, e.g. \"BAT1\").",
            "minLength": 1,
            "type": "string"
          },
          "powerKw": {
            "description": "Active power, kW. Sign follows the asset role.",
            "type": "number"
          },
          "regulationPercent": {
            "type": "number"
          },
          "socPercent": {
            "type": "number"
          },
          "temperatureCelsius": {
            "type": "number"
          }
        },
        "required": ["deviceId", "assetType", "powerKw"],
        "type": "object"
      },
      "SubDeviceStatus": {
        "enum": ["ONLINE", "OFFLINE", "DEGRADED", "UNKNOWN"],
        "type": "string"
      },
      "VcpCommandsPagedResponseDto": {
        "properties": {
          "items": {
            "description": "Command-log rows, newest first.",
            "example": [
              {
                "commandType": "SET_MODE",
                "createdAt": "2026-05-10T12:00:00Z",
                "id": "b2f8a76e-...",
                "status": "COMPLETED"
              }
            ],
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "page": {
            "description": "1-indexed page number.",
            "type": "integer"
          },
          "pageSize": {
            "description": "Page size used.",
            "type": "integer"
          },
          "total": {
            "description": "Total matching rows across all pages.",
            "type": "integer"
          }
        },
        "required": ["items", "page", "pageSize", "total"],
        "type": "object"
      },
      "VcpConfigResponseDto": {
        "properties": {
          "activeSchedule": {
            "description": "Most recent ACTIVE / ACCEPTED / PENDING schedule, or `null`.",
            "nullable": true,
            "type": "object"
          },
          "constraints": {
            "description": "Site constraints payload (jsonb on `site_configs.constraints`).",
            "nullable": true,
            "type": "object"
          },
          "fallback": {
            "description": "Fallback configuration (jsonb on `site_configs.fallback`).",
            "nullable": true,
            "type": "object"
          },
          "modeOverride": {
            "description": "Active ad-hoc mode override (`null` when none or expired).",
            "nullable": true,
            "type": "object"
          },
          "operatingMode": {
            "description": "Operating mode (e.g. `STANDARD`, `ZERO_EXPORT`).",
            "type": "string"
          },
          "pendingCommands": {
            "description": "Up to 100 most recent PENDING / EXECUTING command-log entries.",
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "siteId": {
            "description": "Plant (site) UUID.",
            "type": "string"
          }
        },
        "required": [
          "siteId",
          "constraints",
          "fallback",
          "operatingMode",
          "activeSchedule",
          "pendingCommands"
        ],
        "type": "object"
      },
      "VcpLatestTelemetryResponseDto": {
        "properties": {
          "messageId": {
            "description": "Random UUID identifying this snapshot read.",
            "format": "uuid",
            "type": "string"
          },
          "payload": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CanonicalTelemetryPayloadDto"
              }
            ],
            "description": "9-field canonical telemetry payload."
          },
          "siteId": {
            "description": "Plant (site) UUID.",
            "format": "uuid",
            "type": "string"
          },
          "source": {
            "description": "Origin of the message. Always 'voke' for Voke-sourced events.",
            "type": "string"
          },
          "timestamp": {
            "description": "Wall-clock time of the most recent ingested reading, ISO 8601.",
            "format": "date-time",
            "type": "string"
          },
          "version": {
            "description": "VCP protocol version. Always `1.1` today.",
            "example": "1.1",
            "type": "string"
          }
        },
        "required": ["version", "messageId", "timestamp", "source", "siteId", "payload"],
        "type": "object"
      },
      "VcpMeterEntryDto": {
        "properties": {
          "chargeRegisterKwh": {
            "description": "Cumulative BESS charge energy (kWh), monotonic.",
            "type": "number"
          },
          "consumptionRegisterKwh": {
            "description": "Cumulative consumption (kWh), monotonic.",
            "type": "number"
          },
          "deviceId": {
            "description": "Sub-device externalId (e.g. \"GRID\", \"PV1\") — same identifier as `/vcp/sites` subDevices[].deviceId.",
            "example": "GRID",
            "type": "string"
          },
          "dischargeRegisterKwh": {
            "description": "Cumulative BESS discharge energy (kWh), monotonic.",
            "type": "number"
          },
          "exportRegisterKwh": {
            "description": "Cumulative exported energy (kWh), monotonic.",
            "type": "number"
          },
          "importRegisterKwh": {
            "description": "Cumulative imported energy (kWh), monotonic.",
            "type": "number"
          },
          "productionRegisterKwh": {
            "description": "Cumulative FVE production (kWh), monotonic.",
            "type": "number"
          },
          "role": {
            "description": "Functional role of this meter.",
            "enum": ["GRID", "FVE", "BESS", "CONSUMPTION"],
            "type": "string"
          }
        },
        "required": ["deviceId", "role"],
        "type": "object"
      },
      "VcpMeterReadingDto": {
        "properties": {
          "dataQuality": {
            "description": "Quality of the underlying data.",
            "enum": ["GOOD", "DEGRADED", "ESTIMATED"],
            "type": "string"
          },
          "meters": {
            "description": "Latest absolute register values per meter-bearing sub-device.",
            "items": {
              "$ref": "#/components/schemas/VcpMeterEntryDto"
            },
            "type": "array"
          },
          "readingAt": {
            "description": "When this snapshot was assembled (ISO 8601 UTC).",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": ["readingAt", "meters", "dataQuality"],
        "type": "object"
      },
      "VcpMeterReadingResponseDto": {
        "properties": {
          "readings": {
            "description": "MeterReading payloads ordered by `readingAt` ASC.",
            "items": {
              "type": "object"
            },
            "type": "array"
          }
        },
        "required": ["readings"],
        "type": "object"
      },
      "VcpMeterStateResponseDto": {
        "properties": {
          "eanCons": {
            "description": "Consumption metering-point EAN of the resolved site.",
            "example": "859182400123456789",
            "nullable": true,
            "type": "string"
          },
          "eanProd": {
            "description": "Production metering-point EAN of the resolved site.",
            "example": "859182400987654321",
            "nullable": true,
            "type": "string"
          },
          "reading": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VcpMeterReadingDto"
              }
            ],
            "description": "Latest meter reading, or null when no telemetry is fresh enough (site offline / no register-tagged signals).",
            "nullable": true
          },
          "siteId": {
            "description": "Voke site (plant) UUID the EAN resolved to.",
            "type": "string"
          }
        },
        "required": ["siteId", "eanCons", "eanProd", "reading"],
        "type": "object"
      },
      "VcpPlantListResponseDto": {
        "properties": {
          "plants": {
            "items": {
              "$ref": "#/components/schemas/VcpPlantSummaryDto"
            },
            "type": "array"
          }
        },
        "required": ["plants"],
        "type": "object"
      },
      "VcpPlantSubDeviceDto": {
        "properties": {
          "assetType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AssetType"
              }
            ],
            "description": "Partner-facing energy-system role (BESS, FVE, METER, INVERTER, …)."
          },
          "deviceId": {
            "description": "External sub-device identifier (e.g. \"BAT1\", \"PV1\"). Use this in command targets.",
            "type": "string"
          },
          "name": {
            "description": "Human-readable display name.",
            "type": "string"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SubDeviceStatus"
              }
            ],
            "description": "Operational status as last observed."
          }
        },
        "required": ["deviceId", "assetType", "name", "status"],
        "type": "object"
      },
      "VcpPlantSummaryDto": {
        "properties": {
          "eanCons": {
            "description": "Consumption metering-point EAN (odběrný EAN), 18 digits. Null when not configured for the site. Filterable via `GET /vcp/sites?ean=`.",
            "example": "859182400123456789",
            "nullable": true,
            "type": "string"
          },
          "eanProd": {
            "description": "Production metering-point EAN (výrobní EAN), 18 digits. Null when not configured for the site. Filterable via `GET /vcp/sites?ean=`.",
            "example": "859182400987654321",
            "nullable": true,
            "type": "string"
          },
          "externalPlantId": {
            "description": "Optional partner-supplied identifier set on `plants.external_plant_id` (useful for partner-side reconciliation against their own catalogue).",
            "nullable": true,
            "type": "string"
          },
          "id": {
            "description": "Plant (site) UUID.",
            "type": "string"
          },
          "name": {
            "description": "Human-readable plant name.",
            "type": "string"
          },
          "status": {
            "description": "Plant operational status (ONLINE, OFFLINE, PENDING, etc).",
            "type": "string"
          },
          "subDevices": {
            "description": "Physical sub-devices attached to this plant (cabinets, meters, inverters, batteries). Use `deviceId` as the target in device commands.",
            "items": {
              "$ref": "#/components/schemas/VcpPlantSubDeviceDto"
            },
            "type": "array"
          },
          "supportedCommands": {
            "description": "Command types this site supports given its sub-device mix. Always includes `SITE_SETPOINT`, `MODE_CHANGE`, `EMERGENCY`. Adds `BESS_*` commands if any sub-device has `assetType=BESS`, and `FVE_*` commands if any has `assetType=FVE`.",
            "example": [
              "SITE_SETPOINT",
              "MODE_CHANGE",
              "EMERGENCY",
              "BESS_CHARGE",
              "FVE_PRODUCE_MAX"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": ["id", "name", "status", "subDevices", "supportedCommands"],
        "type": "object"
      },
      "VcpScheduleListResponseDto": {
        "properties": {
          "schedules": {
            "items": {
              "$ref": "#/components/schemas/VcpScheduleSummaryDto"
            },
            "type": "array"
          }
        },
        "required": ["schedules"],
        "type": "object"
      },
      "VcpScheduleSummaryDto": {
        "properties": {
          "createdAt": {
            "description": "Created at (ISO 8601).",
            "format": "date-time",
            "type": "string"
          },
          "endTime": {
            "description": "Window end (ISO 8601).",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "Schedule UUID.",
            "type": "string"
          },
          "plantId": {
            "description": "Plant (site) UUID.",
            "type": "string"
          },
          "slotCount": {
            "description": "Number of slots in the schedule.",
            "type": "number"
          },
          "slotDurationMinutes": {
            "description": "Slot duration in minutes (typically 15).",
            "type": "number"
          },
          "slots": {
            "description": "Slot payloads in chronological order; one per slot.",
            "example": [
              {
                "mode": "STANDARD",
                "setpoint": {
                  "value": 0
                },
                "slotIndex": 0
              }
            ],
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "startTime": {
            "description": "Window start (ISO 8601).",
            "format": "date-time",
            "type": "string"
          },
          "status": {
            "description": "Lifecycle status (PENDING/ACCEPTED/ACTIVE/COMPLETED/FAILED/CANCELLED).",
            "type": "string"
          }
        },
        "required": [
          "id",
          "plantId",
          "status",
          "startTime",
          "endTime",
          "slotCount",
          "slotDurationMinutes",
          "slots",
          "createdAt"
        ],
        "type": "object"
      },
      "VcpTelemetryGranularity": {
        "enum": ["raw", "5m", "1h", "1d"],
        "type": "string"
      },
      "VcpTelemetryPointDto": {
        "properties": {
          "count": {
            "description": "Aggregation count for non-`raw` granularity (number of source rows behind this bucket). Absent on `raw` reads.",
            "type": "integer"
          },
          "timestamp": {
            "description": "Timestamp ISO 8601 (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "value": {
            "description": "Numeric metric value.",
            "type": "number"
          }
        },
        "required": ["timestamp", "value"],
        "type": "object"
      },
      "VcpTelemetryResponseDto": {
        "properties": {
          "readings": {
            "items": {
              "$ref": "#/components/schemas/VcpTelemetryPointDto"
            },
            "type": "array"
          }
        },
        "required": ["readings"],
        "type": "object"
      }
    },
    "securitySchemes": {
      "api-key": {
        "in": "header",
        "name": "X-API-Key",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "contact": {},
    "description": "Partner-facing read endpoints (`vcp:read` scope). All paths are filtered from the full Voke OpenAPI spec by the `vcp` tag.",
    "title": "Voke Partner API",
    "version": "1.0"
  },
  "openapi": "3.0.0",
  "paths": {
    "/api/v1/vcp/meter-state": {
      "get": {
        "description": "Resolves the EAN against both consumption and production EANs of sites in your organization and returns the freshest absolute register values. `reading` is null when no telemetry is fresh enough.",
        "operationId": "VcpMeterStateController_getMeterState_api/v1",
        "parameters": [
          {
            "description": "Metering-point EAN (18 digits). Matches either the consumption (`eanCons`) or production (`eanProd`) EAN of a site in your organization.",
            "in": "query",
            "name": "ean",
            "required": false,
            "schema": {
              "example": "859182400123456789",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VcpMeterStateResponseDto"
                }
              }
            },
            "description": "Latest meter state for the EAN"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["VALIDATION_ERROR"],
                          "example": "VALIDATION_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Bad Request",
                          "type": "string"
                        },
                        "message": {
                          "example": "Missing or malformed `ean` query parameter (must be 18 digits)",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Missing or malformed `ean` query parameter (must be 18 digits)"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["UNAUTHORIZED"],
                          "example": "UNAUTHORIZED",
                          "type": "string"
                        },
                        "error": {
                          "example": "Unauthorized",
                          "type": "string"
                        },
                        "message": {
                          "example": "Missing or invalid API key",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Missing or invalid API key"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["FORBIDDEN"],
                          "example": "FORBIDDEN",
                          "type": "string"
                        },
                        "error": {
                          "example": "Forbidden",
                          "type": "string"
                        },
                        "message": {
                          "example": "Insufficient API key scope",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Insufficient API key scope"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["SITE_NOT_FOUND"],
                          "example": "SITE_NOT_FOUND",
                          "type": "string"
                        },
                        "error": {
                          "example": "Not Found",
                          "type": "string"
                        },
                        "message": {
                          "example": "No site with this EAN in the API key's organization",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "No site with this EAN in the API key's organization"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["INTERNAL_SERVER_ERROR"],
                          "example": "INTERNAL_SERVER_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Internal Server Error",
                          "type": "string"
                        },
                        "message": {
                          "example": "Internal server error",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "Latest meter state for a metering-point EAN (one-call lookup)",
        "tags": ["vcp"]
      }
    },
    "/api/v1/vcp/sites": {
      "get": {
        "operationId": "VcpSitesController_list_api/v1",
        "parameters": [
          {
            "description": "Filter by metering-point EAN (18 digits). Matches either the consumption (`eanCons`) or production (`eanProd`) EAN of a site. Unknown EAN yields an empty `plants` array.",
            "in": "query",
            "name": "ean",
            "required": false,
            "schema": {
              "example": "859182400123456789",
              "pattern": "EAN_PATTERN",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VcpPlantListResponseDto"
                }
              }
            },
            "description": "Plant list"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["VALIDATION_ERROR"],
                          "example": "VALIDATION_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Bad Request",
                          "type": "string"
                        },
                        "message": {
                          "example": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["UNAUTHORIZED"],
                          "example": "UNAUTHORIZED",
                          "type": "string"
                        },
                        "error": {
                          "example": "Unauthorized",
                          "type": "string"
                        },
                        "message": {
                          "example": "Missing or invalid API key",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Missing or invalid API key"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["FORBIDDEN"],
                          "example": "FORBIDDEN",
                          "type": "string"
                        },
                        "error": {
                          "example": "Forbidden",
                          "type": "string"
                        },
                        "message": {
                          "example": "Insufficient API key scope",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Insufficient API key scope"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["SITE_NOT_FOUND"],
                          "example": "SITE_NOT_FOUND",
                          "type": "string"
                        },
                        "error": {
                          "example": "Not Found",
                          "type": "string"
                        },
                        "message": {
                          "example": "Site not found in the API key's organization",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Site not found in the API key's organization"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["INTERNAL_SERVER_ERROR"],
                          "example": "INTERNAL_SERVER_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Internal Server Error",
                          "type": "string"
                        },
                        "message": {
                          "example": "Internal server error",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "List plants (sites) accessible to the API key; optionally filter by EAN",
        "tags": ["vcp"]
      }
    },
    "/api/v1/vcp/sites/{siteId}/commands": {
      "get": {
        "operationId": "VcpSitesController_getCommands_api/v1",
        "parameters": [
          {
            "in": "path",
            "name": "siteId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1-indexed page number. Default `1`.",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Page size (max 500). Default `50`.",
            "in": "query",
            "name": "pageSize",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 500,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VcpCommandsPagedResponseDto"
                }
              }
            },
            "description": "Command-log page"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["VALIDATION_ERROR"],
                          "example": "VALIDATION_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Bad Request",
                          "type": "string"
                        },
                        "message": {
                          "example": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["UNAUTHORIZED"],
                          "example": "UNAUTHORIZED",
                          "type": "string"
                        },
                        "error": {
                          "example": "Unauthorized",
                          "type": "string"
                        },
                        "message": {
                          "example": "Missing or invalid API key",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Missing or invalid API key"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["FORBIDDEN"],
                          "example": "FORBIDDEN",
                          "type": "string"
                        },
                        "error": {
                          "example": "Forbidden",
                          "type": "string"
                        },
                        "message": {
                          "example": "Insufficient API key scope",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Insufficient API key scope"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["SITE_NOT_FOUND"],
                          "example": "SITE_NOT_FOUND",
                          "type": "string"
                        },
                        "error": {
                          "example": "Not Found",
                          "type": "string"
                        },
                        "message": {
                          "example": "Site not found in the API key's organization",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Site not found in the API key's organization"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["INTERNAL_SERVER_ERROR"],
                          "example": "INTERNAL_SERVER_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Internal Server Error",
                          "type": "string"
                        },
                        "message": {
                          "example": "Internal server error",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "Paginated command log for the site",
        "tags": ["vcp"]
      }
    },
    "/api/v1/vcp/sites/{siteId}/config": {
      "get": {
        "operationId": "VcpSitesController_getConfig_api/v1",
        "parameters": [
          {
            "in": "path",
            "name": "siteId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VcpConfigResponseDto"
                }
              }
            },
            "description": "Site config snapshot"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["VALIDATION_ERROR"],
                          "example": "VALIDATION_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Bad Request",
                          "type": "string"
                        },
                        "message": {
                          "example": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["UNAUTHORIZED"],
                          "example": "UNAUTHORIZED",
                          "type": "string"
                        },
                        "error": {
                          "example": "Unauthorized",
                          "type": "string"
                        },
                        "message": {
                          "example": "Missing or invalid API key",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Missing or invalid API key"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["FORBIDDEN"],
                          "example": "FORBIDDEN",
                          "type": "string"
                        },
                        "error": {
                          "example": "Forbidden",
                          "type": "string"
                        },
                        "message": {
                          "example": "Insufficient API key scope",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Insufficient API key scope"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["SITE_NOT_FOUND"],
                          "example": "SITE_NOT_FOUND",
                          "type": "string"
                        },
                        "error": {
                          "example": "Not Found",
                          "type": "string"
                        },
                        "message": {
                          "example": "Site not found in the API key's organization",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Site not found in the API key's organization"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["INTERNAL_SERVER_ERROR"],
                          "example": "INTERNAL_SERVER_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Internal Server Error",
                          "type": "string"
                        },
                        "message": {
                          "example": "Internal server error",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "Get current VCP site config (constraints, fallback, mode, active schedule)",
        "tags": ["vcp"]
      }
    },
    "/api/v1/vcp/sites/{siteId}/schedules": {
      "get": {
        "operationId": "VcpSitesController_listSchedules_api/v1",
        "parameters": [
          {
            "in": "path",
            "name": "siteId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Window start (ISO 8601). Defaults to `now − 7 days`.",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Window end (ISO 8601). Defaults to `now + 7 days`.",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VcpScheduleListResponseDto"
                }
              }
            },
            "description": "Schedules"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["VALIDATION_ERROR"],
                          "example": "VALIDATION_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Bad Request",
                          "type": "string"
                        },
                        "message": {
                          "example": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["UNAUTHORIZED"],
                          "example": "UNAUTHORIZED",
                          "type": "string"
                        },
                        "error": {
                          "example": "Unauthorized",
                          "type": "string"
                        },
                        "message": {
                          "example": "Missing or invalid API key",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Missing or invalid API key"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["FORBIDDEN"],
                          "example": "FORBIDDEN",
                          "type": "string"
                        },
                        "error": {
                          "example": "Forbidden",
                          "type": "string"
                        },
                        "message": {
                          "example": "Insufficient API key scope",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Insufficient API key scope"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["SITE_NOT_FOUND"],
                          "example": "SITE_NOT_FOUND",
                          "type": "string"
                        },
                        "error": {
                          "example": "Not Found",
                          "type": "string"
                        },
                        "message": {
                          "example": "Site not found in the API key's organization",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Site not found in the API key's organization"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["INTERNAL_SERVER_ERROR"],
                          "example": "INTERNAL_SERVER_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Internal Server Error",
                          "type": "string"
                        },
                        "message": {
                          "example": "Internal server error",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "List schedules for a site within a time window; defaults to 7 days back / 7 days ahead",
        "tags": ["vcp"]
      }
    },
    "/api/v1/vcp/sites/{siteId}/telemetry": {
      "get": {
        "operationId": "VcpSitesController_queryTelemetry_api/v1",
        "parameters": [
          {
            "in": "path",
            "name": "siteId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Metric name (e.g. `BAT1/BAT_C`, `GRID/AC_WR`). Required — partners must select one metric per request to keep response size bounded.",
            "in": "query",
            "name": "metric",
            "required": true,
            "schema": {
              "maxLength": 200,
              "minLength": 1,
              "type": "string"
            }
          },
          {
            "description": "Window start (ISO 8601 UTC).",
            "in": "query",
            "name": "from",
            "required": true,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Window end (ISO 8601 UTC).",
            "in": "query",
            "name": "to",
            "required": true,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Aggregation granularity. `raw` reads from the `telemetry` hypertable; `5m`/`1h`/`1d` read from continuous aggregates. Default: `raw`.",
            "in": "query",
            "name": "granularity",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/VcpTelemetryGranularity"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VcpTelemetryResponseDto"
                }
              }
            },
            "description": "Telemetry points"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["VALIDATION_ERROR"],
                          "example": "VALIDATION_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Bad Request",
                          "type": "string"
                        },
                        "message": {
                          "example": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["UNAUTHORIZED"],
                          "example": "UNAUTHORIZED",
                          "type": "string"
                        },
                        "error": {
                          "example": "Unauthorized",
                          "type": "string"
                        },
                        "message": {
                          "example": "Missing or invalid API key",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Missing or invalid API key"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["FORBIDDEN"],
                          "example": "FORBIDDEN",
                          "type": "string"
                        },
                        "error": {
                          "example": "Forbidden",
                          "type": "string"
                        },
                        "message": {
                          "example": "Insufficient API key scope",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Insufficient API key scope"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["SITE_NOT_FOUND"],
                          "example": "SITE_NOT_FOUND",
                          "type": "string"
                        },
                        "error": {
                          "example": "Not Found",
                          "type": "string"
                        },
                        "message": {
                          "example": "Site not found in the API key's organization",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Site not found in the API key's organization"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["INTERNAL_SERVER_ERROR"],
                          "example": "INTERNAL_SERVER_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Internal Server Error",
                          "type": "string"
                        },
                        "message": {
                          "example": "Internal server error",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "Query telemetry for a metric over a time range; optional aggregation (5m/1h/1d) reads continuous aggregates",
        "tags": ["vcp"]
      }
    },
    "/api/v1/vcp/sites/{siteId}/telemetry/latest": {
      "get": {
        "operationId": "VcpSitesController_getLatestTelemetry_api/v1",
        "parameters": [
          {
            "in": "path",
            "name": "siteId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VcpLatestTelemetryResponseDto"
                }
              }
            },
            "description": "Latest telemetry snapshot"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["VALIDATION_ERROR"],
                          "example": "VALIDATION_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Bad Request",
                          "type": "string"
                        },
                        "message": {
                          "example": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["UNAUTHORIZED"],
                          "example": "UNAUTHORIZED",
                          "type": "string"
                        },
                        "error": {
                          "example": "Unauthorized",
                          "type": "string"
                        },
                        "message": {
                          "example": "Missing or invalid API key",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Missing or invalid API key"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["FORBIDDEN"],
                          "example": "FORBIDDEN",
                          "type": "string"
                        },
                        "error": {
                          "example": "Forbidden",
                          "type": "string"
                        },
                        "message": {
                          "example": "Insufficient API key scope",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Insufficient API key scope"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["SITE_NOT_FOUND"],
                          "example": "SITE_NOT_FOUND",
                          "type": "string"
                        },
                        "error": {
                          "example": "Not Found",
                          "type": "string"
                        },
                        "message": {
                          "example": "Site not found in the API key's organization",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Site not found in the API key's organization"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["INTERNAL_SERVER_ERROR"],
                          "example": "INTERNAL_SERVER_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Internal Server Error",
                          "type": "string"
                        },
                        "message": {
                          "example": "Internal server error",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "Latest snapshot of grid / FVE / inverter / battery for the site",
        "tags": ["vcp"]
      }
    },
    "/api/v1/vcp/sites/{siteId}/telemetry/meter": {
      "get": {
        "operationId": "VcpSitesController_getMeterHistory_api/v1",
        "parameters": [
          {
            "in": "path",
            "name": "siteId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "ISO start of the meter-reading window. Max 48h before `to`.",
            "in": "query",
            "name": "from",
            "required": true,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "ISO end of the meter-reading window. Defaults to now.",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VcpMeterReadingResponseDto"
                }
              }
            },
            "description": "Meter readings"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["VALIDATION_ERROR"],
                          "example": "VALIDATION_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Bad Request",
                          "type": "string"
                        },
                        "message": {
                          "example": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Invalid path or query parameters (e.g. malformed UUID, bad ISO date)"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["UNAUTHORIZED"],
                          "example": "UNAUTHORIZED",
                          "type": "string"
                        },
                        "error": {
                          "example": "Unauthorized",
                          "type": "string"
                        },
                        "message": {
                          "example": "Missing or invalid API key",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Missing or invalid API key"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["FORBIDDEN"],
                          "example": "FORBIDDEN",
                          "type": "string"
                        },
                        "error": {
                          "example": "Forbidden",
                          "type": "string"
                        },
                        "message": {
                          "example": "Insufficient API key scope",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Insufficient API key scope"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["SITE_NOT_FOUND"],
                          "example": "SITE_NOT_FOUND",
                          "type": "string"
                        },
                        "error": {
                          "example": "Not Found",
                          "type": "string"
                        },
                        "message": {
                          "example": "Site not found in the API key's organization",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Site not found in the API key's organization"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiErrorResponseDto"
                    },
                    {
                      "properties": {
                        "code": {
                          "enum": ["INTERNAL_SERVER_ERROR"],
                          "example": "INTERNAL_SERVER_ERROR",
                          "type": "string"
                        },
                        "error": {
                          "example": "Internal Server Error",
                          "type": "string"
                        },
                        "message": {
                          "example": "Internal server error",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Internal server error"
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "Query meter readings (max 48h window)",
        "tags": ["vcp"]
      }
    }
  },
  "servers": [],
  "tags": [
    {
      "description": "VCP REST integration endpoints",
      "name": "vcp"
    }
  ]
}
