openapi: 3.0.3

info:
  title: Volumizer / BeeVision Dimensioner API
  version: "1.4.0"
  description: |
    BeeVision dimensioners expose an embedded HTTP service for remote
    measurement, calibration, configuration, conveyor control and label
    printing.

    All API requests are sent to the base path
    `/beevisionservice/<command>` on the device. By default the service
    is reachable on the standard HTTP port **80**. The same handlers are
    also bound to port **27018** (plain HTTP) and port **443** (HTTPS)
    when those listeners are enabled on the device.

    * Use `GET` when no data is sent from the client to the device.
    * Use `POST` and a JSON body otherwise.
    * Responses are JSON. Successful operations return `StatusCode = 0`
      and `StatusMessage = "Operation successful"`. Failures return a
      negative `StatusCode` and a human-readable `StatusMessage`.

    This document only covers the public commands listed in the
    *Software Guide v1.4.0 – Accepted Commands by Volumizer API*
    section. Internal endpoints used by the Web UI are intentionally
    omitted.

    > **Note on two PDF typos.** The Software Guide PDF prints
    > `getMeasurmentSettingsFile` and `startReverseConveyor`. The real
    > command names accepted by the device are
    > `getMeasurementSettingsFile` and `reverseStartConveyor` — those are
    > the ones used in this spec.
  contact:
    name: 3DTIM / BeeVision Support
    email: info@beevision.ai
    url: https://beevision.ai
  license:
    name: Proprietary
    url: https://beevision.ai

servers:
  - url: http://{host}/beevisionservice
    description: BeeVision device on the primary HTTP port (80)
    variables:
      host:
        default: localhost
        description: IP address or hostname of the BeeVision dimensioner
  - url: http://{host}:{port}/beevisionservice
    description: BeeVision device on a custom API port (default 27018)
    variables:
      host:
        default: localhost
        description: IP address or hostname of the BeeVision dimensioner
      port:
        default: "27018"
        description: Custom API port configured on the device
  - url: https://{host}/beevisionservice
    description: BeeVision device on HTTPS port 443 (if enabled)
    variables:
      host:
        default: localhost
        description: IP address or hostname of the BeeVision dimensioner

