Skip to content
The text was updated for 2.10; the screenshots are from version 2.5.0 and may differ from the interface.

REST Server ​

About 11 min read

The REST Server protocol lets IoT devices, cloud services and other software send tag values themselves (push) to 2WinScada with an HTTP POST request. Unlike the REST Client protocol, 2WinScada does not poll the external system; the external system delivers the data to the 2WinScada ingest endpoint at whatever interval it chooses.

Each REST Server device represents a separate data source. With every request, the external system sends the device identifier and the device key generated for that device in HTTP headers; if the identity is verified, the values in the body are written to the device's tags.

License ​

REST Server is available in the Standard and Professional license editions; it is not available in the Starter edition. If the license does not include REST integration, the ingest endpoint rejects requests with error code 4900. For details, see the License page.

Channel Definition ​

On the General tab of the new channel window, enter the Name and select RestServer as the Connection Type.

Channel definition, General tab

A REST Server channel has only the General tab; the channel has no connection parameters. The channel does not connect to the external system; it accepts the requests that arrive at the data ingest endpoint. Authentication and body settings are made on the Parameters tab of each device.

Device Definition ​

On the General tab, the Name and Active fields are filled in as for other protocols. The device must be Active for data to be accepted.

The Parameters tab contains the REST Server Ingest group:

  • REST Server Ingest Enabled: Turns on data ingest for the device (default: selected). If not selected, requests to this device are rejected with error code 4603.

Below the group are the Identity and Key, Payload Parsing and No-Data Watchdog tabs.

Identity and Key ​

Identity and Key tab

FieldDescription
External Device IdIdentifier that the external system sends in the X-Device-Id header to identify this device (e.g. kazan-dairesi-01). Matched case-insensitively. It is recommended to enter a hard-to-guess External Device Id for each device. If left empty, the device's numeric ID in the system must be written in the X-Device-Id header.
Device KeySecret key that the external system sends in the X-Device-Key header. The field is shown masked; as stated in the help text below it, use the copy button to share the key. If the key is empty, no request to this device is accepted.
Generate KeyGets a new random key from the server and writes it to the Device Key field. On a saved device, if the External Device Id is empty, the device's numeric ID is also written to that field.
Copy KeyCopies the key to the clipboard without displaying it.

Creating and renewing a key:

  1. Click Generate Key. The generated key starts with dev_.
  2. Copy the key with Copy Key and transfer it securely to the configuration of the external system.
  3. Save the device form with Save. The new key becomes valid after saving; from that moment on, requests with the previous key are rejected with error code 4600.

WARNING

Do not share the device key over open channels such as e-mail, screenshots or query parameters; the key allows the system sending the request to write data to that device. Access the ingest endpoint over HTTPS so that the key is not carried as plain text on the network. When a device is copied, the External Device Id and Device Key are copied too; generate a new key on the copy and change the identifier.

Payload Parsing ​

This tab defines how free-form JSON in the body is converted to tag values. Examples of the body formats are in the Sending Data section.

FieldDescriptionDefault
List JSON PathDot-separated path of the field in the body that contains the tag list or tag object (e.g. data.items). The first part of the path must be a field at the root level of the body; the root itself cannot be referenced. Required while data ingest is enabled.Empty
Tag Address KeyName of the field in the list element that carries the tag address. Required while Tag address in object keys is not selected.sourceKey
Tag Value KeyName of the field in the list element that carries the value. Required.value
Tag Timestamp KeyName of the field in the list element that carries the timestamp. Optional.ts
Decimal SeparatorDecimal separator in values that arrive as text for numeric tags: Dot (.) or Comma (,).Dot (.)
Tag address in object keysIf selected, the field names of the object referenced by List JSON Path are treated as tag addresses and the field values as tag values.Not selected

Field names are matched case-insensitively.

TIP

Even if you will use only the Metrics or Tags body format, List JSON Path must still be filled in; you can enter a name that does not exist in your body (e.g. items).

No-Data Watchdog ​

Lowers the quality of the device and its tags when no data arrives from the external system for a certain time.

No-Data Watchdog tab

