Skip to content

REST and WebSocket API

The CONNECT panel uses a documented HTTP and WebSocket API on port 5100 for all its operations. Your own tools can use the same API to read and write signals, create interfaces and run discovery.

Every request follows the access rule: local callers pass, remote callers present X-API-Key.

ws://<host>:5100/ws wss:// behind a TLS reverse proxy

This is the live channel used by the browser HMI. It uses the rv WebSocket Realtime v2 protocol: JSON over WebSocket. realvirtual Core and the ctrlX bridge use the same protocol.

On connect the client receives a complete baseline before anything else:

  1. import_answer — all signal types and their current values, so the client can register every signal correctly without waiting.
  2. data — a full snapshot of current values.
  3. From then on: data messages carrying only what changed, on a fixed 10 ms tick.

The baseline is always sent before the client joins the broadcast, so a delta can never overtake it.

Gateway to client

TypePayload
import_answerSignal types and current values
dataSignal values — full snapshot on connect, deltas afterwards
config_answerThe configuration, in response to config_get
discover_answerDiscovery results for one interface

Client to gateway

TypeEffect
dataValues are written into the gateway — this is how a client commands the machine
import_requestRequests a fresh import_answer
config_getRequests the configuration
subscribeSignal subscription hint

A value message looks like this:

{
"type": "data",
"version": 2,
"signals": { "Conveyor1Running": true, "Actual_Temp": 234, "Motor1_Speed": 1.45 }
}
  • The gateway sends only the latest value per signal per tick. If a value changes and reverts within one tick, only its current value is sent, as appropriate for an HMI.
  • The gateway sends nothing while nothing changes — an idle connection costs nothing.
  • A heartbeat runs every 30 seconds; clients idle for 90 seconds are closed.
  • A configuration change resends a full snapshot, so no client is left with a stale set.

Authentication for a WebSocket upgrade uses ?apikey=<key>, because a browser cannot set headers on a handshake.

Method and pathPurpose
GET /healthLiveness, version, build and capability flags — answers without authentication
GET /health/detailSignal and client counts, license state
GET /signalsAll signals with types, count and version
GET /configThe complete configuration
PUT /configReplace the complete configuration
GET /config/interfacesList interfaces
POST /config/interfacesCreate an interface
PUT /config/interfaces/{id}Replace an interface — also used for tag-table re-import
DELETE /config/interfaces/{id}Remove an interface
POST /signals/validateValidate a protocol address without saving anything
POST /discover/{id}/startRun discovery on a live interface
POST /discover/{id}/bindRegister and persist selected discovered signals
GET /interface-typesAvailable interface types and what each one supports

Additional endpoints exist for the optional services: /history/* for recorded data, /cad/step-to-glb and /cad/jt-to-glb for CAD conversion, /diagnose and /comments for AI diagnosis, and /update/* for updates.

Configuration writes are saved atomically and applied by hot-reload. Affected interfaces restart; the gateway does not.

Terminal window
# Is the gateway up?
curl http://localhost:5100/health
# All current signals
curl -H "X-API-Key: $KEY" http://localhost:5100/signals
# Validate an address before creating a signal
curl -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"interfaceType":"S7","protocolAddress":"DB1.DBX0.0","dataType":"Bool"}' \
http://localhost:5100/signals/validate
Wire typeDirection
PLCInputBool, PLCInputInt, PLCInputFloatWritten by realvirtual, read by the PLC
PLCOutputBool, PLCOutputInt, PLCOutputFloatWritten by the PLC, read by realvirtual

See configuring interfaces for what that means in practice.