Skip to content

Latest commit

 

History

History
1260 lines (920 loc) · 35.2 KB

api-endpoints.md

File metadata and controls

1260 lines (920 loc) · 35.2 KB

API Endpoints Reference

Complete technical reference for all REST API endpoints used by the PepperDash Essentials Web Config App.

All API endpoints are accessed through the base path /cws/:appId/api where :appId is the program slot identifier (e.g. app01 through app10).

Base Configuration

Base URL: https://[processor-ip]/cws/:appId/api Protocol: HTTPS only Authentication: Credential-based via POST /loginCredentials (see below) Content-Type: application/json for POST requests Response Format: JSON

Authentication Endpoints

Set Login Credentials

Purpose: Authenticate with the processor. The backend uses a single shared authentication mechanism for all program slots.

POST /loginCredentials

Request Body:

{
  "username": "admin",
  "password": "yourpassword"
}

Response: 200 OK (empty body) on success

Notes:

  • A successful response with any appId authenticates the session for all running slots
  • The app probes all 10 slots in parallel after initial auth to discover which are running
  • A 4xx or network error indicates invalid credentials or that the slot is not running

System Information Endpoints

Get Versions

Purpose: Retrieve all loaded assemblies and their versions

GET /versions

Response:

[
  {
    "Name": "PepperDash-Essentials",
    "Version": "1.8.0.0"
  },
  {
    "Name": "System.Core",
    "Version": "4.2.1.0"
  }
]

Response Fields:

  • Name (string): Full assembly name
  • Version (string): Version number in dotted format

Usage: Displayed on Versions page for system documentation and troubleshooting

Error Conditions:

  • 500: Server error if version information cannot be retrieved

Get API Paths

Purpose: Retrieve all available REST API routes registered on the processor

GET /apiPaths

Response:

{
  "url": "https://192.168.1.100/cws/app01",
  "routes": [
    {
      "Name": "getDevices",
      "Url": "app01/api/devices",
      "DataTokens": { "Name": "getDevices" },
      "RouteHandler": null
    }
  ]
}

Response Fields:

  • url (string): Base URL of the processor web server for this app slot
  • routes (array): List of route objects
    • Name (string): Route name
    • Url (string): Route URL relative to the base
    • DataTokens.Name (string): Data token name when present

Usage: Displayed on the API Paths page; routes are sorted alphabetically and shown with clickable URLs

Error Conditions:

  • 500: Server error if route information cannot be retrieved

Get Plugin Load Issues

Purpose: Retrieve the plugin files that recorded problems while Essentials loaded them: plugins built against a newer Essentials or a newer Crestron SDK, plugins that failed to load, missing dependencies, and factories skipped by a minimum version check

Requires: Essentials 3.0 or later. The Plugin Issues link appears only when the processor lists this route in apiPaths.

GET /pluginLoadIssues
GET /pluginLoadIssues?all=true

By default only plugin files with at least one issue are returned. ?all=true includes plugins that loaded cleanly.

Response:

{
  "EssentialsVersion": "3.0.0-rc.11",
  "IssueCount": 2,
  "ErrorCount": 0,
  "Plugins": [
    {
      "FileName": "KpmgRoom.dll",
      "AssemblyName": "KpmgRoom",
      "Version": "1.0.0",
      "BuiltAgainst": { "PepperDashEssentials": "3.0.0-rc.16" },
      "Status": "Loaded",
      "Issues": [
        {
          "Severity": "Warning",
          "Category": "BuiltAgainstNewerEssentials",
          "Message": "Built against PepperDashEssentials 3.0.0-rc.16, but Essentials 3.0.0-rc.11 is running.",
          "Detail": "Plugins built against a newer Essentials can call APIs, or depend on Crestron SDK versions, that this Essentials does not have...",
          "TriggeredBy": "Direct load",
          "TimestampUtc": "2026-10-20T14:02:11Z"
        },
        {
          "Severity": "Warning",
          "Category": "NewerDependencyReference",
          "Message": "References Crestron.SimplSharpPro.UI 2.21.274.0, but 2.21.128.0 is loaded.",
          "Detail": "...",
          "TriggeredBy": "Direct load",
          "TimestampUtc": "2026-10-20T14:02:11Z"
        }
      ]
    }
  ]
}