FieldDescriptionDefaultRange
No-Data Watchdog EnabledTurns on the watchdog. While it is off, the device quality stays Good even if no data arrives.Not selected–
No-Data Timeout [s]The quality is lowered this many seconds after the last accepted data. If no data has arrived since the service started, the quality is lowered immediately.301–86400
No-Data QualityQuality assigned to the device and its tags when the time is exceeded: Bad or Uncertain.Uncertain–
Recover quality to Good on dataIf selected, the quality of the device and all its tags is set to Good after every accepted request. If not selected, only the tags that received a value become Good; the device quality stays low.Selected–

Tag Definition ​

Select the device in the channel tree and add a new tag in the tag table on the right. The common fields are filled in as on the Tag Management page.

Each incoming value is matched only among the tags of the authenticated device, in this order:

  1. If TargetTagId is given in the body, the tag with this numeric ID.
  2. The tag whose Address field is the same as the incoming address (e.g. the sourceKey value or the Metrics field name).
  3. If none is found, the tag whose name is the same as the incoming address.

Address and name comparisons are case-insensitive; leading and trailing spaces are ignored. Values that do not match are rejected and written to the Errors list in the response.

Choose a Data Type that suits the incoming value; a value that cannot be converted is rejected. The Update Interval[s] field is not used for REST Server; the tag is updated as soon as the request arrives.

Sending Data ​

Request ​

PropertyValue
Addresshttps://<server>/api/RestIngest/Telemetry
MethodPOST
Content-Type headerapplication/json
X-Device-Id headerExternal Device Id or the device's numeric ID
X-Device-Key headerDevice Key

