Skip to content
Proxus 2.0.0 Proxus 2.0: the largest release in Proxus history Release notes

How-to guide · for Developers

REST API

Sign in with a user name and password, get a token, and read or change Proxus objects such as devices, gateways and rules over OData.

At the end of this guide, a script of yours signs in to the hub, gets a token and reads devices with their gateway. The same API can create, change and delete objects, within the rights of the user you sign in with.

Before you start

You need:

  • The hub's address, for example http://localhost:8080 on a local installation. The API is served on the same port as the hub's screens.
  • A Proxus user for the integration. Its role decides what the API may read and change, exactly as in the screens. See Users and roles.
  • curl, Python 3 with the requests package, or .NET, depending on the example you follow.

What the API offers

AddressWhat it does
POST /api/Authentication/AuthenticateChecks a user name and password and returns a token.
/api/odata/<EntitySet>Read, create, change and delete objects (OData v4).
/api/odata/$metadataThe full data model: every entity set, its fields and its links.
/swaggerAn interactive page that lists every operation and lets you try it.
POST /api/Telemetry/executeStored tag values. See Telemetry API.

Among the entity sets are Device, DeviceProfile, DeviceProfileRegister (tags), Gateway, TargetProfile (outbound targets), NotificationChannel, Rule, RuleAction, Flow (pipelines), Function, Alert, Log, ScheduledDelivery, TrendView and UnsTopicPermission. The list at /api/odata/ is always the complete one.

Step 1: Get a token

Send the user name and password as JSON. The answer is the token itself, as plain text.

curl -X POST http://localhost:8080/api/Authentication/Authenticate \
  -H "Content-Type: application/json" \
  -d '{"userName":"Admin","password":""}'

Put the token in the Authorization header of every later call:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
  • A wrong user name or password returns 401 with the text User name or password is incorrect.
  • A call to /api/... without a valid token is answered with 401, and a call the user may not make with 403.
  • A token stays valid for the time set in TokenExpireTime (one year in the delivered configuration). Get a new one when a call answers 401.

Step 2: Read objects

TOKEN=$(curl -s -X POST http://localhost:8080/api/Authentication/Authenticate \
  -H "Content-Type: application/json" -d '{"userName":"Admin","password":""}')

curl -s -G http://localhost:8080/api/odata/Device \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "\$filter=startswith(DeviceName,'LYS')" \
  --data-urlencode "\$select=Oid,DeviceName,Enabled" \
  --data-urlencode "\$count=true" \
  --data-urlencode "\$top=3"

The answer:

{
  "@odata.context": "http://localhost:8080/api/odata/$metadata#Device(Oid,DeviceName,Enabled)",
  "@odata.count": 14,
  "value": [
    { "Oid": 66, "DeviceName": "LYS_MILL_01", "Enabled": true },
    { "Oid": 67, "DeviceName": "LYS_LINE1_PLC", "Enabled": true },
    { "Oid": 69, "DeviceName": "LYS_PACKER_04", "Enabled": true }
  ]
}

The usual OData query options work:

OptionExampleNotes
$filterSite eq 'Lyon Foods Plant'eq, ne, gt, lt, and, or, startswith, contains
$selectOid,DeviceName,StatusOnly these fields.
$expandGateway($select=Name)Follow a link to another object.
$orderbyDeviceName desc
$top, $skip$top=50&$skip=100$top may be at most 100. A larger value is refused with 400.
$count$count=trueAdds @odata.count with the total.

One object is read by its key: GET /api/odata/Device(69). A device's latest values come with it when you expand LatestValues:

curl -s -G "http://localhost:8080/api/odata/Device(69)" -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "\$select=DeviceName" --data-urlencode "\$expand=LatestValues"

Each latest value has Key, Value, DataType, Quality and LastUpdate.

Step 3: Use it from code

list_devices.py
import requests

HUB = "http://localhost:8080"

# 1. Sign in and get a token
response = requests.post(
    f"{HUB}/api/Authentication/Authenticate",
    json={"userName": "Admin", "password": ""},
    timeout=30,
)
response.raise_for_status()
token = response.text.strip()
headers = {"Authorization": f"Bearer {token}"}

# 2. Read the devices of one site with their gateway
response = requests.get(
    f"{HUB}/api/odata/Device",
    params={
        "$filter": "Site eq 'Lyon Foods Plant'",
        "$select": "Oid,DeviceName,Status",
        "$expand": "Gateway($select=Name)",
        "$orderby": "DeviceName",
    },
    headers=headers,
    timeout=30,
)
response.raise_for_status()
for device in response.json()["value"]:
    print(device["Oid"], device["DeviceName"], device["Status"], device["Gateway"]["Name"])
Program.cs
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;

var hub = new HttpClient { BaseAddress = new Uri("http://localhost:8080/") };

// 1. Sign in and get a token
var login = await hub.PostAsJsonAsync("api/Authentication/Authenticate",
    new { userName = "Admin", password = "" });
login.EnsureSuccessStatusCode();
var token = await login.Content.ReadAsStringAsync();
hub.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

// 2. Read the gateways
using var gateways = JsonDocument.Parse(
    await hub.GetStringAsync("api/odata/Gateway?$select=Oid,Name"));
foreach (var gateway in gateways.RootElement.GetProperty("value").EnumerateArray())
    Console.WriteLine($"{gateway.GetProperty("Oid")} {gateway.GetProperty("Name")}");

Create, change and delete

The entity sets also take POST (create), PATCH (change some fields), PUT (replace) and DELETE, the standard OData way. For example, to switch a device off:

curl -X PATCH "http://localhost:8080/api/odata/Device(69)" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"Enabled": false}'

The user's role decides what is allowed. A change the role does not permit is refused, exactly as the same change would be refused in the hub's screens.

What's next

Was this page helpful?

Evaluating Proxus? See it on your own machines in a 30-minute technical session.