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

# Map clustering



## OpenAPI

````yaml /openapi/emsp-location/openapi.yaml get /emsp/v1/locations/clusters
openapi: 3.0.0
info:
  title: Spirii EMMS - Location Discovery API
  description: Real-time charging locations, EVSE availability, and geospatial search
  version: v1
  contact: {}
servers:
  - url: https://api.spirii.com
    description: Production
security:
  - OAuth2ClientCredentials:
      - emsp:locations:read
tags:
  - name: Locations
    description: Location discovery and search operations
paths:
  /emsp/v1/locations/clusters:
    get:
      tags:
        - Locations
      summary: Map clustering
      operationId: locations_clusters
      parameters:
        - name: token_id
          required: false
          in: query
          description: >-
            End-user token id; resolves through its token group to the reachable
            SUB networks.
          schema:
            type: string
        - name: token_group_id
          required: false
          in: query
          description: >-
            Token group id (peer to token_id); resolves to its assigned SUB
            networks.
          schema:
            type: string
        - name: start_charging_capability
          required: false
          in: query
          description: >-
            Keep only locations with an EVSE usable with this start-charging
            method. `RFID` matches a location with at least one EVSE exposing an
            RFID reader; `APP` matches one with an EVSE that can be
            remote-started. Existential (any EVSE) and availability-agnostic
            (occupied or faulted EVSEs still count).
          schema:
            type: string
            enum:
              - RFID
              - APP
        - name: vehicle_types
          required: false
          in: query
          description: >-
            Keep only locations with an EVSE that fits any of these vehicle
            types. Values are the OCPI VehicleType enum. Matches a location with
            at least one EVSE advertising ANY listed value (multi-value is OR).
            Existential (any EVSE) and availability-agnostic (occupied or
            faulted EVSEs still count).
          schema:
            type: array
            items:
              type: string
              enum:
                - MOTORCYCLE
                - PERSONAL_VEHICLE
                - PERSONAL_VEHICLE_WITH_TRAILER
                - VAN
                - SEMI_TRACTOR
                - RIGID
                - TRUCK_WITH_TRAILER
                - BUS
                - DISABLED
        - name: bounding_box
          required: true
          in: query
          description: >-
            Viewport as `SW_lat,SW_lng,NE_lat,NE_lng` (south-west then
            north-east corner).
          schema:
            example: 55.6,12.5,55.7,12.6
            type: string
        - name: zoom_level
          required: false
          in: query
          description: Zoom level for clustering granularity (1-20, default 12).
          schema:
            minimum: 1
            maximum: 20
            default: 12
            type: number
      responses:
        '200':
          description: Location clusters for the requested map viewport and zoom level.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LocationClustersResponse'
        '400':
          description: Invalid query parameters
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetailDto'
        '401':
          description: Missing or invalid credentials
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetailDto'
        '403':
          description: Insufficient scope
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetailDto'
components:
  schemas:
    LocationClustersResponse:
      type: object
      properties:
        clusters:
          description: Location clusters for map display.
          type: array
          items:
            $ref: '#/components/schemas/LocationClusterItemResponse'
      required:
        - clusters
    ProblemDetailDto:
      type: object
      properties:
        type:
          type: string
          example: about:blank
          description: >-
            URI identifying the problem type (about:blank until the docs site is
            live)
        title:
          type: string
          example: Tenant not found
        status:
          type: number
          example: 404
        detail:
          type: string
          example: No tenant exists with id 0192...c3.
        instance:
          type: string
          example: /v1/tenant/profile
        code:
          type: string
          example: tenant_not_found
          description: Stable machine-readable error code
        trace_id:
          type: string
          example: abc123def456
          description: Correlation id; matches dd.trace_id in Datadog
        timestamp:
          type: string
          example: '2026-06-10T09:30:00.000Z'
          format: date-time
        errors:
          description: Field-level validation errors (validation failures only)
          type: array
          items:
            $ref: '#/components/schemas/ProblemFieldErrorDto'
      required:
        - type
        - title
        - status
        - detail
        - instance
        - code
        - trace_id
        - timestamp
    LocationClusterItemResponse:
      type: object
      properties:
        center:
          $ref: '#/components/schemas/ClusterCenterResponse'
        count:
          type: number
          minimum: 1
          description: Number of locations in the cluster.
        zoom_level:
          type: number
          description: Zoom level the clustering ran at.
        location_id:
          type: string
          format: uuid
          description: The single location id when count = 1.
      required:
        - center
        - count
        - zoom_level
    ProblemFieldErrorDto:
      type: object
      properties:
        field:
          type: string
          example: workspace_id
        code:
          type: string
          example: is_uuid
        message:
          type: string
          example: workspace_id must be a UUID
      required:
        - field
        - code
        - message
    ClusterCenterResponse:
      type: object
      properties:
        lat:
          type: number
          description: Latitude of the cluster center.
        lon:
          type: number
          description: Longitude of the cluster center.
      required:
        - lat
        - lon
  securitySchemes:
    OAuth2ClientCredentials:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: /oauth/token
          scopes:
            emsp:locations:read: Search and view locations, EVSEs, connectors

````