openapi: 3.1.0
info:
  title: Archipelago Workers API
  description: |
    ## Overview

    API documentation for Archipelago Stats and WebSocket Connector services implementing the Archipelago protocol for Decentraland's communication system. This unified specification provides access to both the observability layer (Stats API) and the real-time communication layer (WebSocket Connector API).

    The Archipelago protocol clusters users into dynamic islands based on their positions, enabling efficient crowd management and scalable communication. Islands are recalculated in real-time as users move, allowing for optimal distribution of avatars and communication channels. When the maximum number of users per island is reached, the system creates overlapping islands to ensure all users can still interact.

    **Key Concepts:**
    - **Islands**: Dynamic groups of users clustered by proximity, with a configurable maximum occupancy
    - **Peers**: Individual users/avatars in the Archipelago system
    - **Parcels**: Geographic coordinates in Decentraland where users are located
    - **Real-time updates**: Islands and peer positions are continuously recalculated

    ### Services

    ### Stats Service

    The **Archipelago Stats API** provides real-time visibility into the Decentraland communication system by aggregating and exposing statistics from the Archipelago core service. This service acts as an observability layer, transforming internal system state into queryable metrics and snapshots.

    **Purpose**: Enables monitoring, debugging, and analytics of user distribution, island clustering, and system health across the metaverse.

    **Key Endpoints**: `/parcels`, `/peers`, `/islands`, `/hot-scenes`, `/core-status`

    **Use Cases**:
    - Live dashboards displaying real-time user distribution
    - System monitoring and health tracking
    - Analytics tools for crowd patterns and trending scenes
    - Developer tools for debugging communication issues

    All data is provided in real-time and reflects the current state of the Archipelago system at the time of the API call.

    ### WebSocket Connector Service

    The **Archipelago WebSocket Connector API** provides real-time bidirectional communication for Decentraland clients through WebSocket connections. This service acts as the gateway between client applications and the Archipelago communication system.

    **Purpose**: Manages the connection layer for all peer-to-peer communication, enabling live position synchronization, chat messaging, profile updates, and island assignment notifications.

    **Key Features**:
    - **Authentication**: Ethereum signature-based challenge-response handshake
    - **Position Updates**: Real-time avatar position and movement synchronization
    - **Chat Messages**: Text communication between nearby users
    - **Island Assignments**: Dynamic notifications when users move between islands

    **Key Endpoints**: `/status`, `/metrics`, `/health/live`, `/ws` (WebSocket)

    **Use Cases**:
    - Client connections for Decentraland applications
    - Real-time multiplayer interactions
    - Social features and chat functionality
    - Scene integration for coordinated experiences

    For detailed information about the Archipelago protocol architecture, message formats, and communication patterns, see [ADR-204](https://adr.decentraland.org/adr/ADR-204).
  version: 1.0.0
  contact:
    name: Decentraland
    url: https://decentraland.org
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
  x-api-id: archipelago-workers-api
servers:
  - url: https://archipelago-ea-stats.decentraland.org
    description: Stats service - Production
  - url: https://archipelago-ea-stats.zone
    description: Stats service - Development
  - url: https://archipelago-ea-ws-connector.decentraland.org
    description: WebSocket Connector service - Production
  - url: https://archipelago-ea-ws-connector.zone
    description: WebSocket Connector service - Development
paths:
  /parcels:
    get:
      tags:
        - Stats Service
      summary: Get parcels with peer counts
      description: |
        Returns a list of parcels with their current peer density information. Parcels represent geographic coordinates in Decentraland, and this endpoint helps identify areas with high user concentration. The peer count for each parcel indicates how many users are currently present in that geographic area, enabling crowd visualization and hotspot detection.
      operationId: getParcels
      security: []
      responses:
        '200':
          description: List of parcels with peer counts
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties: &ref_6
                    peersCount:
                      type: number
                      description: Number of peers in this parcel
                    parcel:
                      type: object
                      properties: &ref_10
                        x:
                          type: number
                          description: X coordinate
                        'y':
                          type: number
                          description: Y coordinate
                      required: &ref_11
                        - x
                        - 'y'
                  required: &ref_7
                    - peersCount
                    - parcel
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: &ref_0
                  error:
                    type: string
                    description: Error message
                  code:
                    type: integer
                    description: Error code
                required: &ref_1
                  - error
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
  /peers:
    get:
      tags:
        - Stats Service
      summary: Get all connected peers
      description: |
        Returns a list of all peers (users) currently active in the archipelago system. Each peer includes their unique identifier, Ethereum address, current position coordinates, assigned island, and last heartbeat timestamp. This endpoint provides a comprehensive view of all active users in the system at any given moment.
      operationId: getPeers
      security: []
      responses:
        '200':
          description: List of connected peers
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    description: Success status
                  peers:
                    type: array
                    items:
                      type: object
                      properties: &ref_2
                        id:
                          type: string
                          description: Peer ID
                        address:
                          type: string
                          description: Peer address
                        lastPing:
                          type: number
                          description: Last ping timestamp
                        parcel:
                          type: array
                          items:
                            type: number
                          description: Parcel coordinates [x, y]
                        position:
                          type: array
                          items:
                            type: number
                          description: Position coordinates [x, y, z]
                      required: &ref_3
                        - id
                        - address
                        - lastPing
                        - parcel
                        - position
                    description: List of peers
                required:
                  - ok
                  - peers
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
  /peers/{id}:
    get:
      tags:
        - Stats Service
      summary: Get specific peer information
      description: Returns information about a specific peer
      operationId: getPeer
      security: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: Peer ID
      responses:
        '200':
          description: Peer information
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    description: Success status
                  peer:
                    description: Peer information
                    type: object
                    properties: *ref_2
                    required: *ref_3
                required:
                  - ok
                  - peer
        '404':
          description: Peer not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    description: Success status
                  peer:
                    oneOf:
                      - type: object
                      - type: 'null'
                    description: Peer information (null when not found)
                required:
                  - ok
                  - peer
  /islands:
    get:
      tags:
        - Stats Service
      summary: Get all islands
      description: |
        Returns a list of all active islands in the archipelago system. Islands are dynamic clusters of peers that are continuously recalculated based on user positions. Each island entry includes the island identifier, current peer count, maximum capacity, center coordinates (x, y, z), radius, and the list of peers currently assigned to that island. Islands are created, merged, and split dynamically to maintain optimal distribution of users across the metaverse.
      operationId: getIslands
      security: []
      responses:
        '200':
          description: List of islands
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    description: Success status
                  islands:
                    type: array
                    items:
                      type: object
                      properties: &ref_4
                        id:
                          type: string
                          description: Island ID
                        peers:
                          type: array
                          items:
                            type: object
                            properties: *ref_2
                            required: *ref_3
                          description: List of peers in this island
                        maxPeers:
                          type: number
                          description: Maximum number of peers allowed
                        center:
                          type: array
                          items:
                            type: number
                          description: Center coordinates [x, y, z]
                        radius:
                          type: number
                          description: Island radius
                      required: &ref_5
                        - id
                        - peers
                        - maxPeers
                        - center
                        - radius
                    description: List of islands
                required:
                  - ok
                  - islands
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
  /islands/{id}:
    get:
      tags:
        - Stats Service
      summary: Get specific island information
      description: Returns information about a specific island
      operationId: getIsland
      security: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: Island ID
      responses:
        '200':
          description: Island information
          content:
            application/json:
              schema:
                type: object
                properties: *ref_4
                required: *ref_5
        '404':
          description: Island not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: number
                    description: HTTP status code
                  body:
                    oneOf:
                      - type: object
                      - type: 'null'
                    description: Island information (null when not found)
                required:
                  - status
                  - body
  /hot-scenes:
    get:
      tags:
        - Stats Service
      summary: Get hot scenes data
      description: |
        Returns data about popular scenes (hot scenes) in Decentraland based on current user activity. This endpoint provides information about scenes that are currently attracting high user traffic, including scene metadata, user counts, geographic coordinates, thumbnails, and project details. Hot scenes help identify trending areas and popular destinations in the metaverse.
      operationId: getHotScenes
      security: []
      responses:
        '200':
          description: Hot scenes data
          content:
            application/json:
              schema:
                type: array
                items: &ref_12
                  type: object
                  properties:
                    id:
                      type: string
                      description: Scene ID
                    name:
                      type: string
                      description: Scene name
                    baseCoords:
                      type: array
                      items:
                        type: number
                      description: Base coordinates [x, y]
                    usersTotalCount:
                      type: number
                      description: Total number of users in scene
                    parcels:
                      type: array
                      items:
                        type: array
                        items:
                          type: number
                      description: List of parcel coordinates
                    thumbnail:
                      type: string
                      description: Scene thumbnail URL
                    projectId:
                      type: string
                      description: Project ID
                    creator:
                      type: string
                      description: Creator name
                    description:
                      type: string
                      description: Scene description
                  required:
                    - id
                    - name
                    - baseCoords
                    - usersTotalCount
                    - parcels
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
  /core-status:
    get:
      tags:
        - Stats Service
      summary: Get core service status
      description: |
        Returns the operational status of the Archipelago core service. The core service is responsible for implementing the archipelago clustering logic, managing island creation/merging/splitting, processing peer position updates, and publishing island change notifications. This endpoint allows monitoring of the core service health and availability.
      operationId: getCoreStatus
      security: []
      responses:
        '200':
          description: Core service status
          content:
            application/json:
              schema:
                type: object
                properties: &ref_13
                  status:
                    type: string
                    description: Core service status
                  timestamp:
                    type: string
                    format: date-time
                    description: Status timestamp
                required: &ref_14
                  - status
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
  /comms/parcels:
    get:
      tags:
        - Stats Service
      deprecated: true
      summary: Get parcels (backwards compatibility)
      description: Backwards compatibility endpoint for parcels
      operationId: getCommsParcels
      security: []
      responses:
        '200':
          description: List of parcels with peer counts
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties: *ref_6
                  required: *ref_7
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
  /comms/peers:
    get:
      tags:
        - Stats Service
      deprecated: true
      summary: Get peers (backwards compatibility)
      description: Backwards compatibility endpoint for peers
      operationId: getCommsPeers
      security: []
      responses:
        '200':
          description: List of connected peers
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    description: Success status
                  peers:
                    type: array
                    items:
                      type: object
                      properties: *ref_2
                      required: *ref_3
                    description: List of peers
                required:
                  - ok
                  - peers
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
  /comms/peers/{id}:
    get:
      tags:
        - Stats Service
      deprecated: true
      summary: Get specific peer (backwards compatibility)
      description: Backwards compatibility endpoint for specific peer
      operationId: getCommsPeer
      security: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: Peer ID
      responses:
        '200':
          description: Peer information
          content:
            application/json:
              schema:
                type: object
                properties: *ref_2
                required: *ref_3
        '404':
          description: Peer not found
  /comms/islands:
    get:
      tags:
        - Stats Service
      deprecated: true
      summary: Get islands (backwards compatibility)
      description: Backwards compatibility endpoint for islands
      operationId: getCommsIslands
      security: []
      responses:
        '200':
          description: List of islands
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    description: Success status
                  islands:
                    type: array
                    items:
                      type: object
                      properties: *ref_4
                      required: *ref_5
                    description: List of islands
                required:
                  - ok
                  - islands
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_0
                required: *ref_1
  /comms/islands/{id}:
    get:
      tags:
        - Stats Service
      deprecated: true
      summary: Get specific island (backwards compatibility)
      description: Backwards compatibility endpoint for specific island
      operationId: getCommsIsland
      security: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: Island ID
      responses:
        '200':
          description: Island information
          content:
            application/json:
              schema:
                type: object
                properties: *ref_4
                required: *ref_5
        '404':
          description: Island not found
  /status:
    get:
      tags:
        - WebSocket Connector Service
      summary: Get service status
      description: Returns service status with version, commit hash, current time, and user count
      operationId: getStatus
      security: []
      responses:
        '200':
          description: Service status
          content:
            application/json:
              schema:
                type: object
                properties: &ref_15
                  version:
                    type: string
                    description: Service version
                  commitHash:
                    type: string
                    description: Git commit hash
                  currentTime:
                    type: string
                    format: date-time
                    description: Current server time
                  userCount:
                    type: number
                    description: Number of connected users
                required: &ref_16
                  - version
                  - commitHash
                  - currentTime
                  - userCount
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: &ref_8
                  error:
                    type: string
                    description: Error message
                  code:
                    type: integer
                    description: Error code
                required: &ref_9
                  - error
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_8
                required: *ref_9
  /metrics:
    get:
      tags:
        - WebSocket Connector Service
      summary: Get Prometheus metrics
      description: Returns Prometheus metrics for monitoring
      operationId: getMetrics
      security: []
      responses:
        '200':
          description: Prometheus metrics
          content:
            text/plain:
              schema:
                type: string
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: *ref_8
                required: *ref_9
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_8
                required: *ref_9
  /health/live:
    get:
      tags:
        - WebSocket Connector Service
      summary: Liveness probe
      description: Returns 'alive' for liveness checks
      operationId: getLiveness
      security: []
      responses:
        '200':
          description: Service is alive
          content:
            text/plain:
              schema:
                type: string
                example: alive
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: *ref_8
                required: *ref_9
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_8
                required: *ref_9
  /ws:
    get:
      tags:
        - WebSocket Connector Service
      summary: WebSocket connection
      description: |
        Establishes a WebSocket connection for real-time communication in the Archipelago system. This endpoint enables peer-to-peer communication, position synchronization, and island management for Decentraland clients.

        **Authentication Flow:**
        1. Client initiates connection with an Ethereum address
        2. Server responds with a challenge string to sign
        3. Client sends signed challenge with AuthChain
        4. Server validates signature and assigns peer ID

        **Supported Message Types:**
        - `challengeRequest`: Initial connection with address
        - `challengeResponse`: Server-provided challenge
        - `signedChallenge`: Client-provided signed challenge with AuthChain
        - `welcome`: Server confirmation with assigned peer ID
        - `heartbeat`: Keep-alive messages
        - `kicked`: Disconnection notification

        Once authenticated, the peer receives real-time updates about island assignments, nearby peers, and position changes as they move through Decentraland's metaverse.
      operationId: connectWebSocket
      security: []
      responses:
        '101':
          description: Switching protocols to WebSocket
        '200':
          description: WebSocket connection established
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: connected
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties: *ref_8
                required: *ref_9
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties: *ref_8
                required: *ref_9
      x-websocket:
        description: WebSocket protocol for real-time communication
        protocol: archipelago-websocket
        handshake:
          description: Authentication handshake process
          steps:
            - step: 1
              name: HANDSHAKE_START
              description: Client sends challenge request with Ethereum address
              message:
                type: object
                properties:
                  type:
                    type: string
                    enum:
                      - challengeRequest
                  address:
                    type: string
                    description: Ethereum address
            - step: 2
              name: HANDSHAKE_CHALLENGE_SENT
              description: Server responds with challenge response
              message:
                type: object
                properties:
                  type:
                    type: string
                    enum:
                      - challengeResponse
                  challenge:
                    type: string
                    description: Challenge string to sign
            - step: 3
              name: HANDSHAKE_CHALLENGE_SENT
              description: Client sends signed challenge
              message:
                type: object
                properties:
                  type:
                    type: string
                    enum:
                      - signedChallenge
                  authChain:
                    type: array
                    description: AuthChain with signature
            - step: 4
              name: HANDSHAKE_COMPLETED
              description: Server validates and sends welcome message
              message:
                type: object
                properties:
                  type:
                    type: string
                    enum:
                      - welcome
                  peerId:
                    type: string
                    description: Assigned peer ID
        messages:
          client:
            challengeRequest:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - challengeRequest
                address:
                  type: string
                  description: Ethereum address
            signedChallenge:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - signedChallenge
                authChain:
                  type: array
                  description: AuthChain with signature
            heartbeat:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - heartbeat
          server:
            challengeResponse:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - challengeResponse
                challenge:
                  type: string
                  description: Challenge string to sign
            welcome:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - welcome
                peerId:
                  type: string
                  description: Assigned peer ID
            kicked:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - kicked
                reason:
                  type: string
                  enum:
                    - KR_NEW_SESSION
                  description: Kick reason
        authentication:
          type: ethereum-signature
          description: Ethereum signature validation via AuthChain
components:
  schemas:
    Parcel:
      type: object
      properties: *ref_10
      required: *ref_11
    ParcelResult:
      type: object
      properties: *ref_6
      required: *ref_7
    Error:
      type: object
      properties: *ref_8
      required: *ref_9
    Peer:
      type: object
      properties: *ref_2
      required: *ref_3
    Island:
      type: object
      properties: *ref_4
      required: *ref_5
    HotScenes:
      type: array
      items: *ref_12
    CoreStatus:
      type: object
      properties: *ref_13
      required: *ref_14
    Status:
      type: object
      properties: *ref_15
      required: *ref_16