tags:
  - name: Measurement
    description: Trigger measurements and query results.
  - name: Camera & Calibration
    description: Start/stop the depth camera and run calibration.
  - name: Device Info & Lifecycle
    description: Serial number, software version, device info, reboot and updates.
  - name: Settings Files
    description: Get/set calibration, user and measurement settings.
  - name: Records, Images & Logs
    description: Download or delete measurement records, images and log archives.
  - name: Network
    description: Ethernet and Wi-Fi configuration.
  - name: Date & Time
    description: Read or update the device clock.
  - name: External Barcode & Image
    description: Push external barcode or image data into the device.
  - name: Conveyor
    description: Conveyor / PLC start, reverse and stop.
  - name: Label Printing
    description: Send ZPL label data to the connected printer.

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        Some deployments enable JWT-protected API access. When enabled,
        every request must include `Authorization: Bearer <token>`. The
        token is obtained from `webUILogin` using HTTP Basic auth.
        On a device with JWT disabled (the default), this header is not
        required.

  parameters:
    BarcodeQuery:
      name: barcode
      in: query
      required: false
      schema:
        type: string
      description: |
        Optional barcode value to attach to the measurement.
        Example: `?barcode=1234567`.
    MeasurementIdQuery:
      name: measurementId
      in: query
      required: false
      schema:
        type: integer
      description: Query measurement records by numeric measurement ID.
    DateQuery:
      name: date
      in: query
      required: false
      schema:
        type: string
        format: date
      description: |
        Query measurement records by date in `YYYY-MM-DD` format,
        e.g. `2023-01-30`.
    IncludeImagesQuery:
      name: includeImages
      in: query
      required: false
      schema:
        type: boolean
        default: false
      description: |
        When `true`, the `ImageBase64` field is populated in returned
        records. Defaults to `false`.

  schemas:
    BaseStatusResponse:
      type: object
      properties:
        StatusCode:
          type: integer
          description: 0 on success. Negative value on failure.
          example: 0
        StatusMessage:
          type: string
          description: Empty / "Operation successful" on success, error text otherwise.
          example: Operation successful
      required:
        - StatusCode
        - StatusMessage

    MeasurementResult:
      type: object
      description: |
        Result of a measurement operation. Shape mirrors the JSON payload
        the device emits over both its async web-service POST and the
        synchronous `/measure`-family commands.
      properties:
        StatusCode:
          type: integer
          description: 0 on success. Negative value on failure.
          example: 0
        StatusMessage:
          type: string
          example: OK
        Width:
          type: string
          example: "40.1"
        Length:
          type: string
          example: "29.4"
        Height:
          type: string
          example: "21.0"
        DimWt:
          type: string
          description: Dimensional weight using the configured divisor.
          example: "4.9"
        RealVolume:
          type: string
          example: "24018"
        Weight:
          type: string
          description: Empty when no scale is connected.
          example: "0.84"
        UnitID:
          type: string
          example: "663"
        BranchID:
          type: string
          example: "1"
        Barcode:
          type: string
          example: "31959968681"
        BarcodeType:
          type: string
          example: ""
        BarcodeSource:
          type: string
          description: |
            `Manual` = from a handheld scanner; `Auto` = from a fixed-mount
            barcode reader.
          example: Auto
        Date:
          type: string
          example: "19.02.2019"
        Time:
          type: string
          example: "16:40:28"
        MeasurementID:
          type: string
          example: "5505"
        ImageBase64:
          type: string
          description: |
            Base64-encoded JPEG. Empty for `measure`/`getLastResult`,
            populated for `captureMeasure`/`getLastImageAndResult` and
            for `getMeasurement` when `includeImages=true`.
          example: ""
        SerialNumber:
          type: string
          example: "160233"
        DimUnit:
          type: string
          example: cm
        WeightUnit:
          type: string
          example: kg
        IsRegular:
          type: integer
          description: 1 = regular shape, 0 = irregular shape.
          example: 1
        ObjectRGBCoordinates:
          type: string
          description: Corner coordinates in the RGB image as `x1,y1|x2,y2|x3,y3|x4,y4`.
          example: "43,44|22,47|48,42|5,5"
        Operator:
          type: string
          description: User ID of the operator who triggered the measurement.
          example: admin
        Reserved1:
          type: string
          example: ""
        CRC:
          type: string
          description: CRC16 checksum of the whole message excluding this field.
          example: "123123"

    MeasurementListResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: "#/components/schemas/MeasurementResult"

    SerialNumberResponse:
      allOf:
        - $ref: "#/components/schemas/BaseStatusResponse"
        - type: object
          properties:
            SerialNumber:
              type: string
              example: "160122"

    SoftwareVersionResponse:
      allOf:
        - $ref: "#/components/schemas/BaseStatusResponse"
        - type: object
          properties:
            SoftwareVersion:
              type: string
              example: "3.6.6"

    DeviceInfoResponse:
      allOf:
        - $ref: "#/components/schemas/BaseStatusResponse"
        - type: object
          properties:
            DeviceModel:
              type: string
              example: BeeVision 3DT270
            SWChecksum:
              type: string
              example: 12d6c1d5322723d59fe81731627ba4fe
            CertificateNumber:
              type: string
              example: "N/A"
            MinWidth:
              type: string
              example: "10"
            MinLength:
              type: string
              example: "10"
            MinHeight:
              type: string
              example: "10"
            MaxWidth:
              type: string
              example: "80"
            MaxLength:
              type: string
              example: "80"
            MaxHeight:
              type: string
              example: "80"
            WidthAccuracy:
              type: string
              example: "1"
            LengthAccuracy:
              type: string
              example: "1"
            HeightAccuracy:
              type: string
              example: "1"
            CertificationStatus:
              type: string
              description: "0 = not sealed, 1 = sealed for certification."
              example: "0"

    DateTimeResponse:
      allOf:
        - $ref: "#/components/schemas/BaseStatusResponse"
        - type: object
          properties:
            Date:
              type: string
              example: "22/05/2019"
            Time:
              type: string
              example: "00:27:07"

    SetDateAndTimeRequest:
      type: object
      properties:
        Date:
          type: string
          description: Date in `DD/MM/YYYY` format.
          example: "22/05/2019"
        Time:
          type: string
          description: Time in `HH:mm:ss` format.
          example: "00:27:07"
      required:
        - Date
        - Time

    WeightResponse:
      allOf:
        - $ref: "#/components/schemas/BaseStatusResponse"
        - type: object
          properties:
            Date:
              type: string
              example: "17.03.2026"
            Time:
              type: string
              example: "06:27:39"
            Weight:
              type: string
              example: "0.202"
            WeightUnit:
              type: string
              example: kg

    UpdateCheckResponse:
      allOf:
        - $ref: "#/components/schemas/BaseStatusResponse"
        - type: object
          properties:
            UpdateExists:
              type: boolean
              example: false

    NetworkSettings:
      type: object
      description: |
        Ethernet/Wi-Fi configuration. Each numeric field is one octet of
        the corresponding address.
      properties:
        interfaceName:
          type: string
          description: Name of the interface (e.g. `Ethernet`, `Wi-Fi`).
          example: Ethernet
        dynamicIP:
          type: string
          description: '`dynamic` for DHCP, `static` for manual configuration.'
          enum: [dynamic, static]
          example: static
        ip1:
          type: string
          example: "10"
        ip2:
          type: string
          example: "2"
        ip3:
          type: string
          example: "1"
        ip4:
          type: string
          example: "110"
        subnet1:
          type: string
          example: "255"
        subnet2:
          type: string
          example: "0"
        subnet3:
          type: string
          example: "0"
        subnet4:
          type: string
          example: "0"
        gateway1:
          type: string
          example: "0"
        gateway2:
          type: string
          example: "0"
        gateway3:
          type: string
          example: "0"
        gateway4:
          type: string
          example: "0"
        dns1:
          type: string
          example: "192"
        dns2:
          type: string
          example: "168"
        dns3:
          type: string
          example: "1"
        dns4:
          type: string
          example: "1"
      required:
        - interfaceName
        - dynamicIP
        - ip1
        - ip2
        - ip3
        - ip4
        - subnet1
        - subnet2
        - subnet3
        - subnet4
        - gateway1
        - gateway2
        - gateway3
        - gateway4
        - dns1
        - dns2
        - dns3
        - dns4

    WifiNetworksResponse:
      allOf:
        - $ref: "#/components/schemas/BaseStatusResponse"
        - type: object
          properties:
            Networks:
              type: array
              description: List of nearby Wi-Fi network SSIDs detected during the scan.
              items:
                type: string

    ConnectToWifiRequest:
      type: object
      properties:
        network:
          type: string
          description: SSID of the Wi-Fi network to join.
          example: MyOffice
        password:
          type: string
          description: Network passphrase (omit / leave empty for open networks).
          example: hunter2
      required:
        - network

    DownloadRecordsRequest:
      type: object
      properties:
        DownloadAll:
          type: integer
          description: |
            When `1`, downloads the entire records file. When `0`, the
            range bounded by `From` and `To` is downloaded.
          enum: [0, 1]
          example: 1
        From:
          type: string
          description: |
            Start of date/time range in `YYYY-MM-DDTHH:mm` format
            (e.g. `2019-12-25T19:00`). Ignored when `DownloadAll = 1`.
          example: ""
        To:
          type: string
          description: |
            End of date/time range in `YYYY-MM-DDTHH:mm` format. Ignored
            when `DownloadAll = 1`.
          example: ""
      required:
        - DownloadAll

    ExternalBarcodeItem:
      type: object
      properties:
        Barcode:
          type: string
          example: "1231231"
        BarcodeType:
          type: integer
          description: Numeric barcode type code.
          example: 3
      required:
        - Barcode

    SetExternalBarcodeRequest:
      type: object
      properties:
        BarcodeList:
          type: array
          items:
            $ref: "#/components/schemas/ExternalBarcodeItem"
        ImageBase64:
          type: string
          description: Optional base64-encoded JPEG.
          example: ""
      required:
        - BarcodeList

    SetExternalBarcodeImageRequest:
      type: object
      properties:
        ImageBase64:
          type: string
          description: Base64-encoded JPEG image of the package.
      required:
        - ImageBase64

    ConveyorRunRequest:
      type: object
      properties:
        runTime_ms:
          type: string
          description: |
            Optional run duration in milliseconds. When provided, the
            conveyor stops automatically after the specified interval.
          example: "1000"

    ZPLPrintRequest:
      type: object
      properties:
        ZPLMessage:
          type: string
          description: A ZPL II command stream to send to the connected printer.
          example: |
            ^XA
            ^FX Top section with company logo, name and address.
            ^CF0,60
            ^FO50,50^GB100,100,100^FS
            ^FO75,75^FR^GB100,100,100^FS
            ^FO88,88^GB50,50,50^FS
            ^FO220,50^FD3DTIM Elektronik^FS
            ^CF0,40
            ^FO220,100^FDODTU^FS
            ^FO220,135^FDAnkara 06800^FS
            ^FO220,170^FDTurkey^FS
            ^FO50,250^GB700,1,3^FS
            ^XZ
      required:
        - ZPLMessage

  responses:
    Success:
      description: Operation completed successfully.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/BaseStatusResponse"
    NotAllowed:
      description: HTTP method not allowed for this endpoint.
    Unauthorized:
      description: Authentication required (only returned when JWT mode is enabled).

