Developer & Integration Tools

No-code where you can. Code where you need it.

Most of the platform is configured, not programmed. Where a device or an integration genuinely needs logic, there are defined places to write it — edited in the platform, owned by the entity they belong to, and audited like any other field.

Book a DemoTalk to an Expert

 
 
 
 
 
 
 
Vision Smart Platform symbol
BoundedCode lives in named places, not scattered through a deployment
VersionedLogic belongs to the model or the version that owns it
AuditedCode changes are recorded like any other field change

Extension points, not a fork.

You extend the platform by filling in the places it leaves open for you. Nothing on this page requires a custom build, a private branch, or a recompile before it takes effect.

CODEC in JavaScript
Encoder and decoder pairs on controller models and versions, with a language selector, and download or upload of the code as files.
Preprocessing functions
Optional transformations applied to an incoming value before the metric is persisted, so what is stored is already in usable form.
Metric template paths
The JSON or XML path that pulls a value out of a payload, together with the data type and unit of measurement that give it meaning.
Rules as JSON
The visual rule builder shows the JSON the engine will evaluate, so what runs is readable and reviewable before it is switched on.
Public and internal APIs
General-purpose endpoints available to any implementation, exposed through an API gateway that handles authentication and policy.
Templates and bulk import
Downloadable templates that impose the file structure for mass enrollment, so an import is a filled-in template rather than a mapping exercise.

Four places where logic belongs.

Every platform ends up needing somewhere to put the awkward part. These are the four, and each of them is attached to the entity it serves — not to an environment, a branch or a build.

Decoder
Turns a raw payload into a structure the metric templates can query. A vendor’s byte layout is dealt with once, here, for every device of that version.
Encoder
Builds the payload a device expects from a command template, so one command definition serves products that encode it differently.
Preprocessing
A transformation applied to a value on its way in, so what gets stored is already in the form operations reads.
Rule conditions and effects
Assembled visually, previewed as JSON. The logic is inspectable before activation and stays an operational object rather than a deployment.

Expose what you configured, without recompiling.

The general-purpose endpoints take a fixed set of context fields plus a flexible list of named parameters. Those names are the ones you defined visually — a query, a rule, an activity. Configure it in the interface, then call it by name. No new endpoint, no release.

Requestnamed parameters you defined
POST /api/generic/executeWithParams
 
{
"activityId": 1042,
"domainId": 7,
"culture": "en-GB",
 
"parameters": [
{ "name": "assetGroup", "value": "north-ring" },
{ "name": "since", "value": "2026-08-01" }
]
}
Responsewhatever the rule returns
{
"readings": 318,
"exceptions": 4,
"lastSeen": "2026-08-26T09:14:00Z"
}

Illustrative example of the general-purpose endpoint shape. Alongside it, the platform exposes process-instance operations — start, load, set and get parameters — and system operations such as current instance information, save, search, flow states, state log and status update. The full API reference is available to integrators and clients on request.

An integration is not a back door.

Calls over the API pass the same gateway, carry the same kind of session and answer to the same roles and permissions as a person clicking through the interface. There is no second access model to keep in step with the first.

Authentication
Handled centrally
  • Authentication is managed by the API gateway, which issues and validates the session
  • A JWT token or an encrypted cookie, set HttpOnly and Secure
  • The gateway can delegate to an external identity provider over OAuth 2.0 or OpenID Connect and still manage the session locally
Policy
Applied before the services
  • Unauthorized calls are blocked at the gateway, before they reach any service behind it
  • SSL termination happens at the gateway
  • Security policies are configuration, not code scattered through the services
Compatibility
Kept on purpose
  • The API can be extended without breaking the integrations already built on it
  • Integration accounts are platform accounts, so their roles and permissions are reviewed alongside everyone else’s
  • Revoking a role revokes it for the interface and the API at the same time

Rules that can call out.

Integration runs in both directions. A rule can compose a JSON body, send it to an external service through the REST client, parse what comes back and carry on with the result — inside the same visual rule, with no service to build and deploy alongside it.

JsonObject
Builds an object from key–value pairs. Values can be scalars, entities, lists or other JSON objects — nesting is natural.
JsonObject("assetId", Device.Serial, "urgent", true)
{"assetId":"AC-4417","urgent":true}
JsonArray
Builds an array; every operand becomes exactly one element.
JsonArray("Admin", "User")
["Admin","User"]
JsonText
Serializes the object to text at the boundary, once. Escaping is guaranteed by the serializer.
JsonText(JsonObject("age", 30))
{"age":30}
RestClient
Sends the serialized payload to an external service from inside the rule.
RestClient(endpoint, JsonText(body))
← the service’s response
JsonParse / JsonValue
Parses the response and reads a value by path. Types survive the round trip: a number comes back a number.
JsonValue(JsonParse(#response), "ticket.id")
4417 Integer, not text

Inside a rule the JSON is an object you compose and query. Only at the boundary — when it goes to the plugin — is it serialized, once.

Tell us where you need to write code.

A vendor payload nobody has decoded, an external system that has to stay in step, a fleet to enroll from a file. We will show you which extension point covers it — and hand you the API reference if that is the answer.

Discuss your project