Response Fields:

  • EssentialsVersion (string): The running Essentials version
  • IssueCount (number), ErrorCount (number): Totals across the returned plugins
  • Plugins (array): One entry per plugin file, plugins with errors first
    • FileName (string): The plugin file, e.g. MyPlugin.dll
    • AssemblyName, Version (string or null): Read from the plugin's metadata when possible
    • BuiltAgainst (object): Essentials package versions the plugin was built against, by package ID. Empty for plugins built before Essentials recorded this
    • Status (string): Loaded (plugin factories registered), LoadedAsLibrary (loaded, no factories), Skipped (not used: no factories registered, or a duplicate of an assembly the program already provides), or Failed (not loaded)
    • Issues (array):
      • Severity (string): Warning (the plugin still loaded) or Error
      • Category (string): BuiltAgainstNewerEssentials, NewerDependencyReference, IncompatibleApi, MinimumVersionNotMet, MissingDependency, LoadFailure, TypeLoadFailure, FactoryFailure, PackageExtractFailure, DuplicateAssembly or DevelopmentBuildNotListed
      • Message (string): One-line description
      • Detail (string or null): Exception or remediation detail
      • TriggeredBy (string): The plugin that caused this load, or Direct load
      • TimestampUtc (string): When the issue was recorded

Usage: Displayed on the Plugin Issues page. The nav link shows the issue count, red when any issue is an error. The same information is available at the processor console with pluginissues or pluginissues verbose.

Error Conditions:

  • 404: Essentials earlier than 3.0 does not have this route
  • 500: Server error if the report cannot be built

Get Device Types

Purpose: Retrieve all available device types supported by current plugins

GET /types

Response:

[
  {
    "Type": "samsungMDC",
    "Description": "Samsung displays using MDC protocol",
    "CType": "PepperDash.Essentials.Devices.Displays.SamsungMDCDisplay"
  },
  {
    "Type": "basicTriList",
    "Description": "Basic TriList device for control systems",
    "CType": "PepperDash.Essentials.Core.Devices.BasicTriList"
  }
]

Response Fields:

  • Type (string): Configuration identifier used in device configuration
  • Description (string): Human-readable description of device purpose
  • CType (string): Full .NET class name that implements the device

Usage: Displayed on Types page for configuration reference and development

Error Conditions:

  • 500: Server error if type information cannot be retrieved

Device Management Endpoints

Get Devices

Purpose: Retrieve all configured devices in the system

GET /devices

Response:

[
  {
    "Key": "Display-Room1",
    "Name": "Conference Room Display"
  },
  {
    "Key": "Codec-Main",
    "Name": "Main Video Codec"
  }
]

Response Fields:

  • Key (string): Unique device identifier used in configuration and debug messages
  • Name (string): Human-readable device name for user interfaces

Usage: Device list display and debug message filtering

Error Conditions:

  • 500: Server error if device information cannot be retrieved

Get Device Properties

Purpose: Retrieve current properties and values for a specific device

GET /deviceProperties/{deviceKey}

Path Parameters:

  • deviceKey (string): The unique Key of the device

Response:

[
  {
    "Name": "PowerIsOn",
    "Type": "Boolean",
    "Value": "true",
    "CanRead": true,
    "CanWrite": true
  },
  {
    "Name": "CurrentInput",
    "Type": "String",
    "Value": "HDMI1",
    "CanRead": true,
    "CanWrite": false
  }
]

Response Fields:

  • Name (string): Property name
  • Type (string): Data type of the property value
  • Value (string): Current property value (always string representation)
  • CanRead (boolean): Whether property value can be read
  • CanWrite (boolean): Whether property value can be modified

Usage: Device detail inspection and monitoring

Error Conditions:

  • 404: Device with specified key not found
  • 500: Server error retrieving device properties

Get Device Methods

Purpose: Retrieve available methods (commands) for a specific device

GET /deviceMethods/{deviceKey}

Path Parameters:

  • deviceKey (string): The unique Key of the device

Response:

[
  {
    "Name": "PowerOn",
    "Params": []
  },
  {
    "Name": "SetInput",
    "Params": [
      {
        "Name": "input",
        "Type": "String"
      }
    ]
  }
]

Response Fields:

  • Name (string): Method name
  • Params (array): Array of parameter definitions
    • Name (string): Parameter name
    • Type (string): Parameter data type

Usage: Device control interface and method execution

Error Conditions:

  • 404: Device with specified key not found
  • 500: Server error retrieving device methods

