openapi: 3.0.0
servers:
  - url: 'http://127.0.0.1/fsi/service'
    description: Local FSI Server Instance
  - url: 'http://127.0.0.1:8080/fsi/service'
    description: Local FSI Server Instance in port 8080
  - url: 'https://demo.fsi-server.com/fsi/service'
    description: Public Demo Server
info:
  title: FSI Server Service API
  version: '1.0'
  contact:
    name: NeptuneLabs
    url: 'https://www.neptunelabs.com/'
    email: info@neptunelabs.com
  termsOfService: 'https://www.neptunelabs.com/terms-conditions/'
  license:
    name: Apache 2.0
    url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
  description: |-
    FSI Server Service API v1

    This API allows you to authenticate with the server, manage assets and directories,
    trigger batch jobs, configure preferences, and manage two‑factor authentication (TOTP).

    Authentication flow overview:
    * Call GET /login to obtain a salt. The server also sets the session cookie `JSESSIONID`.
    * Compute `sha256(salt + sha256(password))` and POST /login with your username and the hashed password.
    * If two‑factor authentication is enabled or required, use the /totp endpoints to create or validate a TOTP code.
    * Include the `JSESSIONID` cookie on all subsequent requests.
externalDocs:
  description: FSI Server Documentation
  url: 'https://docs.neptunelabs.com/'
