openapi: 3.0.0
info:
  title: WisDM external API for enterprise customers to manage their gateways
  version: 4.1.5
servers:
  - url: https://api.wisdm.network
    description: Production endpoint
security:
  - ApiKeyAuth: []

paths:
  /v4/version:
    get:
      summary: Get the version details of the WisDM API
      description: API key with read permission required. Includes gateways that are not assigned to any location.
      operationId: GetVersionRequest
      tags:
        - Get Version Details
      parameters:
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Version
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetVersionResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/organization:
    get:
      summary: Get organization information by the API key generated on WisDM UI
      description: API key with read permission required
      operationId: GetOrganizationRequest
      tags:
        - Get Organization
      parameters:
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Organization
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetOrganizationResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/organization/{organizationId}/locations:
    get:
      summary: List all locations of the organization that the API key can access
      description: API key with read permission required
      operationId: ListLocationsRequest
      tags:
        - List Locations
      parameters:
        - in: path
          name: organizationId
          schema:
            type: string
          required: true
          description: The ID of the organization to list locations
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful List Locations
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListLocationsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"
    post:
      summary: Create a Basic Station location for the organization
      description: |
        Creates a new location and configures it for Basic Station work mode in a single call.
        The API key must include the WRITE_ADD_LOCATION_TO_ORGANIZATION permission.

        This endpoint combines the "general info" and "network configuration" steps that exist
        in the WisDM UI. Only the Basic Station work mode is supported at the moment.
      operationId: CreateLocationRequest
      tags:
        - Create Location
      parameters:
        - in: path
          name: organizationId
          schema:
            type: string
          required: true
          description: The ID of the organization to create the location in
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateLocationRequest"
      responses:
        "201":
          description: Location created successfully
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreateLocationResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/organization/{organizationId}/gateways:
    get:
      summary: List all gateways in the organization
      description: API key with read permission required
      operationId: ListOrganizationGatewaysRequest
      tags:
        - List Gateways
      parameters:
        - in: path
          name: organizationId
          schema:
            type: string
          required: true
          description: The organization ID to list gateways
        - in: query
          name: pageSize
          schema:
            type: integer
            minimum: 10
            maximum: 100
            default: 100
          required: false
          description: The number of items to return per page
        - in: query
          name: nextToken
          schema:
            type: string
          required: false
          description: Token for the next page of results
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful List Gateways
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListOrganizationGatewaysResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/location/{locationId}/name:
    post:
      summary: Update the name of a location
      description: API key with WRITE_UPDATE_LOCATION_NAME permission is required
      operationId: SetLocationNameRequest
      tags:
        - Update Location Name
      parameters:
        - in: path
          name: locationId
          schema:
            type: string
          required: true
          description: The ID of the location to update
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SetLocationNameRequest"
      responses:
        "204":
          description: Location name updated successfully
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/location/{locationId}/gateways:
    post:
      summary: Register or assigned a gateway to the location.
      description: |
        API key with WRITE_ADD_GATEWAY_TO_LOCATION permission is required
        Register or assign a gateway to a specific location within the organization.

        **Security Requirements:**
        - Only unassigned gateways within the organization can be registered or assigned to locations
        - Or contact RAKwireless to prove and whitelist your gateways with the organization

        **Location Work Mode Requirements:**
        - Location must be configured in "Basic Station" mode
        - "Packet Forwarder" and "Network Server" mode is currently not supported

        **Factory Configuration:**
        - Gateway must be pre-pushed to the WisDM organization during factory configuration
        - Registration will fail if the gateway is not properly configured in the factory
      operationId: RegisterGatewayRequest
      tags:
        - Register Gateway to Location
      parameters:
        - in: path
          name: locationId
          schema:
            type: string
          required: true
          description: The location ID to register or assign gateway
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RegisterGatewayRequest"
      responses:
        "201":
          description: Successful Register Gateway to Location
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RegisterGatewayResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "406":
          $ref: "#/components/responses/NotAcceptable"
        "409":
          $ref: "#/components/responses/Conflict"
        "500":
          $ref: "#/components/responses/InternalServerError"
    get:
      summary: List all gateways brief information in the location
      description: API key with read permission required
      operationId: ListGatewaysRequest
      tags:
        - List Gateways
      parameters:
        - in: path
          name: locationId
          schema:
            type: string
          required: true
          description: The location ID to list gateways
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful List Gateways
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListGatewaysResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/location/{locationId}/gateways/status:
    get:
      summary: |
        List all gateways status in the location. 
        Gateway's sensitive fields will keep encrypted for performance.
        The response will be paginated, and the next token will be returned in the response.
        The next token can be used to get the next page of results.
        The next token will be empty if there are no more results.
      description: API key with read permission required
      operationId: ListGatewaysStatusRequest
      tags:
        - List Gateways Status
      parameters:
        - in: path
          name: locationId
          schema:
            type: string
          required: true
          description: The location ID to list gateways
        - in: query
          name: pageSize
          schema:
            type: integer
            default: 100
            minimum: 10
            maximum: 100
          required: false
          description: The number of items to return per page
        - in: query
          name: nextToken
          schema:
            type: string
          required: false
          description: The next token to return the next page of results
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful List Gateways Status
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListGatewaysStatusResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/location/{locationId}/gateways/battery:
    get:
      summary: List all gateways solar battery status in the location
      description: API key with read permission required
      operationId: ListGatewaysSolarBatteryRequest
      tags:
        - List Gateways Solar Battery Status
      parameters:
        - in: path
          name: locationId
          schema:
            type: string
          required: true
          description: The location ID to list gateways
        - in: query
          name: pageSize
          schema:
            type: integer
            default: 100
            minimum: 10
            maximum: 100
          required: false
          description: The number of items to return per page
        - in: query
          name: nextToken
          schema:
            type: string
          required: false
          description: The next token to return the next page of results
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful List Gateways Solar Battery Status
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListGatewaysSolarBatteryResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/status:
    get:
      summary: Get the status of the gateway
      description: API key with read permission required
      operationId: GetGatewayRequest
      tags:
        - Get Gateway Status
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway Status
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/status/basic:
    get:
      summary: Get the basic status of the gateway
      description: API key with read permission required
      operationId: GetGatewayBasicStatusRequest
      tags:
        - Get Gateway Basic Status
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          description: The serial number or 16-character hexadecimal EUI of the gateway
          required: true
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway Basic Status
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayBasicResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/status/system:
    get:
      summary: Get the system status of the gateway
      description: API key with read permission required
      operationId: GetGatewaySystemStatusRequest
      tags:
        - Get Gateway System Status
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          description: The serial number or 16-character hexadecimal EUI of the gateway
          required: true
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway System Status
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewaySystemResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/status/gps:
    get:
      summary: Get the GPS status of the gateway
      description: API key with read permission required
      operationId: GetGatewayGPSStatusRequest
      tags:
        - Get Gateway GPS Status
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          description: The serial number or 16-character hexadecimal EUI of the gateway
          required: true
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway GPS Status
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayGPSResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/status/lora:
    get:
      summary: Get the LoRa status of the gateway
      description: API key with read permission required
      operationId: GetGatewayLoRaStatusRequest
      tags:
        - Get Gateway LoRa Status
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          description: The serial number or 16-character hexadecimal EUI of the gateway
          required: true
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway LoRa Status
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayLoRaResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/status/network:
    get:
      summary: Get the network status of the gateway
      description: API key with read permission required
      operationId: GetGatewayNetworkStatusRequest
      tags:
        - Get Gateway Network Status
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          description: The serial number or 16-character hexadecimal EUI of the gateway
          required: true
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway Network Status
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayNetworkResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/status/storage:
    get:
      summary: Get the storage status of the gateway
      description: API key with read permission required
      operationId: GetGatewayStorageStatusRequest
      tags:
        - Get Gateway Storage Status
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          description: The serial number or 16-character hexadecimal EUI of the gateway
          required: true
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway Storage Status
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayStorageResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/perf/{metric}:
    get:
      summary: Get the specific performance metric of the gateway
      description: API key with read permission required
      operationId: GetGatewayPerfRequest
      tags:
        - Get Gateway Performance
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          description: The serial number or 16-character hexadecimal EUI of the gateway
          required: true
        - in: path
          name: metric
          schema:
            type: string
            enum:
              - rssi
              - snr
              - uplink
              - downlink
          description: The metric to retrieve the data
          required: true
        - in: query
          name: interval
          schema:
            type: string
          description: The time from interval(<12h, <720m) to now toretrieve the data, ends with h, H, m, M
          required: true
        - in: query
          name: rssi
          schema:
            type: integer
            minimum: 0
            maximum: 6
          description: |
            The RSSI level of LoRa uplink packets to retrieve the data, required if metric is rssi
            0 means <=-140, 
            1 means >-140 and <=-120, 
            2 means >-120 and <=-100, 
            3 means >-100 and <=-80, 
            4 means >-80 and <=-60, 
            5 means >-60 and <=-40, 
            6 means >-40
          required: false
        - in: query
          name: snr
          schema:
            type: integer
            minimum: 0
            maximum: 7
          description: |
            The SNR level of LoRa uplink packets to retrieve the data, required if metric is snr
            0 means <=-15, 
            1 means >-15 and <=-10,
            2 means >-10 and <=-5,
            3 means >-5 and <=0,
            4 means >0 and <5,
            5 means >5 and <=10,
            6 means >10 and <=15,
            7 means >15
          required: false
        - in: query
          name: uplink
          schema:
            type: integer
            minimum: 0
            maximum: 15
          description: The uplink data rate to retrieve the data, required if metric is uplink
          required: false
        - in: query
          name: downlink
          schema:
            type: integer
            minimum: 0
            maximum: 15
          description: The downlink data rate to retrieve the data, required if metric is downlink
          required: false
        - in: query
          name: nextToken
          schema:
            type: string
          description: The next token to return the next page of results
          required: false
        - in: query
          name: clientToken
          schema:
            type: string
          description: The client token refer to the query with same parameters, required if nextToken is provided
          required: false
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway Performance
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayPerfResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/battery:
    get:
      summary: Get the solar battery status of the gateway
      description: API key with read permission required
      operationId: GetGatewaySolarBatteryRequest
      tags:
        - Get Gateway Solar Battery Status
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          description: The serial number or 16-character hexadecimal EUI of the gateway
          required: true
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway Solar Battery Status
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewaySolarBatteryResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

    post:
      summary: Enable or disable solar battery monitoring service for the gateway
      description: API key with WRITE_ENABLE_BATTERY_MONITORING permission required
      operationId: EnableSolarBatteryMonitoringRequest
      tags:
        - Enable Gateway Solar Battery Monitoring
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          description: The serial number or 16-character hexadecimal EUI of the gateway
          required: true
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EnableSolarBatteryMonitoringRequest"
      responses:
        "204":
          description: Successful Enable Solar Battery Monitoring with empty response
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/async-cmd:
    post:
      summary: Submit an asynchronous command to the gateway
      operationId: SubmitGatewayAsyncCommandRequest
      tags:
        - Asynchronous Commands
      description: |
        This is an asynchronous operation:
        1. This endpoint returns a commandId upon successful submission
        2. Use the commandId with GET /v4/gateway/{snOrEui}/async-cmd/{commandId} to check execution status and results
        3. You may need to poll the status endpoint multiple times until results are available
        Note: Command execution time varies based on gateway connectivity and response time.
        Note: For security reasons, only commands that are explicitly supported by the gateway firmware will be executed.
        Note: Currently, only netstat command is supported. So any API key with read permission could submit the command.
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          description: The serial number or 16-character hexadecimal EUI of the gateway
          required: true
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SubmitGatewayAsyncCommandRequest"
      responses:
        "201":
          description: Command submitted successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubmitGatewayAsyncCommandResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/async-cmd/{commandId}:
    get:
      summary: Get the status and results of a previously executed command
      operationId: GetAsyncCommandRequest
      tags:
        - Asynchronous Commands
      description: |
        Get the status and results of a previously executed command.
        The command execution is asynchronous:
        1. When a command is first executed, it enters a PENDING state
        2. Gateways need time to receive, execute the command, and upload results
        3. If status remains PENDING:
           - Gateway might be offline
           - Gateway hasn't uploaded results yet
           - Try checking again after a few minutes
        4. If status is SUCCESS, the command has been executed successfully
        5. If status is FAILED, the command has failed
        Note: Results availability depends on gateway connectivity and response time.
        Note: API key with read permission could get the results of the command.
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
        - in: path
          name: commandId
          schema:
            type: string
          required: true
          description: Command ID returned from execute command
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Asynchronous Command Status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayAsyncCommandResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/upgrade:
    post:
      summary: Upgrade the gateway firmware
      description: |
        API key with WRITE_UPGRADE_FIRMWARE permission is required
      operationId: UpgradeGatewayFirmware
      tags:
        - Upgrade Gateway Firmware
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpgradeGatewayFirmwareRequest"
      responses:
        "204":
          description: Successful Upgrade Gateway with empty response
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/reboot:
    post:
      summary: Reboot the gateway
      description: |
        API key with WRITE_REBOOT_GATEWAY permission is required
      operationId: RebootGatewayRequest
      tags:
        - Reboot Gateway
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
      responses:
        "204":
          description: Successful Reboot Gateway with empty response
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/password:
    post:
      summary: Force set the new password of the gateway
      description: |
        API key with WRITE_RESET_PASSWORD permission is required
      operationId: SetGatewayPasswordRequest
      tags:
        - Set Gateway Password
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SetGatewayPasswordRequest"
      responses:
        "204":
          description: Successful Set Gateway Password with empty response
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/name:
    post:
      summary: Update the gateway name
      description: |
        API key with WRITE_EDIT_SYSTEM_SETTINGS permission is required
      operationId: SetGatewayName
      tags:
        - Set Gateway Name
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SetGatewayNameRequest"
      responses:
        "204":
          description: Successful Set Gateway Name with empty response
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/network/priority:
    post:
      summary: Set the network priority of the gateway
      description: |
        API key with WRITE_EDIT_NETWORK_INTERFACE permission is required
      operationId: SetGatewayNetworkPriorityRequest
      tags:
        - Network Priority
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SetGatewayNetworkPriorityRequest"
      responses:
        "204":
          description: Successful Set Gateway Network Priority with empty response
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"
    get:
      summary: Get the network priority of the gateway.
      description: API key with read permission required
      operationId: GetNetworkPriorityRequest
      tags:
        - Network Priority
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway Network Priority
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayNetworkPriorityResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/network/lan:
    post:
      summary: Set the LAN interface of the gateway.
      description: |
        Requires API key with WRITE_EDIT_NETWORK_INTERFACE permission.
        Use this endpoint to toggle the LAN Wi-Fi SSID, enable or disable the bridged LAN Ethernet port, 
        and update the DHCP subnet (IPv4/mask) advertised to downstream clients. Provide only the 
        sections you want to change—omitted sections remain untouched.
        Note: Enable Ethernet's LAN interface will disable its WAN interface, and vice versa.
      operationId: SetGatewayLanSettingsRequest
      tags:
        - Network LAN Interface
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SetGatewayLanSettingsRequest"
      responses:
        "204":
          description: Successful Set Gateway LAN Interface with empty response
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"
    get:
      summary: Get the LAN interface of the gateway.
      description: API key with read permission required
      operationId: GetGatewayLanInterfaceRequest
      tags:
        - Network LAN Interface
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway LAN Status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayLanSettingsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/network/wan:
    post:
      summary: Set the WAN interface of the gateway.
      description: |
        Requires API key with WRITE_EDIT_NETWORK_INTERFACE permission.
        Use this endpoint to toggle Ethernet/Wi-Fi/Cellular WAN links, switch between the supported
        protocols (DHCP/Static/PPPoE), update Wi-Fi credentials, and push custom IPv4/DNS or SIM/APN
        settings that match the WisDM UI capabilities.
      operationId: SetGatewayWanSettingsRequest
      tags:
        - Network WAN Interface
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SetGatewayWanSettingsRequest"
      responses:
        "204":
          description: Successful Set Gateway WAN Interface with empty response
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"
    get:
      summary: Get the WAN interface settings of the gateway.
      description: API key with read permission required
      operationId: GetGatewayWanInterfaceRequest
      tags:
        - Network WAN Interface
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway WAN Status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayWanSettingsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/network/wan/status:
    get:
      summary: Get the status of the WAN interface of the gateway.
      description: |
        API key with read permission required.

        Returns the status of the WAN interface of the gateway. This information also present when getting the gateway status.
      operationId: GetGatewayWanInterfaceStatusRequest
      tags:
        - Network WAN Interface
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
      responses:
        "200":
          description: Successful Get Gateway WAN Interface Status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayWanStatusResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v4/gateway/{snOrEui}/syslog:
    get:
      summary: Get gateway syslog configuration
      description: |
        API key with read permission required.

        Returns the latest syslog configuration persisted for the specified gateway, including the
        current log sharing mode, log rotation windows, and external syslog target (if configured).
      operationId: GetGatewaySyslog
      tags:
        - Gateway Logs
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
      responses:
        "200":
          description: Current gateway syslog configuration
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewaySyslogResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"
    post:
      summary: Update gateway syslog configuration
      description: |
        API key with WRITE_EDIT_SYSTEM_SETTINGS permission required.

        Allows WisDM to toggle whether a gateway uploads its logs to WisDM and/or an external syslog server,
        adjust on-device log rotation, and control how often WisDM polls for fresh logs.
      operationId: SetGatewaySyslog
      tags:
        - Gateway Logs
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SetGatewaySyslogRequest"
      responses:
        "204":
          description: Log configuration update accepted
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"
  /v4/gateway/{snOrEui}/syslog/download:
    get:
      summary: Get gateway syslog download URLs
      description: |
        API key with read permission required.

        Returns pre-signed download links for log files uploaded by the gateway within the specified time range.
        The backend queries the WisDM log bucket, filters the objects by the provided timestamps, and generates limited-time URLs.
      operationId: GetGatewayLogsRequest
      tags:
        - Gateway Logs
      parameters:
        - in: path
          name: snOrEui
          schema:
            type: string
          required: true
          description: The serial number or 16-character hexadecimal EUI of the gateway
        - in: query
          name: startDate
          schema:
            type: string
            format: date-time
          required: true
          description: Include log files newer than or equal to this timestamp (UTC, ISO-8601).
        - in: query
          name: endDate
          schema:
            type: string
            format: date-time
          required: true
          description: Include log files older than or equal to this timestamp (UTC, ISO-8601).
        - in: query
          name: maxFiles
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 20
          required: false
          description: Optional cap for the number of log files returned. Files are sorted by LastModified in descending order.
        - in: header
          name: Accept-Encoding
          schema:
            type: string
            enum:
              - gzip
          required: false
      responses:
        "200":
          description: Successful Get Gateway Logs
          headers:
            Content-Encoding:
              schema:
                type: string
                enum:
                  - gzip
              description: The content encoding of the response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GetGatewayLogsResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "500":
          $ref: "#/components/responses/InternalServerError"

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY
      description: The API key generated on WisDM UI for the organization

  schemas:
    GetVersionResponse:
      type: object
      required:
        - version
        - commitId
      properties:
        version:
          type: string
          description: The version of the WisDM API
        commitId:
          type: string
          description: The commit ID of the WisDM API

    GetOrganizationResponse:
      $ref: "#/components/schemas/Organization"

    ListLocationsResponse:
      type: object
      properties:
        total:
          type: integer
          description: Total number of locations
        locations:
          type: array
          items:
            $ref: "#/components/schemas/Location"
    CreateLocationRequest:
      type: object
      required:
        - name
        - workMode
        - enableCriticalFwAutoUpdate
        - basicStation
        - advancedFrequencySettings
      properties:
        name:
          type: string
          minLength: 4
          maxLength: 50
          pattern: '^(?=.*\S).+$'
          description: >
            Human friendly location name shown in WisDM UI.
        address:
          $ref: "#/components/schemas/LocationAddress"
          description: |
            Optional. When omitted, the organization's registered address will be copied automatically.
        workMode:
          type: string
          enum:
            - Basics station
          description: Only Basics station is supported at the moment
        enableCriticalFwAutoUpdate:
          type: boolean
          description: Whether critical firmware auto update is enabled for gateways in this location
        basicStation:
          $ref: "#/components/schemas/CreateLocationBasicStation"
        advancedFrequencySettings:
          $ref: "#/components/schemas/AdvancedFrequencySettings"
          description: Frequency plan applied to gateways in this location.
        channelsNumber:
          type: integer
          enum:
            - 8
            - 16
          description: Number of channels supported by gateways assigned to this location.
    CreateLocationResponse:
      type: object
      required:
        - locationId
        - name
        - workMode
      properties:
        locationId:
          type: string
          description: The ID of the newly created location
        organizationId:
          type: string
          description: The organization ID that owns the location
        name:
          type: string
          description: Name of the new location
        workMode:
          type: string
          description: Work mode assigned to the Location

    SetLocationNameRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          minLength: 4
          maxLength: 50
          pattern: '^(?=.*\S).+$'
          description: >
            Human friendly location name shown in WisDM UI.

    RegisterGatewayRequest:
      type: object
      required:
        - sn
        - eui
        - name
      properties:
        sn:
          type: string
          description: The serial number of the gateway
        eui:
          type: string
          description: The EUI of the gateway
        name:
          $ref: "#/components/schemas/GatewayName"
        bsHasLocalAuthSuite:
          type: boolean
          description: |
            Set to false for gateways without pre-configured Basic Station certificates.
            Set to true if the gateway has factory-preconfigured Basic Station certificates. 
            Only gateways with version 2.2.15 or higher supports this feature.
        bsClientCertificate:
          allOf:
            - $ref: "#/components/schemas/BasicStationCertificate"
          description: |
            Client certificate for TLS authentication. Required when bsHasLocalAuthSuite is false 
            and location uses 'TLS Server and Client Authentication' mode.
        bsClientKey:
          allOf:
            - $ref: "#/components/schemas/BasicStationPrivateKey"
          description: |
            Client private key for TLS authentication. Required when bsHasLocalAuthSuite is false 
            and location uses 'TLS Server and Client Authentication' mode.
        bsToken:
          allOf:
            - $ref: "#/components/schemas/BasicStationClientToken"
          description: |
            Authentication token for token-based authentication. Required when bsHasLocalAuthSuite is false 
            and location uses 'TLS Server Authentication and Client Token Authentication' mode.

    RegisterGatewayResponse:
      type: object
      required:
        - sn
        - eui
        - locationId
      properties:
        locationId:
          type: string
          description: The location ID the gateway registered to
        sn:
          type: string
          description: The serial number of the gateway registered to location
        eui:
          type: string
          description: The EUI of the gateway registered to location

    ListGatewaysResponse:
      type: object
      required:
        - total
        - gateways
      properties:
        total:
          type: integer
          description: Total number of gateways
        gateways:
          type: array
          items:
            $ref: "#/components/schemas/GatewayInfo"

    ListOrganizationGatewaysResponse:
      allOf:
        - $ref: "#/components/schemas/Pagination"
        - type: object
          properties:
            gateways:
              type: array
              items:
                $ref: "#/components/schemas/GatewayInfo"

    ListGatewaysStatusResponse:
      allOf:
        - $ref: "#/components/schemas/Pagination"
        - type: object
          properties:
            gateways:
              type: array
              items:
                $ref: "#/components/schemas/GatewayStatus"

    ListGatewaysSolarBatteryResponse:
      allOf:
        - $ref: "#/components/schemas/Pagination"
        - type: object
          properties:
            gateways:
              type: array
              items:
                $ref: "#/components/schemas/GetGatewaySolarBatteryResponse"

    GetGatewayResponse:
      $ref: "#/components/schemas/GatewayStatus"

    GetGatewayBasicResponse:
      $ref: "#/components/schemas/GatewayInfo"

    GetGatewayGPSResponse:
      $ref: "#/components/schemas/GPSStatus"

    GetGatewaySystemResponse:
      $ref: "#/components/schemas/SystemStatistics"

    GetGatewayNetworkResponse:
      $ref: "#/components/schemas/NetworkStatus"

    GetGatewayStorageResponse:
      $ref: "#/components/schemas/StorageStatistics"

    GetGatewayLoRaResponse:
      $ref: "#/components/schemas/LoraStatistics"

    GetGatewayPerfResponse:
      type: object
      required:
        - result
      properties:
        result:
          type: array
          items:
            $ref: "#/components/schemas/GatewayMetric"
        nextToken:
          type: string
          description: The next token to return the next page of results
        clientToken:
          type: string
          description: The client token refer to the query

    GetGatewaySolarBatteryResponse:
      type: object
      required:
        - sn
        - enabled
        - battery
      properties:
        sn:
          type: string
          description: The serial number of the gateway
        enabled:
          type: boolean
          description: Whether the solar battery monitoring service is enabled for the gateway
        battery:
          $ref: "#/components/schemas/SolarBatteryStatus"

    EnableSolarBatteryMonitoringRequest:
      type: object
      required:
        - enabled
      properties:
        enabled:
          type: boolean
          description: Whether the solar battery monitoring service is enabled for the gateway
          example: true

    SubmitGatewayAsyncCommandRequest:
      allOf:
        - $ref: "#/components/schemas/ShellCommand"
        - type: object
          properties:
            pipes:
              type: array
              items:
                description: The pipes to execute with the command
                $ref: "#/components/schemas/ShellCommand"
                example:
                  command: "grep"
                  args: "LISTEN"
            timeout:
              type: integer
              description: The timeout to execute the command
              default: 60

    SubmitGatewayAsyncCommandResponse:
      type: object
      required:
        - commandId
      properties:
        commandId:
          type: string
          description: The command ID returned from the command submission

    GetGatewayAsyncCommandResponse:
      type: object
      properties:
        sn:
          type: string
          description: Serial number of the gateway
        commandId:
          type: string
          description: The command ID returned from the command submission
        result:
          type: string
          description: Command execution result

    UpgradeGatewayFirmwareRequest:
      type: object
      required:
        - version
      properties:
        version:
          type: string
          description: The version of the firmware to upgrade the gateway to
          pattern: ^[0-9]+\.[0-9]+\.[0-9]+$
          example: "2.2.13"

    SetGatewayPasswordRequest:
      type: object
      required:
        - password
      properties:
        password:
          type: string
          description: The new password to set for the gateway. It must be 12-126 characters long, include at least one Latin letter, one number, and one supported special character, use only supported characters, and must not start or end with a space.
          minLength: 12
          maxLength: 126
          pattern: '^(?! )(?!.* $)(?=.*[A-Za-z])(?=.*\d)(?=.*[!"“#$%&/\\''‘()* +,\-./:;<=>?@\[\]\^_`{|}~])[A-Za-z\d!"“#$%&/\\''‘()* +,\-./:;<=>?@\[\]\^_`{|}~]{12,126}$'
          example: "Example123!@"

    SetGatewayNameRequest:
      type: object
      required:
        - name
      properties:
        name:
          $ref: "#/components/schemas/GatewayName"

    SetGatewayNetworkPriorityRequest:
      type: object
      required:
        - priority
      properties:
        priority:
          $ref: "#/components/schemas/NetworkPriority"

    GetGatewayNetworkPriorityResponse:
      type: object
      required:
        - sn
        - priority
      properties:
        sn:
          type: string
          description: The serial number of the gateway
        priority:
          $ref: "#/components/schemas/NetworkPriority"

    SetGatewayLanSettingsRequest:
      $ref: "#/components/schemas/LanSettings"

    GetGatewayLanSettingsResponse: 
      $ref: "#/components/schemas/LanSettings"

    SetGatewayWanSettingsRequest:
      $ref: "#/components/schemas/WanSettings"

    GetGatewayWanSettingsResponse:
      $ref: "#/components/schemas/WanSettings"

    GetGatewayWanStatusResponse:
      $ref: "#/components/schemas/WanStatus"

    GetGatewayLogsResponse:
      type: object
      required:
        - sn
        - totalFiles
        - files
      properties:
        sn:
          type: string
          description: Serial number of the gateway.
        totalFiles:
          type: integer
          minimum: 0
          description: Total number of log files that matched the query (before applying maxFiles limit).
        files:
          type: array
          description: Ordered list of log files with pre-signed URLs (most recent first).
          items:
            $ref: "#/components/schemas/GatewayLogFile"

    GetGatewaySyslogResponse:
      type: object
      required:
        - sn
        - shareLogs
      properties:
        sn:
          type: string
          description: Serial number of the gateway.
        shareLogs:
          type: string
          enum:
            - none
            - external
            - wisdm
            - externalAndWisdm
          description: |
            Destination for the gateway log stream. `wisdm` sends logs only to WisDM, `external`
            sends only to the configured external syslog server, `externalAndWisdm` delivers to both,
            and `none` disables uploads entirely.
        logsRotationCycle:
          type: integer
          description: Number of days the gateway keeps local log files before rotating them.
        wisdmLogsRetrievalCycle:
          type: integer
          nullable: true
          description: Interval in minutes between WisDM log pull jobs.
        wisdmLogsRotationCycle:
          type: integer
          nullable: true
          description: Number of days WisDM keeps uploaded logs before purging them from cloud storage.
        externalLogServer:
          $ref: "#/components/schemas/ExternalLogServer"
          description: Address of external log server. Returned when shareLogs includes an external server.
        logLevel:
          $ref: "#/components/schemas/GatewayLogLevel"
          description: Minimum severity of gateway logs to be forwarded.

    SetGatewaySyslogRequest:
      type: object
      properties:
        shareLogs:
          type: string
          enum:
            - none
            - external
            - wisdm
            - externalAndWisdm
          description: |
            Destination for the gateway log stream. `wisdm` sends logs only to WisDM, `external`
            sends only to the configured external syslog server, `externalAndWisdm` delivers to both,
            and `none` disables uploads entirely.
        logsRotationCycle:
          type: integer
          enum:
            - 14
            - 30
            - 90
            - 180
            - 360
          description: Number of days the gateway keeps local log files before rotating them.
        wisdmLogsRetrievalCycle:
          type: integer
          enum:
            - 60
            - 120
            - 240
            - 480
            - 720
            - 1440
          description: |
            Interval in minutes between WisDM log pull jobs. Required when shareLogs includes WisDM.
        wisdmLogsRotationCycle:
          type: integer
          enum:
            - 1
            - 7
            - 14
            - 30
          description: Number of days WisDM keeps uploaded logs before purging them from cloud storage. Required when shareLogs includes WisDM.
        externalLogServer:
          $ref: "#/components/schemas/ExternalLogServer"
          description: Address of external log server. Required when shareLogs includes external server.
        logLevel:
          $ref: "#/components/schemas/GatewayLogLevel"
          description: Minimum severity of gateway logs to be forwarded.

    # Basic Components
    Organization:
      type: object
      required:
        - id
      properties:
        id:
          type: string
          description: The ID of the organization
        name:
          type: string
          description: The name of the organization

    Location:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: string
          description: The ID of the location
        name:
          type: string
          description: The name of the location

    LocationAddress:
      type: object
      properties:
        country:
          type: string
          description: ISO country/region code (optional).
        addressLine1:
          type: string
          description: Primary address line. Optional when copying from the organization address.
        city:
          type: string
        state:
          type: string
        zip:
          type: string
        latitude:
          type: string
          description: Latitude in decimal degrees
        longitude:
          type: string
          description: Longitude in decimal degrees

    AdvancedFrequencySettings:
      type: object
      required:
        - region
        - isLoRaWANPublic
      properties:
        region:
          type: string
          enum:
            - EU433
            - CN470
            - RU864
            - IN865
            - EU868
            - US915
            - AU915
            - KR920
            - AS923
          description: Frequency plan region for the location
        regionVariation:
          type: string
          description: Required when region is AS923
          enum:
            - "1"
            - "2"
            - "3"
            - "4"
        isLoRaWANPublic:
          type: boolean
          description: Whether the network operates on the public LoRaWAN spectrum
        frequencySubBand:
          type: string
          description: |
            Optional. When omitted for CN470/US915/AU915 the backend will apply the default
            frequency sub-band used by the WisDM UI.

    CreateLocationBasicStation:
      type: object
      required:
        - serverType
        - serverURL
        - serverPort
        - authenticationMode
      properties:
        serverType:
          type: string
          enum:
            - CUPS-BOOT
            - CUPS
            - LNS
          description: Basic Station server type
        serverURL:
          type: string
          maxLength: 255
          description: Fully qualified URL of the server
        serverPort:
          type: integer
          minimum: 1
          maximum: 65535
          description: TCP port used by the Basic Station server
        authenticationMode:
          type: string
          enum:
            - None
            - TLS Server Authentication
            - TLS Server and Client Authentication
            - TLS Server Authentication and Client Token Authentication
          description: Authentication mode used by gateways in this location
        trustCACertificate:
          allOf:
            - $ref: "#/components/schemas/BasicStationCertificate"
          description: PEM encoded CA certificate. Required for any non-None authentication mode.
        useIndividualKeys:
          type: boolean
          description: |
            Enables per-gateway credentials instead of sharing certificates/tokens at the location level.
            Required when authenticationMode is TLS Server and Client Authentication or
            TLS Server Authentication and Client Token Authentication.
            When true, clientCertificate, clientKey, and token are ignored.
        clientCertificate:
          allOf:
            - $ref: "#/components/schemas/BasicStationCertificate"
          description: PEM encoded client certificate (required when useIndividualKeys=false and TLS client auth is configured)
        clientKey:
          allOf:
            - $ref: "#/components/schemas/BasicStationPrivateKey"
          description: PEM encoded client private key (required when useIndividualKeys=false and TLS client auth is configured)
        token:
          allOf:
            - $ref: "#/components/schemas/BasicStationClientToken"
          description: Client token (required when useIndividualKeys=false and token auth is configured)

    BasicStationCertificate:
      type: string
      minLength: 128
      maxLength: 4096
      pattern: '^-----BEGIN CERTIFICATE-----\r?\n(?:[A-Za-z0-9+/=]+\r?\n)+-----END CERTIFICATE-----\r?\n?$'
      description: PEM encoded X.509 certificate.

    BasicStationPrivateKey:
      type: string
      minLength: 128
      maxLength: 4096
      pattern: '^(?:-----BEGIN PRIVATE KEY-----\r?\n(?:[A-Za-z0-9+/=]+\r?\n)+-----END PRIVATE KEY-----|-----BEGIN RSA PRIVATE KEY-----\r?\n(?:[A-Za-z0-9+/=]+\r?\n)+-----END RSA PRIVATE KEY-----|-----BEGIN EC PRIVATE KEY-----\r?\n(?:[A-Za-z0-9+/=]+\r?\n)+-----END EC PRIVATE KEY-----)\r?\n?$'
      description: PEM encoded client private key.

    BasicStationClientToken:
      type: string
      minLength: 1
      maxLength: 256
      pattern: '^[0-9A-Za-z._~+/\-]+$'
      description: Client token without the Authorization Bearer prefix.

    Pagination:
      type: object
      required:
        - pageSize
        - totalPages
      properties:
        pageSize:
          type: integer
          description: Number of items per page
        totalPages:
          type: integer
          description: Total number of pages available
        nextToken:
          type: string
          description: Token for the next page of results. If there is no more data, it will be null.

    GatewayInfo:
      type: object
      required:
        - sn
        - eui
        - locationId
        - name
        - model
        - mac
        - status
      properties:
        sn:
          type: string
          description: The serial number of the gateway
        eui:
          type: string
          description: The EUI of the gateway
        locationId:
          type: string
          description: The location ID of the gateway, or "unassigned" when the gateway is not assigned to a location
          example: "unassigned"
        name:
          $ref: "#/components/schemas/GatewayName"
        model:
          type: string
          description: The model of the gateway
        mac:
          type: string
          pattern: "^([0-9a-fA-F]{2})(([:-][0-9a-fA-F]{2}){5})$"
          description: >
            The MAC address of the gateway's ethernet interface, formatted in the hexadecimal notation
            according to clause 1.1 and clause 2.1 of RFC 7042.
        version:
          type: string
          description: The reported firmware version of the gateway
        status:
          type: string
          description: The status of the gateway, online, offline, pre-provisioning, provisioning and unknown
          enum: [ONLINE, OFFLINE, PRE_PROVISIONING, PROVISIONING, UNKNOWN]
        lastDyingGasp:
          type: string
          description: last dying gasp event date time
          example: "2023-01-03 01:27:55"
        lastReportedTime:
          type: string
          description: The time when the gateway last reported status
          example: "2023-01-03 01:27:55"

    GatewayName:
      type: string
      maxLength: 32
      pattern: ^[A-Za-z0-9_-]*$
      description: The name of the gateway. Only letters, numbers, underscores, and hyphens are allowed.
      example: "RAK_Gateway-01"

    GatewayStatus:
      allOf:
        - $ref: "#/components/schemas/GatewayInfo"
        - type: object
          properties:
            system:
              $ref: "#/components/schemas/SystemStatistics"
            gps:
              description: GPS status of the gateway.
              $ref: "#/components/schemas/GPSStatus"
            network:
              description: Network status of the gateway.
              $ref: "#/components/schemas/NetworkStatus"
            lora:
              description: LoRa statistics of the gateway.
              $ref: "#/components/schemas/LoraStatistics"
            storage:
              description: Storage status of the gateway.
              $ref: "#/components/schemas/StorageStatistics"

    SystemStatistics:
      type: object
      properties:
        uptime:
          type: integer
          description: System uptime of the gateway in seconds
        cpu:
          description: CPU usage percentage of the gateway
          type: number
          format: double
          minimum: 0
          maximum: 100
        memory:
          description: Memory usage percentage of the gateway
          type: number
          format: double
          minimum: 0
          maximum: 100

    GPSStatus:
      description: GPS status of the gateway
      type: object
      properties:
        state:
          type: string
          description: GPS state of the gateway
          enum:
            [
              GPS_LOCKED_WITH_PPS,
              GPS_LOCKED_WITHOUT_PPS,
              GPS_UNLOCKED,
              GPS_NO_OUTPUT,
            ]
        satellites_number:
          type: integer
          description: Number of satellites the GPS module has locked on
        longitude:
          type: number
          format: double
          minimum: -180
          maximum: 180
        latitude:
          type: number
          format: double
          minimum: -90
          maximum: 90

    LoraStatistics:
      type: object
      description: LoRa statistics of the gateway
      properties:
        activeNodes:
          type: integer
          description: Total number of LoRa end devices active at last hours
          minimum: 0
        txPackets:
          type: integer
          description: Total number of LoRa packets sent by the gateway
          minimum: 0
        rxPackets:
          type: integer
          description: Total number of LoRa packets received by the gateway
          minimum: 0

    StorageStatistics:
      type: object
      properties:
        healthy:
          type: boolean
          description: |
            Indicates if the storage is healthy or not. 
            If the gateway carries a SD card, the storage is healthy if the SD card is inserted/not broken
            and the storage is not full.
            If the gateway does not carry a SD card, the storage is healthy if the storage is not full.
        total:
          type: integer
          description: Total size of the storage, unit MB
        free:
          type: integer
          description: Free size of the storage, unit MB
        used_percent:
          type: integer
          description: Percentage of used size of the storage
          minimum: 0
          maximum: 100

    NetworkStatus:
      type: object
      description: Current network status include LAN and WAN interfaces of the gateway
      properties:
        lan:
          description: LAN status always equal to its settings.
          $ref: "#/components/schemas/LanSettings"
        wan:
          description: WAN interface runtime status, including the active interface, IP address, and uptime.
          $ref: "#/components/schemas/WanStatus"

    WanStatus:
      type: object
      properties:
        active:
          description: Current active wan interface. None means something wrong.
          type: string
          enum: [NONE, ETH, CELLULAR, WIFI]
        ethernet:
          $ref: "#/components/schemas/WanEthernetInterface"
        wifi:
          $ref: "#/components/schemas/WanWifiInterface"
        cellular:
          $ref: "#/components/schemas/WanCellularInterface"

    WanInterface:
      type: object
      required:
        - enabled
        - priority
      properties:
        enabled:
          type: boolean
          description: Current WAN interface status, True represents the interface is enabled, False represents disabled.
        priority:
          type: integer
          description: The priority of the WAN interface
        online:
          type: boolean
          description: The online status of the WAN interface, True represents the interface is online, False represents the interface is offline.
        ipv4AddrMask:
          description: The IP address and mask of the WAN interface
          $ref: "#/components/schemas/Ipv4AddrMask"
        uptime:
          type: integer
          description: The uptime of the interface in seconds

    Ipv4Addr:
      type: string
      pattern: '^(?!0\.0\.0\.0$)(?!255\.255\.255\.255$)(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$'
      example: '198.51.100.1'
      description: >
        String identifying a IPv4 address formatted in the 'dotted decimal' notation
        as defined in RFC 1166.

    Ipv4Netmask:
      type: string
      pattern: '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$'
      example: "255.255.255.0"
      description: >
        String identifying a IPv4 netmask formatted in the 'dotted decimal' notation
        as defined in RFC 1166.

    Ipv4AddrMask:
      type: string
      pattern: '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$'
      example: "192.168.230.1/24"
      description: >
        "String identifying a IPv4 address mask formatted in the 'dotted decimal' notation
        as defined in RFC 1166."

    WanTrackTarget:
      type: string
      pattern: '^(?:(?!0\.0\.0\.0$)(?!255\.255\.255\.255$)(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])|(?![0-9]{1,3}(\.[0-9]{1,3}){3}$)(?=.{1,100}$)[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*\.[A-Za-z]{2,}|https?:\/\/(?=.{1,100}$)[A-Za-z0-9]([-.\w]*[A-Za-z0-9])?(\/[A-Za-z0-9\-._~:\/?#\[\]@!$&''()*+,;=%]*)?)$'
      description: >
        WAN tracking target. `ping` accepts IPv4 addresses or domain names;
        `httping` also accepts HTTP(S) URLs.

    WanEthernetInterface:
      $ref: "#/components/schemas/WanInterface"

    WanWifiInterface:
      $ref: "#/components/schemas/WanInterface"

    WanCellularInterface:
      allOf:
        - $ref: "#/components/schemas/WanInterface"
        - type: object
          properties:
            sim_present:
              type: boolean
              description: Whether the SIM card is inserted/detected or not
            imsi:
              type: string
              description: The IMSI of the cellular interface
            iccid:
              type: string
              description: The ICCID of the cellular interface
              example: "8986031900000000000"
            imei:
              type: string
              description: The IMEI of the cellular interface
              example: "8986031900000000000"
            signalLevel:
              type: integer
              description: The signal level of the cellular interface
            rsrp:
              type: number
              description: The RSRP of the cellular interface
            rsrq:
              type: number
              description: The RSRQ of the cellular interface
            sinr:
              type: number
              description: The SINR of the cellular interface
            rssi:
              type: number
              description: The RSSI of the cellular interface
            rat:
              type: string
              description: The Radio Access Type of the cellular interface
            networkType:
              type: string
              description: The network type of the cellular interface, FDD LTE, TDD LTE, etc.
            autoSelect:
              type: boolean
              description: Whether the operator auto selected enabled or not
            plmn:
              type: string
              description: The PLMN of the operator the cellular interface attached to

    SolarBatteryStatus:
      type: object
      properties:
        temperature:
          type: number
          example: 27
          description: Average temperature of the solar battery in Celsius
        voltage:
          type: number
          example: 14.56
          description: Current voltage of the solar battery in V
        soc:
          type: number
          example: 99
          description: State of charge of the solar battery in percentage
        current:
          type: number
          example: -0.14
          description: Current current of the solar battery in mA
        soh:
          type: number
          example: 100
          description: State of health of the solar battery in percentage
        cycles:
          type: number
          example: 33
          description: Cycle times of the solar battery
        remainCapacity:
          type: number
          example: 49990
          description: Remaining capacity of the solar battery in mAh
        fullChargeCapacity:
          type: number
          example: 50000
          description: Full charge capacity of the solar battery in mAh
        mode:
          type: string
          example: "Charging"
          description: Battery working mode
          enum:
            [
              CHARGING,
              DISCHARGING,
              FULLY_CHARGED,
              FULLY_DISCHARGED,
              PROTECT,
              PERMANENT_FAIL,
              UNKNOWN,
            ]

    GatewayMetric:
      type: object
      required:
        - value
        - timestamp
      properties:
        value:
          type: integer
          description: The value of the metric
        timestamp:
          type: string
          description: The timestamp of the metric

    ShellCommand:
      type: object
      required:
        - command
      properties:
        command:
          type: string
          description: The command to execute
          example: "netstat"
        args:
          type: string
          description: The arguments to execute the command
          example: "-an"

    NetworkPriority:
      type: string
      description: The priority order of the network
      enum:
        - ETH_CELLULAR_WIFI
        - ETH_WIFI_CELLULAR
        - ETH_CELLULAR
        - ETH_WIFI
        - CELLULAR_ETH_WIFI
        - CELLULAR_WIFI_ETH
        - CELLULAR_ETH
        - CELLULAR_WIFI
        - WIFI_CELLULAR_ETH
        - WIFI_ETH_CELLULAR
        - WIFI_ETH
        - WIFI_CELLULAR
        - INVALID

    WifiEncryptionType:
      type: string
      description: The encryption type of the Wi-Fi interface
      enum: [NONE, WPA-PSK, WPA2-PSK, WPA-WPA2-PSK-MIXED]

    LanSettings:
      type: object
      properties:
        subnet:
          description: Indicate the IP address on LAN interface and DHCP subnet for connecting devices
          $ref: "#/components/schemas/Ipv4AddrMask"
        ethernet:
          $ref: "#/components/schemas/LanEthernetSettings"
        wifi:
          $ref: "#/components/schemas/LanWifiSettings"

    LanEthernetSettings:
      type: object
      required:
        - enabled
      properties:
        enabled:
          type: boolean
          description: Whether the LAN ethernet interface is enabled

    LanWifiSettings:
      type: object
      required:
        - enabled
      properties:
        enabled:
          type: boolean
          description: Whether the LAN Wi-Fi interface is enabled
        ssid:
          type: string
          description: The SSID of the LAN Wi-Fi interface
          maxLength: 32
        encryption:
          $ref: "#/components/schemas/WifiEncryptionType"
        key:
          type: string
          description: |
            Present only when encryption is not NONE.
            The key of the LAN Wi-Fi interface. Should follow pattern ^[A-Za-z0-9~!@#$%^&*()_+=:;\[|\]{}.<>\-?/`" ]*$
            Minimum length is 8, maximum length is 63.
        channel:
          type: string
          description: The channel of the LAN Wi-Fi Interface
          enum:
            [
              Auto,
              2412MHz,
              2417MHz,
              2422MHz,
              2427MHz,
              2432MHz,
              2437MHz,
              2442MHz,
              2447MHz,
              2452MHz,
              2457MHz,
              2462MHz,
            ]
          default: Auto
        hidden:
          type: boolean
          description: Whether the LAN Wi-Fi interface is hidden

    WanSettings:
      type: object
      description: Desired WAN configuration persisted in WisDM. Provide only the interfaces you need to change.
      properties:
        ethernet:
          $ref: "#/components/schemas/WanEthernetSettings"
        wifi:
          $ref: "#/components/schemas/WanWifiSettings"
        cellular:
          $ref: "#/components/schemas/WanCellularSettings"

    WanEthernetSettings:
      type: object
      required:
        - enabled
      properties:
        enabled:
          type: boolean
          description: Whether the WAN ethernet interface is enabled
        protocol:
          type: string
          description: Ethernet protocol to use on WAN. Required when enabled is true.
          enum: [dhcp, static, pppoe]
        staticAddress:
          description: Static IP address configuration for WAN ethernet interface. Required when protocol is static.
          $ref: "#/components/schemas/WanStaticAddress"
        dhcpClient:
          description: DHCP client configuration for WAN ethernet interface. Required when protocol is dhcp.
          $ref: "#/components/schemas/WanDhcpClient"
        pppoe:
          description: PPPoE configuration for WAN ethernet interface. Required when protocol is pppoe.
          $ref: "#/components/schemas/WanPppoeClient"
        tracking:
          description: Tracking settings for WAN ethernet interface. Required when enabled is true.
          $ref: "#/components/schemas/WanTrackingSettings"

    WanWifiSettings:
      type: object
      required:
        - enabled
      properties:
        enabled:
          type: boolean
          description: Whether the WAN Wi-Fi interface is enabled
        ssid:
          type: string
          description: Target SSID of the upstream Wi-Fi network. Required when enabled is true.
        encryption:
          description: Encryption type for the upstream Wi-Fi network. Required when enabled is true.
          $ref: "#/components/schemas/WifiEncryptionType"
        key:
          type: string
          minLength: 8
          maxLength: 63
          description: The passphrase used when encryption is not NONE.
        protocol:
          type: string
          enum: [dhcp, static]
          description: IPv4 protocol used after the radio associates with the AP. Required when enabled is true.
        staticAddress:
          description: Static IP address configuration for WAN Wi-Fi interface. Required when protocol is static.
          $ref: "#/components/schemas/WanStaticAddress"
        dhcpClient:
          description: DHCP client configuration for WAN Wi-Fi interface. Required when protocol is dhcp.
          $ref: "#/components/schemas/WanDhcpClient"
        tracking:
          description: Tracking settings for WAN Wi-Fi interface. Required when enabled is true.
          $ref: "#/components/schemas/WanTrackingSettings"

    WanCellularSettings:
      type: object
      required:
        - enabled
      properties:
        enabled:
          type: boolean
          description: Whether the WAN cellular interface is enabled
        apn:
          type: string
          description: The APN (Access Point Name) might be essential for seamless cellular connectivity. Check with your internet service provider whether it's needed for you.
        username:
          type: string
          description: The username for SIM profiles that require authentication.
        password:
          type: string
          description: The password for SIM profiles that require authentication.
        pinCode:
          type: string
          description: The SIM PIN code, if applicable.
        tracking:
          description: Tracking settings for WAN cellular interface. Required when enabled is true.
          $ref: "#/components/schemas/WanTrackingSettings"

    WanStaticAddress:
      type: object
      required:
        - ipv4Address
        - ipv4Netmask
        - ipv4Router
        - dnsServers
      properties:
        ipv4Address:
          description: Static IPv4 address assigned to the WAN device
          $ref: "#/components/schemas/Ipv4Addr"
        ipv4Netmask:
          description: Subnet mask associated with the IPv4 address
          $ref: "#/components/schemas/Ipv4Netmask"
        ipv4Router:
          description: Default IPv4 gateway
          $ref: "#/components/schemas/Ipv4Addr"
        dnsServers:
          type: array
          minItems: 1
          maxItems: 3
          description: Custom DNS servers applied when using static addressing
          items:
            $ref: "#/components/schemas/Ipv4Addr"

    WanDhcpClient:
      type: object
      required:
        - useDNS
      properties:
        useDNS:
          type: boolean
          description: Whether to accept DNS servers advertised by the DHCP server
        dnsServers:
          type: array
          minItems: 1
          maxItems: 3
          description: Required when useDNS is false; overrides DHCP provided DNS servers
          items:
            $ref: "#/components/schemas/Ipv4Addr"

    WanPppoeClient:
      type: object
      required:
        - username
        - password
        - useDNS
      properties:
        username:
          type: string
          minLength: 1
          maxLength: 255
          description: PAP/CHAP username
        password:
          type: string
          minLength: 1
          maxLength: 255
          description: PAP/CHAP password
        useDNS:
          type: boolean
          description: Whether to use DNS servers advertised by PPPoE authentication
        dnsServers:
          type: array
          minItems: 1
          maxItems: 3
          description: Required when useDNS is false; overrides PPPoE provided DNS servers
          items:
            $ref: "#/components/schemas/Ipv4Addr"

    WanTrackingSettings:
      type: object
      required:
        - trackMethod
        - trackTargets
        - reliability
        - pingCount
        - pingInterval
        - pingTimeout
        - interfaceDown
        - interfaceUp
      properties:
        trackMethod:
          type: string
          description: Probe type used for connectivity checks
          enum: [ping, httping]
          default: ping
        trackTargets:
          type: array
          minItems: 1
          maxItems: 5
          description: Target IP addresses, hostnames, or HTTP(S) URLs that are probed to verify WAN health
          items:
            $ref: "#/components/schemas/WanTrackTarget"
        reliability:
          type: integer
          minimum: 1
          maximum: 100
          description: The minimum number if IP addresses that must responsed to confirm a successful ping test
        pingCount:
          type: integer
          minimum: 1
          maximum: 100
          description: Number of packets sent during each probe cycle
        pingTimeout:
          type: integer
          minimum: 1
          maximum: 10
          description: Timeout in seconds for each probe packet
        pingInterval:
          type: integer
          enum: [1, 3, 5, 10, 20, 30, 60, 300, 600, 900, 1800, 3600]
          description: Interval in seconds between probe cycles
        interfaceDown:
          type: integer
          minimum: 1
          maximum: 10
          description: Number of ping tests that must fail consecutively to confirm the interface is down
        interfaceUp:
          type: integer
          minimum: 1
          maximum: 10
          description: Number of ping tests that must succeed consecutively to confirm the interface is up

    GatewayLogFile:
      type: object
      required:
        - key
        - sizeBytes
        - lastModified
        - downloadUrl
        - expiresAt
      properties:
        key:
          type: string
          description: Full S3 object key of the log file.
        sizeBytes:
          type: integer
          format: int64
          description: Size of the log file in bytes.
        lastModified:
          type: string
          format: date-time
          description: Timestamp when the log file was last modified in S3.
        downloadUrl:
          type: string
          format: uri
          description: Pre-signed URL that can be used to download the log file.
        expiresAt:
          type: string
          format: date-time
          description: Timestamp (UTC) when the pre-signed URL expires.


    ExternalLogServer:
      type: object
      properties:
        ip:
          description: IPv4 address of the external syslog server.
          $ref: "#/components/schemas/Ipv4Addr"
        port:
          type: integer
          minimum: 1
          maximum: 65535
          description: TCP/UDP port of the external syslog server.

    GatewayLogLevel:
      description: |
        Minimum severity of gateway logs to forward. `error` forwards only critical failures,
        while `debug` forwards all logs. Defaults to "info".
      type: string
      enum:
        - error
        - warning
        - notice
        - info
        - debug

    ProblemDetails:
      type: object
      properties:
        statusCode:
          type: integer
          description: The HTTP status code for this occurrence of the problem
        errorMessage:
          type: string
          description: A human-readable explanation specific to this occurrence of the problem

  responses:
    BadRequest:
      description: Bad Request
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ProblemDetails"

    Forbidden:
      description: Access Denied
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ProblemDetails"

    NotAcceptable:
      description: Not Acceptable
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ProblemDetails"

    InternalServerError:
      description: Internal Server Error
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ProblemDetails"

    NotFound:
      description: Resource Not Found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ProblemDetails"

    Conflict:
      description: Resource conflict
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ProblemDetails"