Configuration Endpoints

Get Configuration

Purpose: Retrieve the complete merged system configuration

GET /config

Response: Complete JSON configuration object (structure varies by system)

Example Response Structure:

{
  "devices": {
    "Display-Room1": {
      "key": "Display-Room1",
      "name": "Conference Room Display",
      "type": "samsungMDC",
      "properties": {
        "control": {
          "tcpSshProperties": {
            "address": "192.168.1.100",
            "port": 1515
          }
        }
      }
    }
  },
  "rooms": {
    "ConferenceRoom": {
      "name": "Conference Room",
      "devices": ["Display-Room1"]
    }
  }
}

Usage: Configuration analysis, backup, and documentation

Response Size: Can be very large (10KB - 1MB+) depending on system complexity

Error Conditions:

  • 500: Server error if configuration cannot be retrieved or merged

Debug and Monitoring Endpoints

Start Debug Session

Purpose: Initiate a WebSocket debug session for real-time message monitoring

GET /debugSession

Response:

{
  "url": "wss://192.168.1.100/cws/app01/api/debug-websocket"
}

Response Fields:

  • url (string): WebSocket URL for establishing debug connection

Usage: Real-time debug message monitoring in Debug Console

WebSocket Protocol:

  • Connection: Use returned URL to establish WebSocket connection
  • Messages: Server sends JSON-formatted log messages
  • Client: Client receives messages, no need to send data to server

WebSocket Message Format:

{
  "Timestamp": "2024-01-15T10:30:45.123Z",
  "MessageTemplate": "Device {Key} power state changed to {State}",
  "RenderedMessage": "Device Display-Room1 power state changed to On",
  "Level": "Information",
  "Properties": {
    "Key": "Display-Room1",
    "State": "On"
  }
}

Error Conditions:

  • 500: Server error if debug session cannot be started
  • WebSocket connection errors handled by client WebSocket implementation

Poll Debug Messages

Purpose: Read the debug log over HTTP instead of the WebSocket. Dev Tools uses this on Virtual Control (VC-4), where the WebSocket ports are firewalled

GET /debugSession/messages
GET /debugSession/messages?since=42&wait=5000

Query Parameters:

  • since (number, optional): The next value from the previous response. Leave it out to start a session and get the starting cursor
  • wait (number, optional): Milliseconds to hold the request when nothing is new, up to 10000. Default 0

Response:

{
  "next": 44,
  "missed": false,
  "messages": ["{\"Timestamp\":\"...\",\"Level\":\"Information\",...}", "..."]
}

Response Fields:

  • next (number): Pass as since on the next request
  • missed (boolean): Some messages after since were dropped before they were fetched: the buffer overflowed, the session went idle for over a minute, it was stopped, or the program restarted
  • messages (string[]): Each one is the same JSON text the WebSocket sends, in the WebSocket message format above

Usage: The server returns as soon as a message arrives, so polling again right after each response gives near-live updates. Messages are only collected while a client has polled in the last minute. POST /debugSession ends the session


Stop Debug Session

Purpose: Stop an active debug session and close WebSocket connections

POST /debugSession

Request Body: None required

Response: Empty (204 No Content on success)

Usage: Clean termination of debug sessions

Error Conditions:

  • 500: Server error stopping debug session

System Control Endpoints

Get Minimum Log Level

Purpose: Retrieve the current minimum log level for debug output

GET /appdebug

Response:

{
  "minimumLevel": "Information"
}

Response Fields:

  • minimumLevel (string): Current minimum log level setting

Valid Log Levels (in order of severity):

  • Verbose: Most detailed logging
  • Debug: Detailed technical information
  • Information: General informational messages
  • Warning: Warning conditions
  • Error: Error conditions
  • Fatal: Fatal error conditions

Usage: Display current log level setting and provide options for changes

Error Conditions:

  • 500: Server error retrieving log level setting

Set Minimum Log Level

Purpose: Change the minimum log level for debug output

POST /appdebug

Request Body:

{
  "minimumLevel": "Warning"
}

Request Fields:

  • minimumLevel (string): New minimum log level (must be valid level)

Response: Empty (204 No Content on success)

Usage: Adjust debug verbosity from Debug Console interface

Error Conditions:

  • 400: Invalid log level specified
  • 500: Server error setting log level

Get Configuration Loading Setting

Purpose: Check if configuration loading on boot is disabled