paths:
  /login:
    get:
      summary: Get Salt
      tags:
        - Authentication
      responses:
        '200':
          $ref: '#/components/responses/Salt'
      operationId: get-login
      description: |-
        Retrieve a per‑login salt and establish a session cookie.
        The response includes a `salt` value for hashing your password and sets a `JSESSIONID` cookie.
        Send this cookie with the subsequent POST /login request.
      security: []
    post:
      summary: Login
      operationId: post-login
      responses:
        '200':
          $ref: '#/components/responses/Login'
      description: |-
        Authenticate with username and password hashed as `sha256(salt + sha256(password))` using the `salt` from GET /login.
        On success, the session cookie remains valid for subsequent requests. If TOTP is required, the response indicates this in the `messageCode`.
      tags:
        - Authentication
      requestBody:
        $ref: '#/components/requestBodies/Login'
  /health:
    get:
      summary: Check Server Health
      responses:
        '200':
          $ref: '#/components/responses/Health'
        '500':
          $ref: '#/components/responses/ErrorGeneral'
      operationId: get-health
      description: |-
        Retrieves the current health status of the FSI Server instance.
        This endpoint performs a check to determine if the service is operational. It is primarily intended for automated monitoring systems, load balancers (e.g., as a heartbeat check), or liveness probes.
        The response provides a JSON object with the `status` field, returning either `ok` (system healthy) or `failed` (system malfunctioning).
      tags:
        - Health
      security: []
  /logout:
    get:
      summary: Logout and destroy session
      tags:
        - Authentication
      responses:
        '200':
          $ref: '#/components/responses/Boolean'
      operationId: get-logout
      description: |-
        Invalidate the current session and clear the session cookie.
        Use this endpoint to sign out the current user.
  /licence:
    get:
      summary: EULA
      responses:
        '200':
          description: ''
          content:
            text/plain:
              schema:
                type: string
      operationId: get-eula
      security: []
      tags:
        - License
      description: |-
        Retrieves the End User License Agreement (EULA) text.
        Returns a plain text response containing the license terms. If no license text is available, a 204 No Content status is returned.
    parameters: []
  /licence/test:
    put:
      summary: Test license
      operationId: put-licence-test
      responses:
        '200':
          description: License is valid
          content:
            application/json:
              schema:
                type: object
                description: contains license information as JSON
        '400':
          description: Invalid license XML file
        '500':
          $ref: '#/components/responses/ErrorGeneral'
      requestBody:
        content:
          application/xml:
            schema:
              type: string
              description: License as XML
            examples:
              Sample license XML:
                value: |
                  <license>
                    VGVzdCBsaWNlbnNl
                  </license>
        description: Upload a license XML to validate it without installing.
      tags:
        - License
      description: |-
        Validates a license XML file without installing it.
        This endpoint parses the XML content, verifies the digital signature, and checks the expiration date.
        The response returns the parsed license information as a JSON object, allowing you to inspect the license details before installation.
  /licence/install:
    put:
      summary: Install license
      operationId: put-licence-install
      responses:
        '200':
          description: License installed
        '400':
          description: Invalid license XML file
        '500':
          $ref: '#/components/responses/ErrorGeneral'
      tags:
        - License
      description: |-
        Installs a new license on the server.
        This endpoint receives the license XML, validates its integrity and signature, and if valid, saves it as the active license.
        Any previous license is overwritten. The server functionality will reflect the new license terms immediately.
      requestBody:
        content:
          application/xml:
            schema:
              type: string
              description: License as XML
            examples:
              Install license example:
                value: |
                  <license>
                    VGVzdCBsaWNlbnNl
                  </license>
        description: Upload a license XML to install it on the server.
    parameters: []
  '/{type}/{asset-path}':
    parameters:
      - $ref: '#/components/parameters/type'
      - $ref: '#/components/parameters/asset-path'
    get:
      summary: Downloads an asset file
      responses:
        '200':
          description: Successful binary file download.
          content:
            application/force-download:
              schema:
                type: string
                format: binary
        '403':
          $ref: '#/components/responses/ErrorGeneral'
        '404':
          $ref: '#/components/responses/FileNotFound'
      operationId: get-image-file
      description: This endpoint allows downloading an asset in binary format by specifying its unique asset ID.
      parameters:
        - schema:
            type: boolean
          in: query
          name: info
          description: 'If true, return only metadata as JSON instead of the binary content'
      tags:
        - Assets
    delete:
      summary: Delete an asset
      operationId: delete-image-file-filepath
      responses:
        '200':
          $ref: '#/components/responses/Action'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
      description: This endpoint deletes an asset identified by its unique asset-path
      tags:
        - Assets
    post:
      summary: Perform operations on an asset
      operationId: post-image-file-filepath
      responses:
        '200':
          $ref: '#/components/responses/Action'
        '201':
          description: Created
        '403':
          $ref: '#/components/responses/ErrorGeneral'
        '404':
          $ref: '#/components/responses/Action'
        '415':
          $ref: '#/components/responses/Action'
        '503':
          $ref: '#/components/responses/ErrorGeneral'
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                cmd:
                  type: string
                  description: The type of operation to perform
                  enum:
                    - copy
                    - saveMetaData
                    - deleteMetaData
                    - restoreMetaData
                    - delete
                reimport:
                  type: boolean
                  deprecated: true
                to:
                  type: string
                  description: 'In the case of the `copy` type, the destination location'
                overwrite:
                  type: boolean
                  description: 'In the case of the `copy` type, an existing asset should be overwritten.'
                '':
                  type: string
                  x-stoplight:
                    id: e2k1vfztm69mm
              required:
                - cmd
            examples:
              Delete asset:
                value:
                  cmd: delete
              Copy to another path:
                value:
                  cmd: copy
                  to: /archive/2025/hero.jpg
                  overwrite: true
              Save metadata:
                value:
                  cmd: saveMetaData
        description: 'Form fields for asset commands like delete, copy, or metadata operations.'
      tags:
        - Assets
      description: 'This endpoint allows performing specific operations on an asset, such as updating metadata or copying the asset, by specifying the operation details in the request body.'
    put:
      summary: Upload an asset file
      operationId: put-image-file-imagepath
      responses:
        '200':
          $ref: '#/components/responses/Action'
        '201':
          $ref: '#/components/responses/Action'
        '401':
          $ref: '#/components/responses/ErrorGeneral'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
      requestBody:
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
        description: Asset to upload
      description: This endpoint allows uploading an asset file in binary format to the server.
      tags:
        - Assets
  /user/list:
    get:
      summary: Get Users
      tags:
        - Users
      responses:
        '200':
          $ref: '#/components/responses/Users'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
      operationId: get-user-list
      description: Get list of users. There is only a valid answer if the user has admin rights.
  /user/change:
    put:
      summary: Switch User
      operationId: put-user-change
      responses:
        '200':
          $ref: '#/components/responses/Action'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
      tags:
        - Users
      description: Switch from current user to another. There is only possible if the user has admin rights.
  /sessionrefresh:
    get:
      summary: Refresh Session
      tags:
        - Authentication
      responses:
        '200':
          $ref: '#/components/responses/SessionRefresh'
      operationId: get-sessionrefresh
      description: Allows refreshing the session to prevent expiry
  /password:
    get:
      summary: Get Password Change Salt
      tags:
        - Users
      responses:
        '200':
          $ref: '#/components/responses/Salt'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
      operationId: get-password-salt
      description: Get salt to change the password.
    put:
      summary: Change Password
      operationId: put-password
      responses:
        '200':
          $ref: '#/components/responses/Action'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
        '409':
          $ref: '#/components/responses/Action'
        '412':
          $ref: '#/components/responses/Action'
        '500':
          $ref: '#/components/responses/ErrorGeneral'
      tags:
        - Users
      description: Change the current password.
  '/directory/{asset-path}':
    get:
      summary: List directory
      tags:
        - Directory
      responses:
        '200':
          $ref: '#/components/responses/Directory'
        '401':
          $ref: '#/components/responses/ErrorGeneral'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
        '404':
          description: Not Found
        '500':
          $ref: '#/components/responses/ErrorGeneral'
      operationId: get-directory
      description: List contents of directory.
    parameters:
      - $ref: '#/components/parameters/asset-path'
    put:
      summary: Create Directory
      operationId: put-directory-assetpath
      responses:
        '200':
          $ref: '#/components/responses/Action'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
        '409':
          description: Conflict
        '500':
          $ref: '#/components/responses/ErrorGeneral'
      tags:
        - Directory
      description: Create a new directory
    delete:
      summary: Delete Directory
      operationId: delete-directory-assetpath
      responses:
        '200':
          $ref: '#/components/responses/Action'
      tags:
        - Directory
      description: Delete a directory
    post:
      summary: Command Directory
      operationId: post-directory-assetpath
      responses:
        '200':
          $ref: '#/components/responses/Action'
        '401':
          $ref: '#/components/responses/ErrorGeneral'
      tags:
        - Directory
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                cmd:
                  enum:
                    - reimport
                    - copy
                    - saveMetaData
                    - deleteMetaData
                    - restoreMetaData
                    - delete
                  type: string
                  description: The type of operation to perform
                reimport:
                  type: boolean
                  deprecated: true
                to:
                  type: string
                  description: 'In the case of the `copy` type, the destination location'
              required:
                - cmd
            examples:
              Reimport:
                value:
                  cmd: reimport
              Copy Directory:
                value:
                  cmd: copy
                  to: /archive/2025/
        description: |-
          Form payload specifying a directory command. Use `cmd` to select the action.
          The `reimport` boolean is deprecated; use `cmd: reimport` instead.
      description: Send command to directory
  '/icc/{asset-path}':
    parameters:
      - $ref: '#/components/parameters/asset-path'
    get:
      summary: Get ICC profile
      tags:
        - Assets
      responses:
        '200':
          description: ICC Profile from asset
          content:
            application/force-download:
              schema:
                type: string
                format: binary
                description: icc data
        '403':
          $ref: '#/components/responses/ErrorGeneral'
        '404':
          description: Image not found or ICC profile not exists
        '500':
          $ref: '#/components/responses/ErrorGeneral'
      operationId: get-icc-assetpath
      description: Get ICC Color profile from image asset
  /jobqueue:
    post:
      summary: Batch Job
      operationId: post-jobqueue
      responses:
        '200':
          $ref: '#/components/responses/JobCreate'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
        '404':
          description: Not Found
        '500':
          $ref: '#/components/responses/ErrorGeneral'
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                cmd:
                  type: string
                  enum:
                    - createAndStart
                    - cancel
                    - restart
                  description: the command to execute
                id:
                  type: string
                  description: Job ID
                name:
                  type: string
                  description: The name of the new archive. Applies to createAndStart only.
                file:
                  type: string
                  description: |-
                    Path and filename of the file to
                    add to the archive. Multiple
                    occurrences supported. Applies
                    to createAndStart only.
                renderingQuery:
                  type: string
                  description: |-
                    If present the rendering option
                    will be applied to all images
                    before archiving. Applies
                    to createAndStart only.
                scheduleDate:
                  type: integer
                  format: int64
                  description: |-
                    Unix timestamp when to
                    start processing. Applies
                    to createAndStart only.
                appendFileExtension:
                  type: boolean
                archiveType:
                  type: string
                  enum:
                    - tar.gz
                    - tar.bz2
                  description: Choose TAR archive with GZip or BZip2 compression
              required:
                - cmd
            examples:
              Create and start:
                value:
                  cmd: createAndStart
                  name: Website JPEGs
                  file: /images/hero.jpg
                  renderingQuery: format=jpg&quality=85
                  scheduleDate: 1732032000
                  appendFileExtension: true
                  archiveType: tar.gz
              Cancel job:
                value:
                  cmd: cancel
                  id: 7f3e1b5a-0b2e-4a2c-9c5c-123456789abc
        description: |-
          Form payload for creating or controlling a batch job. For `createAndStart`,
          include at least one `file` parameter, an optional `name`, `renderingQuery`,
          and optionally `scheduleDate` as a Unix timestamp (seconds) to delay start.
          Multiple files can be provided by repeating the `file` form field.
      tags:
        - Batch
      description: Endpoint for batch processing
  /totp:
    get:
      summary: Validate TOTP secret
      tags:
        - Authentication
      responses:
        '200':
          $ref: '#/components/responses/Boolean'
        '401':
          $ref: '#/components/responses/ErrorGeneral'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
      operationId: get-totp
      parameters:
        - schema:
            type: string
          in: query
          name: code
          description: '6‑digit TOTP code from your authenticator app (e.g., 123456)'
          example: '123456'
          required: true
      description: Validate TOTP code for the current user
    put:
      summary: Create 2FA TOTP
      operationId: put-totp
      responses:
        '200':
          $ref: '#/components/responses/TOTPCreation'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
        '415':
          $ref: '#/components/responses/ErrorGeneral'
      requestBody:
        $ref: '#/components/requestBodies/TOTPCreation'
      tags:
        - Users
      description: Create a new TOTP as second factor to the current user
    delete:
      summary: Remove 2FA TOTP
      operationId: delete-totp
      responses:
        '200':
          $ref: '#/components/responses/Boolean'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
      tags:
        - Users
      description: Remove TOTP secret from user
  '/prefs/{prefs-type}':
    get:
      summary: Get Web interface Preferences
      tags:
        - Prefs
      responses:
        '200':
          $ref: '#/components/responses/Prefs'
        '201':
          $ref: '#/components/responses/DownloadPresets'
        '401':
          $ref: '#/components/responses/ErrorGeneral'
      operationId: get-prefs
      description: Get Web interface user prefs
      parameters: []
    parameters:
      - schema:
          type: string
          enum:
            - publishing
            - interface
            - preview
            - archivepresets
            - batchpresets
        name: prefs-type
        in: path
        required: true
    post:
      summary: Set Web interface Preferences
      operationId: post-prefs-prefsname
      responses:
        '200':
          $ref: '#/components/responses/ErrorStatus'
        '403':
          $ref: '#/components/responses/ErrorGeneral'
      tags:
        - Prefs
      description: Save Web interface user prefs
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties: {}
        description: Depending of 'prefs-type' JSON content