# By default, no security is applied: the API is reachable without auth
# on devices where JWT is disabled, which matches the Software Guide
# examples. When JWT mode is enabled on the device, attach the
# `bearerAuth` scheme manually via "Authorize" in Swagger UI.
security: []

paths:
  /measure:
    get:
      tags: [Measurement]
      operationId: measure
      summary: Trigger a new measurement and return the result
      description: |
        In non-automatic trigger modes, `measure` triggers a new
        measurement and returns the result. The `ImageBase64` field is
        left empty. Optionally accepts a `barcode` query parameter to
        attach to the measurement.

        If automatic trigger mode is selected, the most recent
        measurement result is returned instead.
      parameters:
        - $ref: "#/components/parameters/BarcodeQuery"
      responses:
        "200":
          description: Measurement result.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MeasurementResult"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /captureMeasure:
    get:
      tags: [Measurement]
      operationId: captureMeasure
      summary: Trigger a measurement and return the result with image
      description: |
        Same as `measure` but the response includes the captured image
        as a base64-encoded string in `ImageBase64`. Optionally accepts a
        `barcode` query parameter.

        If automatic trigger mode is selected, the most recent
        measurement result is returned instead.
      parameters:
        - $ref: "#/components/parameters/BarcodeQuery"
      responses:
        "200":
          description: Measurement result including image.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MeasurementResult"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getLastResult:
    get:
      tags: [Measurement]
      operationId: getLastResult
      summary: Return the most recent measurement result (no image)
      description: |
        Returns the last cached measurement result. Does **not** trigger
        a new measurement. `ImageBase64` is left empty.
      responses:
        "200":
          description: Last measurement result.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MeasurementResult"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getLastImageAndResult:
    get:
      tags: [Measurement]
      operationId: getLastImageAndResult
      summary: Return the most recent measurement result with image
      description: |
        Returns the last cached measurement result with the captured
        image included as `ImageBase64`. Does **not** trigger a new
        measurement.
      responses:
        "200":
          description: Last measurement result including image.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MeasurementResult"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getMeasurement:
    get:
      tags: [Measurement]
      operationId: getMeasurement
      summary: Query stored measurement records
      description: |
        Queries previously stored measurement records using one of the
        supported filters. Results are returned as a JSON array under
        the `results` key.

        Accepted query parameters:

        - `barcode` — match measurements that have the given barcode.
        - `measurementId` — match by numeric measurement ID.
        - `date` — match all measurements taken on a `YYYY-MM-DD` date.
        - `includeImages` — when `true`, include the `ImageBase64` field.

        Examples:

        ```
        /beevisionservice/getMeasurement?barcode=1234567
        /beevisionservice/getMeasurement?measurementId=3
        /beevisionservice/getMeasurement?date=2021-12-14
        /beevisionservice/getMeasurement?date=2023-01-30&includeImages=false
        ```
      parameters:
        - $ref: "#/components/parameters/BarcodeQuery"
        - $ref: "#/components/parameters/MeasurementIdQuery"
        - $ref: "#/components/parameters/DateQuery"
        - $ref: "#/components/parameters/IncludeImagesQuery"
      responses:
        "200":
          description: List of stored measurement records matching the query.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MeasurementListResponse"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /resetResultsLabel:
    get:
      tags: [Measurement]
      operationId: resetResultsLabel
      summary: Clear the on-screen measurement result and bounding box
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getWeight:
    get:
      tags: [Measurement]
      operationId: getWeight
      summary: Read the current weight from the connected scale
      description: |
        Returns the current weight value from the connected scale,
        without triggering a measurement. The response always includes a
        timestamp and the configured weight unit.
      responses:
        "200":
          description: Latest weight reading.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WeightResponse"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /startCamera:
    get:
      tags: [Camera & Calibration]
      operationId: startCamera
      summary: Start the 3D camera
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /stopCamera:
    get:
      tags: [Camera & Calibration]
      operationId: stopCamera
      summary: Stop the 3D camera
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /calibrate:
    get:
      tags: [Camera & Calibration]
      operationId: calibrate
      summary: Perform device calibration
      description: |
        Performs a calibration cycle and returns the calibration success
        status. Fails with a corresponding error message when the
        software is sealed for certification.
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getSerial:
    get:
      tags: [Device Info & Lifecycle]
      operationId: getSerial
      summary: Return the device serial number
      responses:
        "200":
          description: Device serial number.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SerialNumberResponse"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getSWVersion:
    get:
      tags: [Device Info & Lifecycle]
      operationId: getSWVersion
      summary: Return the Volumizer software version
      responses:
        "200":
          description: Volumizer software version.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SoftwareVersionResponse"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getDeviceInfo:
    get:
      tags: [Device Info & Lifecycle]
      operationId: getDeviceInfo
      summary: Return device model, accuracy bounds and certification status
      responses:
        "200":
          description: Device information.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeviceInfoResponse"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /resetDevice:
    get:
      tags: [Device Info & Lifecycle]
      operationId: resetDevice
      summary: Reboot the device
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /checkForUpdates:
    get:
      tags: [Device Info & Lifecycle]
      operationId: checkForUpdates
      summary: Check whether a newer Volumizer version is available
      responses:
        "200":
          description: Update availability.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UpdateCheckResponse"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /updateVolumizer:
    get:
      tags: [Device Info & Lifecycle]
      operationId: updateVolumizer
      summary: Apply the latest Volumizer update
      description: |
        Applies the update located by the most recent `checkForUpdates`
        call. Must be invoked **after** `checkForUpdates`; otherwise the
        device returns an error.
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getCalibrationSettingsFile:
    get:
      tags: [Settings Files]
      operationId: getCalibrationSettingsFile
      summary: Download calibration settings JSON
      responses:
        "200":
          description: Calibration settings.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        "405":
          $ref: "#/components/responses/NotAllowed"

  /setCalibrationSettingsFile:
    post:
      tags: [Settings Files]
      operationId: setCalibrationSettingsFile
      summary: Overwrite calibration settings JSON
      description: |
        Overwrites the calibration settings file. It is strongly
        recommended to fetch the current file via
        `getCalibrationSettingsFile`, modify it locally and POST it back
        here. Fails when the software is sealed for certification.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getUserSettingsFile:
    get:
      tags: [Settings Files]
      operationId: getUserSettingsFile
      summary: Download user settings JSON
      responses:
        "200":
          description: User settings.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        "405":
          $ref: "#/components/responses/NotAllowed"

  /setUserSettingsFile:
    post:
      tags: [Settings Files]
      operationId: setUserSettingsFile
      summary: Overwrite user settings JSON
      description: |
        Overwrites the user settings file. It is recommended to fetch
        the current file via `getUserSettingsFile`, edit it locally and
        POST it back here.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getMeasurementSettingsFile:
    get:
      tags: [Settings Files]
      operationId: getMeasurementSettingsFile
      summary: Download measurement settings JSON
      description: |
        Returns the measurement settings file, which contains the
        legally-relevant parameters of the device.

        > The Software Guide v1.4.0 PDF lists this endpoint as
        > `/getMeasurmentSettingsFile`. That spelling is a typo in the
        > PDF — the device only accepts `getMeasurementSettingsFile`.
      responses:
        "200":
          description: Measurement settings.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        "405":
          $ref: "#/components/responses/NotAllowed"

  /setMeasurementSettingsFile:
    post:
      tags: [Settings Files]
      operationId: setMeasurementSettingsFile
      summary: Overwrite measurement settings JSON
      description: |
        Overwrites the measurement settings file. It is strongly
        recommended to fetch the current file via
        `getMeasurementSettingsFile`, modify it locally and POST it back
        here. Fails when the software is sealed for certification.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getRecordsFile:
    get:
      tags: [Records, Images & Logs]
      operationId: getRecordsFile
      summary: Return all stored measurement records
      responses:
        "200":
          description: Stored measurement records.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
            application/xml:
              schema:
                type: string
        "405":
          $ref: "#/components/responses/NotAllowed"

  /downloadRecordsFile:
    post:
      tags: [Records, Images & Logs]
      operationId: downloadRecordsFile
      summary: Download stored measurement records as an XML file
      description: |
        Returns previously saved measurement records as an XML file.

        Body fields:

        - `DownloadAll` — `1` to download all records, `0` to filter by
          date range.
        - `From`, `To` — date/time range in `YYYY-MM-DDTHH:mm` format
          (e.g. `2019-12-25T19:00`). Required when `DownloadAll = 0`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DownloadRecordsRequest"
      responses:
        "200":
          description: XML file of measurement records.
          content:
            application/xml:
              schema:
                type: string
                format: binary
            application/octet-stream:
              schema:
                type: string
                format: binary
        "405":
          $ref: "#/components/responses/NotAllowed"

  /downloadBatchRecordsZip:
    get:
      tags: [Records, Images & Logs]
      operationId: downloadBatchRecordsZip
      summary: Download group (batch) measurement records as a ZIP
      responses:
        "200":
          description: ZIP archive of batch measurement records.
          content:
            application/zip:
              schema:
                type: string
                format: binary
            application/octet-stream:
              schema:
                type: string
                format: binary
        "405":
          $ref: "#/components/responses/NotAllowed"

  /downloadImagesZip:
    get:
      tags: [Records, Images & Logs]
      operationId: downloadImagesZip
      summary: Download stored measurement images as a ZIP
      description: |
        Returns a ZIP archive containing every image stored on the
        device. The `downloadRecordsFile` JSON body schema may be reused
        with this endpoint to restrict the export by date range.
      responses:
        "200":
          description: ZIP archive of measurement images.
          content:
            application/zip:
              schema:
                type: string
                format: binary
            application/octet-stream:
              schema:
                type: string
                format: binary
        "405":
          $ref: "#/components/responses/NotAllowed"

  /deleteMeasurementImages:
    get:
      tags: [Records, Images & Logs]
      operationId: deleteMeasurementImages
      summary: Delete all stored measurement images
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /deleteMeasurementRecords:
    get:
      tags: [Records, Images & Logs]
      operationId: deleteMeasurementRecords
      summary: Delete all stored measurement records
      description: |
        Deletes every measurement record stored on the device. Fails
        when the software is sealed for certification.
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /downloadAllLogs:
    get:
      tags: [Records, Images & Logs]
      operationId: downloadAllLogs
      summary: Download every log file as a ZIP
      responses:
        "200":
          description: ZIP archive containing every log file.
          content:
            application/zip:
              schema:
                type: string
                format: binary
            application/octet-stream:
              schema:
                type: string
                format: binary
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getEthernetSettings:
    get:
      tags: [Network]
      operationId: getEthernetSettings
      summary: Return Ethernet configuration
      responses:
        "200":
          description: Ethernet settings.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NetworkSettings"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /setEthernetSettings:
    post:
      tags: [Network]
      operationId: setEthernetSettings
      summary: Overwrite Ethernet configuration
      description: |
        Overwrites Ethernet settings. Required JSON fields are listed in
        the `NetworkSettings` schema below. Use `getEthernetSettings`
        first to obtain the current `interfaceName`.

        **If you change the device's IP with this call, remember to
        update your client to use the new address.**
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NetworkSettings"
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getWifiSettings:
    get:
      tags: [Network]
      operationId: getWifiSettings
      summary: Return Wi-Fi configuration
      responses:
        "200":
          description: Wi-Fi settings.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NetworkSettings"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /setWifiSettings:
    post:
      tags: [Network]
      operationId: setWifiSettings
      summary: Overwrite Wi-Fi configuration
      description: |
        Overwrites Wi-Fi settings. Body schema is identical to
        `setEthernetSettings`.

        **If you change the device's IP with this call, remember to
        update your client to use the new address.**
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NetworkSettings"
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /scanWifiNetworks:
    get:
      tags: [Network]
      operationId: scanWifiNetworks
      summary: Scan and return available Wi-Fi networks
      description: |
        Starts a Wi-Fi scan and returns the discovered network SSIDs.
        The call typically takes more than 4 seconds to return.
      responses:
        "200":
          description: List of Wi-Fi networks discovered nearby.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WifiNetworksResponse"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /connectToWifi:
    post:
      tags: [Network]
      operationId: connectToWifi
      summary: Connect to a Wi-Fi network
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ConnectToWifiRequest"
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /getDateAndTime:
    get:
      tags: [Date & Time]
      operationId: getDateAndTime
      summary: Return the device date and time
      responses:
        "200":
          description: Current device date and time.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DateTimeResponse"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /setDateAndTime:
    post:
      tags: [Date & Time]
      operationId: setDateAndTime
      summary: Overwrite the device date and time
      description: |
        Overwrites the device date and time. It is recommended to fetch
        the current value via `getDateAndTime`, modify it and post it
        back.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SetDateAndTimeRequest"
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /setExternalBarcodeResult:
    post:
      tags: [External Barcode & Image]
      operationId: setExternalBarcodeResult
      summary: Push external barcode data into the device
      description: |
        Sends an externally scanned barcode (and optional image) to the
        device. Not supported on static BeeVision dimensioners.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SetExternalBarcodeRequest"
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /setExternalBarcodeImage:
    post:
      tags: [External Barcode & Image]
      operationId: setExternalBarcodeImage
      summary: Push an external package image into the device
      description: |
        Sends a base64-encoded image of the package to the device. Not
        supported on static BeeVision dimensioners.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SetExternalBarcodeImageRequest"
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /startConveyor:
    post:
      tags: [Conveyor]
      operationId: startConveyor
      summary: Start the conveyor
      description: |
        Starts the conveyor (if connected). When `runTime_ms` is
        provided, the conveyor stops automatically after the configured
        interval.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ConveyorRunRequest"
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /reverseStartConveyor:
    post:
      tags: [Conveyor]
      operationId: reverseStartConveyor
      summary: Start the conveyor in reverse direction
      description: |
        Starts the conveyor in the reverse direction. When `runTime_ms`
        is provided, the conveyor stops automatically after the
        configured interval.

        > The Software Guide v1.4.0 PDF lists this endpoint as
        > `/startReverseConveyor`. That spelling is a PDF typo — the
        > device only accepts `reverseStartConveyor`.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ConveyorRunRequest"
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /stopConveyor:
    post:
      tags: [Conveyor]
      operationId: stopConveyor
      summary: Stop the conveyor
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"

  /printZPLLabel:
    post:
      tags: [Label Printing]
      operationId: printZPLLabel
      summary: Send a ZPL command stream to the connected label printer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ZPLPrintRequest"
      responses:
        "200":
          $ref: "#/components/responses/Success"
        "405":
          $ref: "#/components/responses/NotAllowed"