GET /doNotLoadConfigOnNextBoot

Response:

{
  "doNotLoadConfigOnNextBoot": false
}

Response Fields:

  • doNotLoadConfigOnNextBoot (boolean): Whether config loading is disabled

Usage: Display current setting and allow user control

Error Conditions:

  • 500: Server error retrieving setting

Set Configuration Loading Setting

Purpose: Enable or disable configuration loading on next boot

POST /doNotLoadConfigOnNextBoot

Request Body:

{
  "doNotLoadConfigOnNextBoot": true
}

Request Fields:

  • doNotLoadConfigOnNextBoot (boolean): New setting value

Response: Empty (204 No Content on success)

Usage: Control configuration loading behavior for troubleshooting

Error Conditions:

  • 400: Invalid boolean value specified
  • 500: Server error setting configuration

Restart Program

Purpose: Restart the entire PepperDash Essentials framework

POST /restartProgram

Request Body: None required

Response: Empty (may not receive response due to restart)

Usage: Complete system restart from web interface

Behavior:

  • System begins restart immediately
  • All connections will be closed
  • Response may not be received due to restart timing
  • System will be unavailable for 2-5 minutes during restart

Error Conditions:

  • 500: Server error initiating restart (system may still restart)

Load Configuration

Purpose: Manually reload system configuration without full restart

POST /loadConfig

Request Body: None required

Response: Empty (204 No Content on success)

Usage: Apply configuration changes without full system restart

Prerequisites: Usually used when "doNotLoadConfigOnNextBoot" is true

Error Conditions:

  • 400: Configuration cannot be loaded (syntax errors, etc.)
  • 500: Server error during configuration loading

Routing Endpoints

Requires PepperDashEssentials.dll 3.0 or later.

Get Routing Devices and Tie Lines

Purpose: Retrieve the complete routing graph — devices, ports, tie lines, and current route state

GET /routingDevicesAndTieLines

Response:

{
  "devices": [
    {
      "key": "display-1",
      "name": "Main Display",
      "hasInputs": true,
      "hasOutputs": false,
      "hasInputsAndOutputs": false,
      "inputPorts": [
        {
          "key": "hdmiIn1",
          "signalType": "AudioVideo",
          "connectionType": "Hdmi",
          "isInternal": false
        }
      ]
    }
  ],
  "tieLines": [
    {
      "sourceDeviceKey": "laptop-1",
      "sourcePortKey": "out1",
      "destinationDeviceKey": "display-1",
      "destinationPortKey": "hdmiIn1",
      "signalType": "AudioVideo",
      "isInternal": false
    }
  ],
  "currentRoutes": [],
  "sinkCurrentSources": [],
  "multiviewLayouts": {}
}

Device role flags: hasInputsAndOutputs is the literal "is a midpoint" flag. Note that a multiview decoder reports hasInputs and hasOutputs while not being a midpoint, so "sink = has inputs and no outputs" is not a safe test — see UI Components Reference.

Multiview tiles: A multiview decoder's tile child devices are not returned as top-level devices. Each tile is synthesized as an input port on the parent, keyed tile{N}:{portKey}, and any tie line or route targeting a tile is remapped onto the parent.


Start Routing Feedback Session

Purpose: Start the routing feedback WebSocket server and obtain its URL

GET /routingFeedbackSession

Response:

{
  "url": "wss://192.168.1.164:65401/routing/join/",
  "fallbackUrl": "wss://10.0.0.5:65401/routing/join/"
}

Usage: Connect to url to receive live route changes. Messages are a discriminated union on type: snapshot, midpointRouteChanged, sinkInputChanged, and layoutChanged. A sinkInputChanged with an empty sourceDeviceKey means the route feeding that input was cleared.


Poll Routing Feedback

Purpose: Read routing feedback over HTTP instead of the WebSocket. Dev Tools uses this on Virtual Control (VC-4), where the WebSocket ports are firewalled

GET /routingFeedbackSession/messages
GET /routingFeedbackSession/messages?since=12&wait=5000

Usage: Works like Poll Debug Messages. The first request, without since, returns the snapshot message as its only message. Later responses carry the same midpointRouteChanged, sinkInputChanged and layoutChanged messages the WebSocket sends. When a response has missed: true, start again without since for a fresh snapshot. POST /routingFeedbackSession ends the session


Execute Routing Command

Purpose: Make or clear a route, addressed entirely by device and port keys