security:
  - jSessionCookie: []
components:
  schemas:
    Problem:
      type: object
      description: Problem Details object used for error responses
      required:
        - type
        - title
      properties:
        err:
          type: string
          description: Optional legacy error message field used by some endpoints
  securitySchemes:
    jSessionCookie:
      type: apiKey
      in: cookie
      name: JSESSIONID
  requestBodies:
    Login:
      content:
        application/x-www-form-urlencoded:
          schema:
            type: object
            properties:
              username:
                type: string
                description: Username or email address of the account
              password:
                type: string
                description: sha256(salt + sha256(password))
            required:
              - username
              - password
          examples:
            sample login:
              value:
                username: me@example.com
                password: 06ff244aabdda1f6159b2e50c57655dfb973a3f641b0568b162bc39eddf93423
    TOTPCreation:
      content:
        application/json:
          schema:
            type: object
            properties:
              size:
                type: integer
                default: 400
                format: int32
                description: Size of the generated QR code image in pixels (width and height)
              onColor:
                type: string
                default: FF000000
                pattern: '^[A-Fa-f0-9]{8}$'
                description: 'Foreground ARGB color for the QR code (8 hex digits, AARRGGBB)'
              offColor:
                type: string
                default: FFFFFFFF
                pattern: '^[A-Fa-f0-9]{8}$'
                description: 'Background ARGB color for the QR code (8 hex digits, AARRGGBB)'
          examples:
            'Default colors, large QR':
              value:
                size: 512
                onColor: FF000000
                offColor: FFFFFFFF
  responses:
    Login:
      description: Response type login
      content:
        application/json:
          schema:
            description: ''
            type: object
            x-examples:
              example-1:
                username: fred@web-site.com
                state: failed
                messageCode: 5
                message: Unknown user or password wrong
                expiry: 0
                accesslevel: ''
                serverversion: FSI Server 0.00
            properties:
              username:
                type: string
                description: Account name of the authenticated user
              state:
                type: string
                description: Result of the login attempt (success or failed)
              messageCode:
                type: integer
                format: int32
                description: Numeric code describing the login result
              message:
                type: string
                description: Human-readable details about the login result
              expiry:
                type: integer
                format: int64
                description: Unix timestamp (seconds) when the session will expire
              accesslevel:
                type: string
                description: Access level or role assigned to the authenticated user
              serverversion:
                type: string
                description: Server software version
          examples:
            TOTP Code required:
              value:
                username: joe@example.com
                state: success
                messageCode: 2
                message: ''
                expiry: 1653317072
                accesslevel: ''
                serverversion: FSI Server 22.05.2465
            Success:
              value:
                username: joe@example.com
                state: success
                messageCode: 1
                message: ''
                expiry: 1653317151
                accesslevel: ''
                serverversion: FSI Server 22.05.2465
            Failed:
              value:
                username: joe
                state: failed
                messageCode: 5
                message: Unknown user or password wrong
                expiry: 0
                accesslevel: ''
                serverversion: FSI Server 22.05.2465
    Action:
      description: Response type action
      content:
        application/json:
          schema:
            type: object
            properties:
              statuscode:
                type: integer
                readOnly: true
                description: Operation status code (0 or positive values indicate the result)
              cause:
                type: string
                readOnly: true
                description: 'Short reason of failure, if any'
              details:
                type: string
                description: Additional information about the action result
          examples:
            Success:
              value:
                statuscode: 0
                cause: ''
                details: Asset deleted
            Failure:
              value:
                statuscode: 403
                cause: Forbidden
                details: You do not have permission to modify this resource
    Boolean:
      description: Response type boolean
      content:
        application/json:
          schema:
            type: object
            properties:
              value:
                type: boolean
                description: true if the requested operation succeeded; otherwise false
          examples:
            Example:
              value:
                value: true
    Directory:
      description: Response type directory
      content:
        application/json:
          schema:
            type: object
            properties:
              images:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                      description: File name of the image
                    lastModified:
                      type: integer
                      format: int64
                      description: Unix timestamp (milliseconds) of last modification
                    size:
                      type: integer
                      format: int64
                      description: File size in bytes
              subdirectory:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                      description: Name of the subdirectory
          examples:
            Sample directory listing:
              value:
                images:
                  - name: example.jpg
                    lastModified: 1653317000000
                    size: 245678
                subdirectory:
                  - name: thumbnails
    DownloadPresets:
      description: Response type downloadPresets
      content:
        application/json:
          schema:
            type: object
            properties:
              version:
                type: string
                description: Preset definition version
              preset:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                      description: Display name of the download preset
                    archiveType:
                      type: string
                      description: Archive format used when creating downloads
                    renderingQuery:
                      type: string
                      description: Rendering options applied before download
                    appendFileExtension:
                      type: boolean
                      description: Whether to append the file extension to archived files
          examples:
            Example presets:
              value:
                version: '1'
                preset:
                  - name: Original Files
                    archiveType: tar.gz
                    renderingQuery: ''
                    appendFileExtension: false
                  - name: Web JPEGs
                    archiveType: tar.bz2
                    renderingQuery: format=jpg&quality=85
                    appendFileExtension: true
    Health:
      description: Response type health
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                description: Current health status of the server (ok or failed)
          examples:
            healthy:
              value:
                status: ok
            unhealthy:
              value:
                status: failed
    JobCreate:
      description: Response type jobCreate
      content:
        application/json:
          schema:
            type: object
            properties:
              statuscode:
                type: integer
                format: int32
                description: Operation status code for the job request
              cause:
                type: string
                description: 'Reason for failure, if any'
              details:
                type: string
                description: Additional details about the job creation
              id:
                type: string
                description: Identifier of the created or referenced job
          examples:
            Created:
              value:
                statuscode: 0
                cause: ''
                details: Job created
                id: 7f3e1b5a-0b2e-4a2c-9c5c-123456789abc
    Prefs:
      description: Response type prefs
      content:
        application/json:
          schema:
            type: object
            properties:
              id:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                      description: Preference key
                    value:
                      type: string
                      description: Preference value
                description: Collection of preference entries
          examples:
            Interface prefs:
              value:
                id:
                  - name: theme
                    value: dark
                  - name: itemsPerPage
                    value: '50'
    Salt:
      description: |-
        Response type salt.
        The session ID is returned in a cookie named `JSESSIONID`. You need to include this cookie in subsequent requests.
      content:
        application/json:
          schema:
            type: object
            properties:
              state:
                type: string
                enum:
                  - error
                  - success
                description: Overall status of the salt request
              salt:
                type: string
                description: required for password hashing
              message:
                type: string
                description: contains error messages
              loginmethod:
                type: string
                enum:
                  - hash
                description: Server-supported login method
          examples:
            Salt Response:
              value:
                state: success
                salt: ec690b114e6e841102e88b8d019dda4130d662fb01a0febb1732ca6ff783dce5fcf3f1369ec9332278899c510a29a5e9a7708e0bb7dd7b7fe56ff9df723bf565
                message: ''
                loginmethod: hash
      headers:
        Set-Cookie:
          schema:
            type: string
    SessionRefresh:
      description: |-
        Response type sessionRefresh.
        The response is composed of values that include the number of seconds until the session expires.
      content:
        application/json:
          schema:
            type: object
            properties:
              expiry:
                type: integer
                format: int64
                description: Seconds until the current session expires
              servertime:
                type: integer
                format: int64
                description: Current server time as Unix timestamp (milliseconds)
              serverversion:
                type: string
                description: Server version string
              username:
                type: string
                description: Username associated with the session
              tfa:
                type: string
                description: 'Enabled two-factor authentication method, if any'
              serverRestartRequired:
                type: boolean
                description: Whether the server requires a restart
              setupRequired:
                type: boolean
                description: Whether further setup is needed
          examples:
            Valid Session:
              value:
                expiry: 900
                servertime: 1653317117405
                serverversion: FSI Server 22.05.2465
                username: support@neptunelabs.com
                tfa: TOTP
                serverRestartRequired: false
                setupRequired: false
      headers: {}
    TOTPCreation:
      description: Response type totpCreation
      content:
        application/json:
          schema:
            type: object
            properties:
              dataURL:
                type: string
                description: Data URL (PNG) for the QR code that encodes the TOTP secret
              secret:
                type: string
                description: The newly generated TOTP secret
              errorCause:
                type: string
                description: Reason if the TOTP creation failed
          examples:
            Example:
              value:
                dataURL: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...'
                secret: JBSWY3DPEHPK3PXP
                errorCause: ''
    Users:
      description: Response type users
      content:
        application/json:
          schema:
            type: array
            description: List of user names (login identifiers)
            minItems: 1
            uniqueItems: true
            x-examples:
              example-1:
                - wordpress
                - admin
                - websiteport
                - support@neptunelabs.com
            items:
              type: string
          examples:
            User List:
              value:
                - admin
                - joe@example.com
                - support@example.com
    ErrorGeneral:
      description: Error details
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples: {}
    ErrorStatus:
      description: Example response
      content:
        application/json:
          schema:
            type: object
            properties:
              statuscode:
                type: integer
                x-stoplight:
                  id: nd0oh6ixretwt
              cause:
                type: string
                x-stoplight:
                  id: skvh11pmwi8p3
          examples:
            Not Authorized:
              value:
                statuscode: 403
                cause: Not Authorized
    FileNotFound:
      description: Asset not found.
      content:
        application/json:
          schema:
            properties:
              id:
                type: string
      headers: {}
  examples: {}
  parameters:
    asset-path:
      name: asset-path
      in: path
      required: true
      schema:
        type: string
      description: 'URL‑encoded file path to the asset. If the path contains slashes or special characters, encode them (e.g., space → %20, slash → %2F)'
    type:
      name: type
      in: path
      required: true
      schema:
        type: string
        enum:
          - image
          - file
      description: 'For historical reasons, either a or b can be used here. However, this has no influence on the endpoint and does not change the result'
tags:
  - name: Assets
    description: 'Manage and retrieve assets (upload, download, delete)'
  - name: Authentication
    description: 'Session management and 2FA (login, logout, TOTP)'
  - name: Batch
    description: Batch processing and job queue operations
  - name: Directory
    description: 'Create, list, and manage directories in the asset store'
  - name: Health
    description: Check the server health and readiness
  - name: License
    description: 'Work with server licensing (view, test, install)'
  - name: Prefs
    description: Manage Web UI preferences for the current user
  - name: Users
    description: User-related operations
