> ## 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.

# Remove a location from a cluster

> Removes one location from a cluster's `locationIds`. This is an
atomic alternative to `PATCH /clusters/{clusterId}` with a shortened
`locationIds` array, so concurrent removals cannot race each other.

A cluster must always have at least one member location. Removing
the last one fails with `400 CLUSTER_EMPTY`. Delete the cluster
instead with `DELETE /clusters/{clusterId}`.




## OpenAPI

````yaml api-reference/energy-management/openapi.en.yaml DELETE /clusters/{clusterId}/locations/{locationId}
openapi: 3.1.0
info:
  title: RiDERgy Energy Management API
  version: '1.0'
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
  description: >
    Programmatic control of charging power limits across locations, individual

    chargers, organizations, and cross-location clusters.


    ## Authentication

    Every endpoint except `GET /health` and `POST /oauth/token` requires a

    Bearer token obtained via the OAuth 2.0 client_credentials flow:


    1. Create OAuth client credentials in the RiDERgy dashboard.

    2. Exchange them for a short-lived access token via `POST /oauth/token`.

    3. Pass the token as `Authorization: Bearer <token>` on every request.


    Tokens expire after 3600 seconds. Your tenant is embedded in the token

    and cannot be spoofed. Credentials for one tenant cannot access another.


    Your tenant must have the Energy Management API feature enabled, otherwise

    requests fail with `403 FEATURE_NOT_ENABLED`. Contact RiDERgy to enable it.


    ## Scopes

    Tokens carry scopes that control which endpoints are accessible:

    `locations:read`, `locations:write`, `clusters:read`, `clusters:write`,

    `chargers:write`, `org:write`. Requests to endpoints requiring a scope

    the token does not have will fail with `403 INSUFFICIENT_SCOPE`.


    ## Priority model

    Location and charger limits are controlled via **priority-windowed
    profiles**:


    - Priorities range from **0 (lowest) to 10 (highest)**, OCPP-stack-style.

    - A target (location or charger connector) can have up to 11 profiles, one
      per priority level, each with its own `[startTime, endTime)` window.
    - At any moment, the **effective limit** is the `limitKw` of the
      highest-priority profile whose window is currently active.
    - If no profile is active, a location falls back to its `permanentLimitKw`.

    - Submitting a profile at a priority that already has one for that target
      **replaces** it.
    - Profiles are applied and reverted automatically at their
      `startTime`/`endTime`. No further API calls are needed once a profile is
      created. Profile records are never deleted, so history remains queryable.

    ## Errors

    All errors share this shape:


    ```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:
  - BearerAuth: []
tags:
  - name: Auth
    description: OAuth 2.0 token endpoint for the client_credentials grant.
  - name: Health
    description: Unauthenticated service health check.
  - name: Locations
    description: Read and set location-level power limits and priority profiles.
  - name: Chargers
    description: >-
      Lock individual charger connectors to a fixed power limit for a time
      window.
  - name: Organizations
    description: Tenant-wide cap profiles (recorded only, enforcement not yet active).
  - name: Clusters
    description: Group locations under a shared kW cap and apply schedules across them.
paths:
  /clusters/{clusterId}/locations/{locationId}:
    delete:
      tags:
        - Clusters
      summary: Remove a location from a cluster
      description: |
        Removes one location from a cluster's `locationIds`. This is an
        atomic alternative to `PATCH /clusters/{clusterId}` with a shortened
        `locationIds` array, so concurrent removals cannot race each other.

        A cluster must always have at least one member location. Removing
        the last one fails with `400 CLUSTER_EMPTY`. Delete the cluster
        instead with `DELETE /clusters/{clusterId}`.
      operationId: removeClusterLocation
      parameters:
        - $ref: '#/components/parameters/ClusterId'
        - $ref: '#/components/parameters/LocationId'
      responses:
        '200':
          description: Location removed, updated cluster returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Cluster'
        '400':
          description: The cluster only has one location left
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                clusterEmpty:
                  summary: CLUSTER_EMPTY
                  value:
                    error:
                      code: CLUSTER_EMPTY
                      message: >-
                        Cannot remove the last location from a cluster; delete
                        the cluster instead
                      requestId: b1f6e6b0-1234-4abc-9def-000000000000
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/FeatureNotEnabled'
        '404':
          description: Cluster not found, or the location is not a member of it
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                clusterNotFound:
                  summary: CLUSTER_NOT_FOUND
                  value:
                    error:
                      code: CLUSTER_NOT_FOUND
                      message: Cluster clst_20260612_a1b2c3d4 not found
                      requestId: b1f6e6b0-1234-4abc-9def-000000000000
                clusterLocationNotFound:
                  summary: CLUSTER_LOCATION_NOT_FOUND
                  value:
                    error:
                      code: CLUSTER_LOCATION_NOT_FOUND
                      message: >-
                        Location 3632155 is not a member of cluster
                        clst_20260612_a1b2c3d4
                      requestId: b1f6e6b0-1234-4abc-9def-000000000000
components:
  parameters:
    ClusterId:
      name: clusterId
      description: The cluster's unique identifier, returned when the cluster was created.
      in: path
      required: true
      schema:
        type: string
      example: clst_20260612_a1b2c3d4
    LocationId:
      name: locationId
      description: The location's unique identifier.
      in: path
      required: true
      schema:
        type: string
      example: '3632155'
  schemas:
    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:
    Unauthorized:
      description: Missing, invalid, or expired Bearer token
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            unauthorized:
              value:
                error:
                  code: UNAUTHORIZED
                  message: Invalid or expired token
                  requestId: b1f6e6b0-1234-4abc-9def-000000000000
    FeatureNotEnabled:
      description: Tenant does not have the Energy Management API enabled
      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:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >
        OAuth 2.0 access token obtained via `POST /oauth/token` with
        client_credentials grant.

        Tenant and scopes are embedded in the JWT. No additional headers needed.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.