POST /routingCommand

Ports are addressed by key, never by selector: a routing port's selector is a driver-defined object that cannot be expressed in JSON, so the processor resolves key → port → selector itself.

Request Body — one of four commands:

{ "command": "sinkRoute", "deviceKey": "display-1", "inputPortKey": "hdmiIn1",
  "sourceDeviceKey": "laptop-1", "signalType": "AudioVideo" }

{ "command": "midpointSwitch", "deviceKey": "dm-chassis-1",
  "inputPortKey": "inputCard3", "outputPortKey": "outputCard5", "signalType": "Video" }

{ "command": "clearSink", "deviceKey": "display-1", "inputPortKey": "hdmiIn1",
  "clearSinkInput": true }

{ "command": "clearMidpointOutput", "deviceKey": "dm-chassis-1",
  "outputPortKey": "outputCard5", "signalType": "AudioVideo" }

Request Fields:

  • command (string): sinkRoute, midpointSwitch, clearSink or clearMidpointOutput. Case-insensitive
  • deviceKey (string): Target device. For sink commands this is the destination — or the multiview parent when addressing a tile
  • inputPortKey (string, optional): May be multiview-qualified (tile2:tileInput); the processor de-qualifies it to the child tile sink. Optional for clearSink, where omitting it clears whatever route the sink has
  • outputPortKey (string): Required for the midpoint commands
  • sourceDeviceKey (string): Required for sinkRoute
  • sourcePortKey (string, optional): Omit to let the processor's path discovery choose
  • signalType (string): Audio, Video, AudioVideo or Usb. Defaults to AudioVideo. Numeric values are rejected
  • releaseOnly (bool): clearSink only — stop usage tracking but leave the signal flowing
  • clearSinkInput (bool): clearSink only — also deselect the destination's own input. Off by default, because clearing a route otherwise never touches the destination
  • dryRun (bool): Validate and compute the path, execute nothing

Response:

{
  "status": "accepted",
  "command": "sinkRoute",
  "deviceKey": "nvx-decoder-1",
  "resolvedDeviceKey": "nvx-decoder-1-tile2",
  "resolvedInputPortKey": "tileInput",
  "signalType": "AudioVideo",
  "effectiveSignalType": "AudioVideo",
  "partial": false,
  "steps": [
    {
      "signalType": "Video",
      "switchingDeviceKey": "dm-chassis-1",
      "inputPortKey": "inputCard3",
      "outputPortKey": "outputCard5"
    }
  ]
}

Response Fields:

  • status: executed (done before the response was written), accepted (validated and queued), validated (dry run), or error
  • resolvedDeviceKey / resolvedInputPortKey: The real device and port the command ran against. These differ from the requested values only when a tile{N}: port was de-qualified
  • effectiveSignalType: What was actually handed to the devices. May be wider than signalType — a pre-mapped route descriptor takes its type from the port's declared type, so an Audio-only request across all-AudioVideo ports executes as AudioVideo rather than breaking away
  • steps: The switch steps that will run, in order. sinkRoute only; an AudioVideo route is discovered as two independent paths, so each step names its own signal type
  • partial: An AudioVideo request that found a path for only one half. The half that was found is still routed

Status Codes:

Status Meaning
200 midpointSwitch / clearMidpointOutput executed inline, or a dry run validated
202 sinkRoute / clearSink validated and queued. Confirmation arrives over the feedback WebSocket, not here
400 Malformed request: invalidJson, missingField, unknownCommand, invalidSignalType
404 deviceNotFound — the key is wrong
409 noRouteFound — the keys are valid but no wiring path exists
422 deviceNotRoutable, tileNotFound, portNotFound, signalTypeNotSupportedByPort — the keys exist but the request is impossible on that device
500 executionError — the device threw while switching

Error Response Body:

{
  "status": "error",
  "error": {
    "code": "noRouteFound",
    "message": "No Video path exists from 'laptop-1' to 'display-1' input 'hdmiIn1'.",
    "field": "signalType"
  }
}

Why sink commands return 202: making a route enqueues onto the processor's single-worker routing queue, and completion is conditional — a destination that is warming or cooling parks its request until the cooldown finishes. The 202 is still meaningful because all validation, including full path discovery, happens synchronously first: a request that provably cannot work returns 409 before anything is queued.

Capability detection: this endpoint does not exist on older processors. Probe Get API Paths for a routingCommand route rather than gating on a version number.


