> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ridergy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cluster erstellen

> Erstellt einen Cluster, der mehrere Standorte unter einem optionalen
gemeinsamen kW-Cap gruppiert. Alle `locationIds` müssen dem
anfragenden Mandanten gehören.




## OpenAPI

````yaml /api-reference/energy-management/openapi.de.yaml POST /clusters
openapi: 3.1.0
info:
  title: RiDERgy Energy Management API
  version: '1.0'
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
  description: |
    Programmatische Steuerung von Ladeleistungslimits über Standorte, einzelne
    Ladepunkte, Organisationen und standortübergreifende Cluster hinweg.

    ## Authentifizierung
    Jeder Endpunkt außer `GET /health` benötigt einen `x-api-key`-Header. Der
    Schlüssel bestimmt Ihren Mandanten — er wird nie aus dem Request-Body oder
    einem anderen Header gelesen, sodass ein Schlüssel eines Mandanten nicht
    auf die Daten eines anderen Mandanten zugreifen kann.

    Ihr Mandant muss das Feature der Energy Management API aktiviert haben,
    andernfalls schlagen Anfragen mit `403 FEATURE_NOT_ENABLED` fehl.
    Kontaktieren Sie RiDERgy, um es zu aktivieren.

    ## Prioritätsmodell
    Standort- und Ladepunkt-Limits werden über **prioritätsbasierte
    Zeitfenster-Profile** gesteuert:

    - Prioritäten reichen von **0 (niedrigste) bis 10 (höchste)**, im
      OCPP-Stack-Stil.
    - Ein Ziel (Standort oder Ladepunkt-Connector) kann bis zu 11 Profile
      haben, eines pro Prioritätsstufe, jeweils mit eigenem
      `[startTime, endTime)`-Zeitfenster.
    - Zu jedem Zeitpunkt ist das **effektive Limit** der `limitKw`-Wert des
      Profils mit der höchsten Priorität, dessen Zeitfenster gerade aktiv ist.
    - Ist kein Profil aktiv, fällt ein Standort auf sein `permanentLimitKw`
      zurück.
    - Wird ein Profil mit einer Priorität übermittelt, für die für dieses Ziel
      bereits eines existiert, wird dieses **ersetzt**.
    - Profile werden automatisch zu ihrer `startTime`/`endTime` angewendet und
      wieder rückgängig gemacht — nach dem Erstellen eines Profils sind keine
      weiteren API-Aufrufe erforderlich. Profil-Datensätze werden nie gelöscht,
      sodass die Historie weiterhin abfragbar bleibt.

    ## Fehler
    Alle Fehler haben diese Form:

    ```json
    {
      "error": {
        "code": "LOCATION_NOT_FOUND",
        "message": "Location 123 was not found for the provided tenant",
        "requestId": "b1f6e6b0-..."
      }
    }
    ```
servers:
  - url: https://api.ridergy.com/v1
    description: Production
security:
  - ApiKeyAuth: []
tags:
  - name: Health
    description: Nicht authentifizierter Service-Health-Check.
  - name: Locations
    description: >-
      Lesen und Setzen von Leistungslimits und Prioritätsprofilen auf
      Standortebene.
  - name: Chargers
    description: >-
      Sperren einzelner Ladepunkt-Connectoren auf ein festes Leistungslimit für
      ein Zeitfenster.
  - name: Organizations
    description: >-
      Mandantenweite Cap-Profile (werden nur erfasst — Durchsetzung noch nicht
      aktiv).
  - name: Clusters
    description: >-
      Gruppierung von Standorten unter einem gemeinsamen kW-Limit und Anwendung
      von Zeitplänen über diese hinweg.
paths:
  /clusters:
    post:
      tags:
        - Clusters
      summary: Create a cluster
      description: |
        Erstellt einen Cluster, der mehrere Standorte unter einem optionalen
        gemeinsamen kW-Cap gruppiert. Alle `locationIds` müssen dem
        anfragenden Mandanten gehören.
      operationId: createCluster
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClusterCreateRequest'
            examples:
              example:
                value:
                  name: North Campus
                  locationIds:
                    - '3632155'
                    - '3632156'
                  limitKw: 200
      responses:
        '201':
          description: Cluster erstellt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Cluster'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/FeatureNotEnabled'
components:
  schemas:
    ClusterCreateRequest:
      type: object
      required:
        - name
        - locationIds
      properties:
        name:
          type: string
          example: North Campus
        locationIds:
          type: array
          minItems: 1
          items:
            type: string
          example:
            - '3632155'
            - '3632156'
        limitKw:
          type:
            - number
            - 'null'
          format: float
          exclusiveMinimum: 0
          description: Optionales clusterweites kW-Cap.
          example: 200
    Cluster:
      type: object
      properties:
        clusterId:
          type: string
          example: clst_20260612_a1b2c3d4
        tenantUuid:
          type: string
        name:
          type: string
          example: North Campus
        locationIds:
          type: array
          items:
            type: string
          example:
            - '3632155'
            - '3632156'
        limitKw:
          type:
            - number
            - 'null'
          example: 200
        status:
          type: string
          enum:
            - ACTIVE
            - INACTIVE
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: LOCATION_NOT_FOUND
            message:
              type: string
              example: Location 123 was not found for the provided tenant
            requestId:
              type: string
              format: uuid
  responses:
    BadRequest:
      description: Ungültiger Request-Body oder Ziel ist inaktiv
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            invalidBody:
              summary: INVALID_REQUEST_BODY
              value:
                error:
                  code: INVALID_REQUEST_BODY
                  message: limitKw must be a positive number
                  requestId: b1f6e6b0-1234-4abc-9def-000000000000
            targetInactive:
              summary: TARGET_INACTIVE
              value:
                error:
                  code: TARGET_INACTIVE
                  message: Location 123 is not active
                  requestId: b1f6e6b0-1234-4abc-9def-000000000000
    Unauthorized:
      description: Fehlender, ungültiger oder abgelaufener API-Schlüssel
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            unauthorized:
              value:
                error:
                  code: UNAUTHORIZED
                  message: Invalid or inactive API key
                  requestId: b1f6e6b0-1234-4abc-9def-000000000000
    FeatureNotEnabled:
      description: Mandant hat die Energy Management API nicht aktiviert
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            featureNotEnabled:
              value:
                error:
                  code: FEATURE_NOT_ENABLED
                  message: >-
                    The Energy Management API is not enabled for your account.
                    Contact RiDERgy to enable this feature.
                  requestId: b1f6e6b0-1234-4abc-9def-000000000000
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Mandanten-spezifischer API-Schlüssel. Der Mandant wird aus dem Schlüssel
        abgeleitet — nie aus dem Request.

````