<server> is the address of the 2WinScada web interface; the endpoint is published on the same HTTPS address as the web interface. If the web interface is published on a port other than the default, add the port as well (https://<server>:<port>). The endpoint does not require a user session or an API key; authentication is done only with the device key.

Example request:

http
POST /api/RestIngest/Telemetry HTTP/1.1
Host: <server>
Content-Type: application/json
X-Device-Id: kazan-dairesi-01
X-Device-Key: <device-key>

{
  "MessageId": "kazan-0001",
  "DeviceTime": "2026-10-15T08:30:00Z",
  "Metrics": {
    "Kazan1_Run": 1,
    "Kazan1_Temp": 45.2
  }
}

The same request with curl:

bash
curl -X POST "https://<server>/api/RestIngest/Telemetry" \
  -H "Content-Type: application/json" \
  -H "X-Device-Id: kazan-dairesi-01" \
  -H "X-Device-Key: <device-key>" \
  -d '{"Metrics":{"Kazan1_Run":1,"Kazan1_Temp":45.2}}'

Body formats ​

The body must be a JSON object (an array at the root level is not accepted). These fixed fields can be used in the body; the field names are case-insensitive:

FieldDescription
MessageIdOptional message identifier (at most 200 characters). A second request for the same device with the same identifier within 24 hours is not processed; IsDuplicate returns true in the response. This record is kept in memory and reset when the service restarts.
DeviceTimeOptional timestamp in ISO 8601 format (e.g. 2026-10-15T08:30:00Z). Used for values that have no time of their own.
MetricsObject whose field names are tag addresses and whose values are tag values.
TagsArray of elements made up of SourceKey or TargetTagId, Value and the optional Ts fields.

Every field other than these is processed according to the Payload Parsing settings. A request must contain at least one value source; several formats can be used together in the same request.

Metrics format: All values are recorded with DeviceTime (or the server time if it is missing).

json
{
  "DeviceTime": "2026-10-15T08:30:00Z",
  "Metrics": { "Kazan1_Run": 1, "Kazan1_Temp": 45.2 }
}

Tags format: Each element can carry its own timestamp. If TargetTagId is given, the tag is matched by its numeric ID.

json
{
  "Tags": [
    { "SourceKey": "Kazan1_Run", "Value": 1, "Ts": "2026-10-15T08:30:00Z" },
    { "TargetTagId": 1234, "Value": 45.2 }
  ]
}

List format: When List JSON Path is data.items and the other settings are at their defaults:

json
{
  "data": {
    "items": [
      { "sourceKey": "Kazan1_Run", "value": 1, "ts": "2026-10-15T08:30:00Z" },
      { "sourceKey": "Kazan1_Temp", "value": 45.2 }
    ]
  }
}

If the path points to a single object instead of an array, this object is read as a single value.

Addresses in field names: When List JSON Path is data and Tag address in object keys is selected. The value of a field can be the tag value directly, or an object that contains the Tag Value Key and Tag Timestamp Key fields:

json
{
  "data": {
    "Kazan1_Run": 1,
    "Kazan1_Temp": { "value": 45.2, "ts": "2026-10-15T08:30:00Z" }
  }
}

Values and timestamp ​

  • A value can be a JSON number, text or true / false. null, object or array values are rejected.
  • For values that arrive as text for numeric tags, the decimal separator is interpreted according to the Decimal Separator setting; no thousands separator may be used. Values sent as JSON numbers are not affected by this setting.
  • Timestamps must be sent as text in ISO 8601 format. Unix timestamps (numbers) are not supported: they are ignored in the list and field-name formats, and in the DeviceTime or Ts field they cause the whole request to be rejected.
  • The time of a value is taken, in order, from the element's own timestamp, from the DeviceTime field or from the server time.
  • The JSON representation of a single value cannot exceed 262,144 characters; a longer value is rejected.

Response ​

When the request reaches the endpoint and is processed, the response returns with HTTP code 200, including authentication errors; the result is evaluated from the Success and ErrorCode fields in the body. If the body is not valid JSON or one of the fixed fields is not of the expected type, HTTP 400 is returned; if the Content-Type is not JSON, HTTP 415 is returned.

Example successful response:

json
{
  "Success": true,
  "ErrorMessage": null,
  "ErrorCode": 0,
  "Payload": {
    "DeviceIdentifier": "kazan-dairesi-01",
    "DeviceId": 12,
    "MessageId": "kazan-0001",
    "IsDuplicate": false,
    "AcceptedCount": 2,
    "RejectedCount": 0,
    "Errors": []
  }
}

Even if Success is true, some values may have been rejected. AcceptedCount is the number of accepted values and RejectedCount the number of rejected values; the Errors list contains the reasons for rejection (e.g. Tag mapping not found, Type conversion failed, Payload item too large).

Error codes:

ErrorCodeMeaning
1101The X-Device-Id or X-Device-Key header is missing.
4600, 4602The device identifier or the device key is not valid, or the device is not loaded at runtime.
4601The body is invalid: there is no value source, an address/identifier or value is missing in a Tags element, MessageId exceeds 200 characters, or no value could be extracted from the body.
4603The device is inactive, REST Server Ingest Enabled is not selected, or the device is currently not accepting data.
4900The license does not include REST integration.
1000Unexpected error; the details are in the service log.

Troubleshooting ​

SymptomChecks
1101 is returnedCheck that the X-Device-Id and X-Device-Key header names are spelled correctly and are not empty.
4600 or 4602 is returnedCheck that the X-Device-Id value is the same as the External Device Id and that the device is in a channel of the RestServer type. Make sure the same External Device Id is not used on more than one device. Check that the key in the external system is the same as the latest key saved on the device; if the key was renewed, make sure the device was saved and the external system was updated. If the device was added recently, make sure it has been loaded into the runtime.
4603 is returnedCheck the Active and REST Server Ingest Enabled settings of the device; after a change, make sure the device has been loaded into the runtime.
4601 is returnedCheck that the body is a JSON object, that the List JSON Path points to the actual path in the body, and that the Tag Address Key / Tag Value Key names are the same as the field names in the body.
Tag mapping not found errorCheck that the incoming address is the same as the tag's Address field or the tag name, and that the tag belongs to the same device.
Type conversion failed errorCheck the type of the value, the tag's Data Type selection and, for numbers that arrive as text, the Decimal Separator setting.
HTTP 400 is returnedCheck that the body is valid JSON, that the DeviceTime and Ts fields are ISO 8601 text and that the Tags field is an array.
Tag quality drops to Uncertain or BadIf the No-Data Watchdog is on, check that the data send interval is shorter than the No-Data Timeout [s] value.

2WinScada 2.10