Secrets Endpoints

Credential storage. No endpoint here ever returns a stored secret value — the processor is write-only for values by design.

Mutations are POST rather than DELETE: the Crestron web server advertises only POST, GET, OPTIONS, so a DELETE would fail CORS preflight.

Get Secret Providers

GET /secrets/providers
{
  "providers": [
    {
      "key": "default",
      "description": "Default secret provider serving Essentials Application 1",
      "scope": "local",
      "enumerationSupported": true,
      "maxKeyLength": 32,
      "maxValueLength": 1600
    },
    {
      "key": "CrestronGlobalSecrets",
      "description": "Default secret provider serving all local applications",
      "scope": "global",
      "enumerationSupported": true,
      "maxKeyLength": 32,
      "maxValueLength": 1600
    }
  ]
}

scope is local (this program slot) or global (shared across slots). The limits are Crestron Data Store caps, not application choices.


List Secrets

GET /secrets?provider=default

Optional: includeReserved=true to show the API's own bookkeeping records, includeSizes=true to include each value's character count.

{
  "provider": "default",
  "scope": "local",
  "indexStatus": "ok",
  "enumerationComplete": true,
  "counts": { "total": 3, "managed": 1, "unmanaged": 2, "stale": 0 },
  "secrets": [
    {
      "key": "displayPassword",
      "managed": true,
      "description": "Display admin",
      "createdUtc": "2026-09-10T14:00:00Z",
      "updatedUtc": "2026-09-16T18:22:05Z",
      "lastModifiedUtc": "2026-09-16T18:22:05Z",
      "owner": "app01",
      "type": "String"
    }
  ],
  "staleIndexEntries": [],
  "warnings": []
}

Response Fields:

  • managed — whether the key was written through this API. Unmanaged records exist in the same flat Data Store but were created elsewhere; Mobile Control's paired-client tokens are one
  • indexStatus — ok, missing, or corrupt:<reason>. Anything but ok means classification is unavailable and every key reports as unmanaged. The secrets themselves are unaffected
  • enumerationComplete — false means the Data Store walk was cut short and the list is partial. Index pruning is refused in that state
  • staleIndexEntries — keys the index lists that no longer exist in the store

Status: 200 · 400 missingField · 404 providerNotFound · 500


Execute Secrets Command

POST /secrets/command
{
  "action": "set",
  "provider": "default",
  "key": "displayPassword",
  "value": "…",
  "description": "Display admin",
  "overwrite": false
}
Action Semantics
set Creates. Existing key + overwrite:false → 409 alreadyExists
update Must already exist, else 404 notFound
delete Removes the secret and its index entry
test Existence probe → {"exists": true}. Never a value
pruneIndex Drops index entries with no matching record. 409 if the walk was incomplete
rebuildIndex Repairs a damaged index. adoptKeys marks existing keys as managed without reading or changing their values
{
  "status": "ok",
  "action": "set",
  "provider": "default",
  "key": "displayPassword",
  "existedBefore": false,
  "indexUpdated": true
}

indexUpdated: false with a warning means the secret was written but its metadata was not. That is reported as success, because the secret is authoritative and the index is advisory — returning an error would invite retrying a write that already happened.

Validation (all before any store access):

Rule Code Status
Key empty or whitespace emptyKey 400
Key over 32 characters, or containing control characters keyTooLong / invalidKey 400
Key starts with __essSecretsIdx reservedKey 400
Value empty (empty means delete in the store) emptyValue 400
Value over 1600 characters valueTooLong 400

The empty-key rule is not cosmetic: an empty key reaches a Data Store call that deletes every record belonging to the application.

Status: 200 · 400 · 403 accessDenied · 404 notFound · 409 alreadyExists / enumerationIncomplete · 507 storeFull · 503 storeUnavailable · 500


Apply Secrets In Bulk

POST /secrets/bulk
{
  "mode": "preview",
  "provider": "default",
  "overwrite": false,
  "secrets": { "displayPassword": "…", "codecPassword": "…" }
}

secrets accepts either the flat map above — which is what the template endpoint emits — or an array of {key, value, provider?, description?}.

{
  "mode": "preview",
  "provider": "default",
  "overwrite": false,
  "summary": {
    "total": 3,
    "create": 1,
    "overwrite": 1,
    "skip": 1,
    "invalid": 0,
    "failed": 0
  },
  "entries": [
    {
      "index": 0,
      "key": "displayPassword",
      "provider": "default",
      "action": "create",
      "applied": false
    }
  ],
  "indexUpdated": false
}

Rules worth knowing:

  • Preview writes nothing. applied is always false, and the response is 200 even when entries are invalid — a successful preview of a bad file is not a failed request
  • A commit with any invalid entry returns 422 and writes nothing
  • overwrite defaults to false
  • An entry targeting an existing unmanaged key is skipped as unmanagedTarget unless allowUnmanagedOverwrite is set. This is what stops a round-tripped template destroying another subsystem's records
  • Bulk never deletes. A key absent from the file is left alone
  • Duplicate keys within one batch are invalid, not last-write-wins
  • Over 200 entries → 400 batchTooLarge

Get Secrets Template

GET /secrets/template?provider=default
{
  "provider": "default",
  "generatedUtc": "2026-09-16T18:30:00Z",
  "note": "Values are intentionally blank. Fill them in, then apply this file.",
  "secrets": { "displayPassword": "", "codecPassword": "" },
  "metadata": [
    {
      "key": "displayPassword",
      "provider": "default",
      "description": "Display admin",
      "managed": true
    }
  ]
}

secrets is byte-for-byte what the bulk endpoint accepts, so the file round-trips: download, fill in, apply elsewhere. includeUnmanaged defaults to false, so other subsystems' records are not offered as blanks to fill in.

Capability detection: these endpoints do not exist on older processors. Probe Get API Paths for a secrets route rather than gating on a version number.


Error Response Format

All endpoints return errors in consistent format:

HTTP Status Codes:

  • 400: Bad Request - Invalid parameters or request format
  • 404: Not Found - Requested resource does not exist
  • 500: Internal Server Error - Server-side processing error

Error Response Body:

{
  "error": "Description of the error condition",
  "details": "Additional technical details (optional)"
}

Rate Limiting and Performance

Rate Limits: No explicit rate limiting implemented

Performance Considerations:

  • /config endpoint may take several seconds for large configurations
  • /debugSession WebSocket can generate high message volumes
  • Multiple simultaneous debug sessions impact processor performance

Best Practices:

  • Cache version and type information (changes infrequently)
  • Close debug sessions when not actively monitoring
  • Use appropriate minimum log levels to reduce debug message volume

Security Considerations

Authentication: Uses processor's built-in web authentication (if configured)

Authorization: No granular permissions - full access if authenticated

HTTPS: All communication must use HTTPS (HTTP not supported)

CORS: Configured to allow requests from the web application origin

Sensitive Data:

  • Configuration may contain IP addresses, usernames, and network topology
  • Debug messages may contain sensitive operational information
  • No automatic filtering of sensitive information in responses

WebSocket Debug Protocol

Connection Establishment

  1. Call GET /debugSession to get WebSocket URL
  2. Establish WebSocket connection using returned URL
  3. Connection remains open until explicitly closed or system restart

Message Flow

  • Server to Client: Continuous stream of debug messages in JSON format
  • Client to Server: No messages required (read-only protocol)

Connection Management

  • Keep-alive: WebSocket handles connection keep-alive automatically
  • Reconnection: Client must handle reconnection logic if connection drops
  • Cleanup: Call POST /debugSession to cleanly stop session

Message Volume Management

  • High Volume: Systems may generate >100 messages per second
  • Filtering: Use minimum log level to reduce message volume
  • Browser Limits: Very high message rates may impact browser performance

Integration Examples

Basic Configuration Retrieval

fetch('https://192.168.1.100/cws/app01/api/config')
  .then((response) => response.json())
  .then((config) => {
    console.log('System configuration:', config);
  });

Starting Debug Session

// Get WebSocket URL
fetch('https://192.168.1.100/cws/app01/api/debugSession')
  .then((response) => response.json())
  .then((data) => {
    // Connect to WebSocket
    const ws = new WebSocket(data.url);

    ws.onmessage = (event) => {
      const message = JSON.parse(event.data);
      console.log('Debug message:', message);
    };

    ws.onclose = () => {
      console.log('Debug session closed');
    };
  });

Setting Log Level

fetch('https://192.168.1.100/cws/app01/api/appdebug', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    minimumLevel: 'Warning',
  }),
});

This reference provides complete technical details for all API interactions. For practical usage examples, see the How-to Guides and Tutorials.