Rule System
The Rule System is a rule engine designed to trigger actions when the rule's conditions are met. It evaluates device sensor data against defined rules and executes actions such as creating alerts, sending emails, publishing MQTT messages, and more.
Core Concepts
Rule Group & Rule
Rule Groups organize related Rules that share the same stateName. Key principles:
- Each Rule Group contains multiple rules.
- Rules within a Rule Group modify values for the same state name.
- Rules can have different trigger types: Time-Triggered, Data-Triggered, EventData-Triggered, or State-Time Transition.
- A Rule Group can be associated with one or more Validity entities to control when the group is active.
Validity
Validity manages the activation times for a Rule Group. It allows scheduling when certain rule groups should be active, based on weekdays, hours of the day, and specific datetime ranges.
For example, a Validity entity that is active on weekdays from 9 AM to 5 PM UTC:
const validity = new ValidityEntity({
workspace: 'myWorkspace',
name: 'Weekday Business Hours',
monday: true,
tuesday: true,
wednesday: true,
thursday: true,
friday: true,
saturday: false,
sunday: false,
startHour: 9,
endHour: 17,
utcOffset: 0,
});
Rule Processing Flow
Entities Reference
RuleGroupEntity
| Field | Type | Description |
|---|---|---|
id | number | Auto-increment primary key |
identifier | string (UUID) | Unique identifier, auto-generated |
stateName | string | null | State machine name shared by all rules in this group |
description | string | null | Human-readable description |
deviceIds | string[] | null | Target specific device IDs (null = all workspace devices) |
deviceTypes | string[] | null | Target specific device types (null = all types) |
exceptDeviceIds | string[] | null | Exclude specific device IDs |
exceptDeviceTypes | string[] | null | Exclude specific device types |
zoneTypeUnion | string[] | null | Zone type union for zone-scoped rule evaluation |
extra | json | null | Additional metadata |
workspace | string | Workspace ID (multi-tenant) |
disableAt | Date | null | Soft-delete timestamp |
validityEntity | ValidityEntity[] | Associated validity schedules |
rules | RuleEntity[] | Child rules |
RuleEntity
| Field | Type | Description |
|---|---|---|
id | number | Auto-increment primary key |
identifier | string (UUID) | Unique identifier, auto-generated |
description | string | null | Human-readable description |
conditions | ConditionFields[] | null | Array of conditions to evaluate |
conditionType | string | "and-case" (all must match) or "or-case" (any must match) |
workspace | string | Workspace ID |
triggerType | string | "data" | "time" | "event_data" | "state_time" |
eventTypes | string[] | null | Event type filters (for event_data trigger only) |
stateTimeCondition | string | null | Duration string (for state_time trigger only) |
crontabExpressions | string[] | null | Cron expressions (for time trigger only) |
triggerState | number | Required current state for the rule to trigger (default 0) |
targetState | number | State to set after rule triggers (default 0) |
createdAt | Date | Creation timestamp |
updateAt | Date | Last update timestamp |
disableAt | Date | null | Soft-delete timestamp |
tags | TagEntity[] | Associated tags |
actionEntity | ActionEntity[] | Associated actions |
ruleGroup | RuleGroupEntity | Parent rule group |
triggerState: The state value that must match for the rule to evaluate.0= normal state,> 0= abnormal state. If the current state does not equaltriggerState, the rule is skipped.targetState: The state to transition to after the rule triggers. This prevents the rule from triggering repeatedly.
ValidityEntity
| Field | Type | Description |
|---|---|---|
id | number | Auto-increment primary key |
identifier | string (UUID) | Unique identifier, auto-generated |
workspace | string | Workspace ID |
name | string | Validity name |
description | string | null | Human-readable description |
monday - sunday | boolean | Day-of-week flags (default true) |
startHour | number | Active start hour, 0-24 decimal (default 0) |
endHour | number | Active end hour, 0-24 decimal (default 24) |
startDatetime | Date | null | Absolute start datetime |
endDatetime | Date | null | Absolute end datetime |
utcOffset | number | UTC offset in hours (default 0) |
createdAt | Date | Creation timestamp |
updateAt | Date | Last update timestamp |
disableAt | Date | null | Soft-delete timestamp |
StateEntity
States track the current value of a stateName per device or zone. This is how the rule engine prevents repeat triggering.
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Primary key |
stateName | string | State machine name (from Rule Group) |
state | number | Current state value (0 = normal) |
stateStartAt | Date | When the current state began (updates on state change) |
deviceId | string | null | Device-scoped state (mutually exclusive with zoneUnion) |
zoneUnion | string | null | Zone-scoped state (mutually exclusive with deviceId) |
workspace | string | Workspace ID |
TagEntity
Tags label rules for organization and filtering.
| Field | Type | Description |
|---|---|---|
id | number | Auto-increment primary key |
tag | string | Tag value |
description | string | null | Human-readable description |
workspace | string | null | Workspace ID |
createdAt | Date | Creation timestamp |
updateAt | Date | Last update timestamp |
disableAt | Date | null | Soft-delete timestamp |
Rule Example
{
"id": 28,
"rules": [
{
"id": 794,
"conditions": [
{
"field": "occupyStartDate",
"operator": "ISOTimePassed",
"value": "{\"seconds\":300}",
"aggregator": ""
}
],
"conditionType": "and-case",
"workspace": "7b6a01b4-2cf3-4e29-998b-5b1ffd59a81e",
"triggerType": "data",
"crontabExpression": null,
"triggerState": 0,
"targetState": 1,
"actionEntity": [
{
"id": 6,
"workspace": "7b6a01b4-2cf3-4e29-998b-5b1ffd59a81e",
"description": null,
"type": "alert",
"meta": null
}
]
},
{
"id": 793,
"conditions": [
{
"field": "occupyStartDate",
"operator": "isNull",
"value": "",
"aggregator": ""
}
],
"conditionType": "and-case",
"workspace": "7b6a01b4-2cf3-4e29-998b-5b1ffd59a81e",
"triggerType": "data",
"crontabExpression": null,
"triggerState": 1,
"targetState": 0,
"actionEntity": []
}
],
"description": "some text",
"field": "occupyStartDate",
"stateName": "occupyStartDate",
"deviceIds": null,
"deviceTypes": null,
"extra": null,
"workspace": "7b6a01b4-2cf3-4e29-998b-5b1ffd59a81e",
"validityEntity": []
}
Rule Types
There are 4 types of rules based on trigger type:
1. Data-Triggered ("data")
Activated when specified data conditions are met (e.g., sensor readings exceeding thresholds). Evaluated each time new sensor data arrives for the device.
2. Time-Triggered ("time")
Activated based on specific time schedules using cron expressions. Evaluated every minute by a cron job.
3. EventData-Triggered ("event_data")
Triggered in response to internal Seer platform events. The eventTypes field filters which events activate the rule.
Available event types:
| Event Type | Description |
|---|---|
new_data.http | New data from HTTP sources |
new_data.mqtt | New data from MQTT sources |
new_data.ws | New data from WebSocket sources |
new_data.simulator | New data from simulator sources |
new_data.internal | New data from internal sources |
alert.trigger | An alert was created |
infer.rule | An inference rule was evaluated |
infer.link | An inference link was evaluated |
rule.state_change | A rule's state changed |
task.create | A task was created |
task.ack | A task was acknowledged |
task.close | A task was closed |
task.reopen | A task was reopened |
4. State-Time Transition ("state_time")
Triggered when the current state has persisted for a specified duration. Combines state monitoring with time-based persistence checks. For example: "temperature state has been 1 (abnormal) for more than 5 minutes".
The stateTimeCondition field specifies the duration as a JSON-encoded Luxon Duration object:
| Key | Type | Example |
|---|---|---|
seconds | number | {"seconds": 300} (5 minutes) |
minutes | number | {"minutes": 5} |
hours | number | {"hours": 1} |
days | number | {"days": 2} |
weeks | number | {"weeks": 1} |
months | number | {"months": 1} |
State-time rules can also have additional conditions that must be met alongside the duration check.
Conditions & Operators
Condition Structure
Each condition in the conditions array has these fields:
| Field | Type | Required | Description |
|---|---|---|---|
field | string | Yes | Dot-path to the data field (e.g., temperature, payload.values.LoadUnit) |
operator | string | Yes | Comparison operator |
value | any | Yes | Comparison value |
aggregator | string | No | Aggregation method for array fields |
Supported Operators
| Operator | Description |
|---|---|
= | Exact match |
!= | Not equal |
> | Greater than |
< | Less than |
>= | Greater than or equal |
<= | Less than or equal |
range | Within a range of values |
!range | Outside a range of values |
exist | Field exists in data |
isNull | Field is null or doesn't exist |
contains | Data field contains this string |
!contains | Data field does not contain this string |
startsWith | Data field starts with this string |
!startsWith | Data field does not start with this string |
endsWith | Data field ends with this string |
!endsWith | Data field does not end with this string |
ISOTimePassed | ISO time has passed within a duration |
UnixTimestampMsPassed | Unix timestamp (ms) has passed within a duration |
UnixTimestampPassed | Unix timestamp (seconds) has passed within a duration |
Aggregators
When the field resolves to an array of values, an aggregator determines how to combine them:
| Aggregator | Behavior |
|---|---|
(none) / "any" | Default. Rule triggers if any record matches the condition |
"all" | Rule triggers if every record matches the condition |
"avg" | Averages numeric values, then compares the result |
"min" | Takes the minimum numeric value, then compares |
"max" | Takes the maximum numeric value, then compares |
"sum" | Sums all numeric values, then compares |
Rule Actions
When a rule's conditions are met, the associated actions are executed. Each action has a type and a meta object containing action-specific configuration.
Supported Action Types
| Type | Description |
|---|---|
alert | Create an alert in the Seer platform |
alarm | Send an alarm to an alarmbox via MQTT |
alarmAlert | Send an alarm and create an alert |
closeAlert | Close existing alerts for a device |
cancelAlarm | Cancel an alarm on the alarmbox |
comEasyTask | Create a task and POST telemetry to a ComEasy system |
email | Send an email via template |
http | Send an HTTP request via Seer control |
inferData | Emit inferred data to the Seer platform |
mqtt | Publish an MQTT payload to the workspace topic |
sms | Send an SMS message |
task | Create a task in the Seer platform |
taskOperation | Perform an operation on an existing task (start/complete/reopen) |
Action: alert
Creates an alert in the Seer platform.
| Meta Field | Description | Optional | Default |
|---|---|---|---|
description | Alert description | Yes | ${category.toLowerCase()} detected from ${shortName ?? extName ?? deviceId} |
title | Alert title | Yes | ${category} Alarm from ${shortName ?? extName ?? deviceId} |
category | Alert category | Yes | Unclassified |
location | Alert location | Yes | The zoneName of the device |
Example:
{
"actions": [
{
"type": "alert",
"meta": {
"category": "high temperature",
"description": "Temperature too high",
"title": "Temperature Alert",
"location": "Room 101"
}
}
]
}
Action: alarm
Sends an alarm to an alarmbox via MQTT.
| Meta Field | Description | Optional |
|---|---|---|
controlUrl | Seer control URL for target alarmDevices | Yes |
alarmDevices | Alarm device IDs | No |
alarmTopic | MQTT topic the alarmbox subscribes to | No |
| additional fields | Any extra fields to send to the alarmbox | Yes |
Example:
{
"actions": [
{
"type": "alarm",
"meta": {
"controlUrl": "http://controller-office-mqtt",
"alarmTopic": "alarmbox/alarm",
"alarmDevices": ["ALARM_BOX_01"]
}
}
]
}
Action: alarmAlert
Sends an alarm and creates an alert. Combines the meta fields of both alarm and alert.
| Meta Field | Description | Optional |
|---|---|---|
controlUrl | Seer control URL for target alarmDevices | Yes |
alarmDevices | Alarm device IDs | No |
alarmTopic | MQTT topic the alarmbox subscribes to | No |
category | Alert category | Yes |
description | Alert description | Yes |
| additional fields | Any extra fields to send to the alarmbox | Yes |
Example:
{
"actions": [
{
"type": "alarmAlert",
"meta": {
"category": "high temperature",
"description": "Temperature too high",
"controlUrl": "http://controller-office-mqtt",
"alarmTopic": "alarmbox/alarm",
"alarmDevices": ["ALARM_BOX_01"]
}
}
]
}
Action: cancelAlarm
Cancels an active alarm on the alarmbox.
| Meta Field | Description | Optional |
|---|---|---|
controlUrl | Seer control URL for target alarmDevices | Yes |
alarmDevices | Alarm device IDs | No |
alarmTopic | MQTT topic for alarm cancellation | No |
| additional fields | Any extra fields to send to the alarmbox | Yes |
Example:
{
"actions": [
{
"type": "cancelAlarm",
"meta": {
"controlUrl": "http://controller-office-mqtt",
"alarmTopic": "alarmbox/alarm",
"alarmDevices": ["ALARM_BOX_01"]
}
}
]
}
Action: closeAlert
Closes active alerts for the triggering device. Makes a PATCH request to the Alert service.
| Meta Field | Description | Optional |
|---|---|---|
| any | Additional fields merged into the close request body | Yes |
The device ID and type from the triggering payload are automatically included in the close request.
Example:
{
"actions": [
{
"type": "closeAlert",
"meta": {}
}
]
}
Action: email
Sends an email via the Seer Post service. Reference: Nodemailer.
| Meta Field | Description | Optional |
|---|---|---|
subject | Email subject | Yes |
template | Email template name stored in Seer (Handlebars format) | Yes |
context | Template context variables | Yes |
from | Sender email address | Yes |
to | Recipient email(s) — string or array | Yes |
cc | CC email(s) — string or array | Yes |
bcc | BCC email(s) — string or array | Yes |
text | Plaintext message body | Yes |
html | HTML message body | Yes |
| additional fields | Any Nodemailer-supported field | Yes |
Example:
{
"actions": [
{
"type": "email",
"meta": {
"subject": "warning: $(extName) is too hot",
"template": "openAlert.hbs",
"to": "$(WS_EMAIL_LIST_1)",
"context": {
"temp": "$(TEMPERATURE)",
"category": "High temperature",
"timeZone": "HongKong"
}
}
}
]
}
Action: http
Sends an HTTP request via Seer control.
| Meta Field | Description | Optional |
|---|---|---|
controlUrl | Seer control URL to relay the request through | Yes |
url | Target URL | No |
method | HTTP method | No |
headers | Request headers | Yes |
body | Request body | Yes |
targetDevice | Device ID for resolving TD_ prefixed variables | Yes |
Example:
{
"actions": [
{
"type": "http",
"meta": {
"method": "GET",
"url": "$(TEST_URL)/radar/#(TD_extName)",
"headers": {
"Authorization": "Bearer $(TEST_TOKEN)"
},
"body": {
"id": ""
},
"targetDevice": "99c115f4-9ba9-4f82-a8c6-56966ebb45dc"
}
}
]
}
Action: inferData
Emits inferred data to the Seer platform via NATS.
| Meta Field | Description | Optional |
|---|---|---|
| any field | Any key-value pairs to emit as inferred data | Yes |
All key-value pairs in meta become the inferred data payload. Values can include Seer variables.
Example:
{
"actions": [
{
"type": "inferData",
"meta": {
"online": false,
"customField": "customValue",
"customField2": true
}
}
]
}
Action: mqtt
Publishes an MQTT payload to the workspace MQTT topic via Seer control.
| Meta Field | Description | Optional |
|---|---|---|
controlUrl | Seer control URL | Yes |
mqttTopic | Override MQTT topic (defaults to workspace topic) | Yes |
type | Payload type (e.g., "cmd", "data") | No |
payload | Single object or array of objects | No |
Example (single payload):
{
"actions": [
{
"type": "mqtt",
"meta": {
"type": "cmd",
"payload": {
"id": "d686a6ad-c1e2-4fe0-9c18-5aa56606cdf0",
"description": "testing mqtt",
"condition": "$(RULE_CONDITION)",
"POWER_ON": true,
"SWING": false
}
}
}
]
}
Example (array of payloads):
{
"actions": [
{
"type": "mqtt",
"meta": {
"type": "cmd",
"payload": [
{
"id": "d686a6ad-c1e2-4fe0-9c18-5aa56606cdf0",
"description": "testing mqtt 1",
"POWER_ON": true
},
{
"id": "d686a6ad-c1e2-4fe0-9c18-5aa56606cdf1",
"description": "testing mqtt 2",
"POWER_ON": false
}
]
}
}
]
}
Action: sms
Sends an SMS message via the Seer Post service.
| Meta Field | Description | Optional |
|---|---|---|
phoneNumbers | Phone number(s) — string or array | No |
message | SMS message content | No |
senderId | SMS sender ID | Yes |
messageType | Type of message | Yes |
Example:
{
"actions": [
{
"type": "sms",
"meta": {
"phoneNumbers": ["+1234567890", "+0987654321"],
"message": "Alert: Device is offline!",
"senderId": "SeerAlert"
}
}
]
}
Action: task
Creates a task in the Seer platform.
| Meta Field | Description | Optional |
|---|---|---|
category | Task category | Yes |
description | Task description | Yes |
Example:
{
"actions": [
{
"type": "task",
"meta": {
"description": "$(extName) is too hot"
}
}
]
}
Action: taskOperation
Performs an operation on an existing task. The task is found by taskId from the triggering event payload, or by querying with deviceId + category.
| Meta Field | Description | Optional |
|---|---|---|
operation | Operation to perform: "start", "complete", or "reopen" | No |
description | Description for the operation | Yes |
category | Task category (used to find the task if taskId not in payload) | Yes |
Example:
{
"actions": [
{
"type": "taskOperation",
"meta": {
"operation": "start",
"description": "Technician dispatched"
}
}
]
}
Action: comEasyTask
Creates a task and sends telemetry to a ComEasy system. This action first creates a Seer task, then POSTs task details to an external ComEasy endpoint.
| Meta Field | Description | Optional | Default |
|---|---|---|---|
url | ComEasy endpoint URL | No | — |
username | Authentication username | No | — |
password | Authentication password | No | — |
task_feedback_base_url | Base URL for task feedback callbacks | No | — |
emergency_level | Emergency level | Yes | 1 |
description | Task description | Yes | — |
device_name | Device name for ComEasy payload | Yes | — |
device_id | Device ID for ComEasy payload | Yes | — |
type | Request type | Yes | "POST_TELEMETRY_REQUEST" |
Seer Variable System
Seer variables allow dynamic value resolution in action meta fields and rule conditions. Variables are written as $(VAR_NAME) or ${VAR_NAME} and are replaced with actual values at execution time.
Rule-Specific Variables
| Variable | Description |
|---|---|
TRIGGER_FIELD_NAME | The name of the condition field that matched |
TRIGGER_FIELD_VALUE | The value of the condition field that matched |
RULE_OBJ | Access any field within the rule object via dot-path (e.g., $(RULE_OBJ.conditions.1.field)) |
RULE_CONDITION | Formatted string of the matched rule conditions |
RULE_DESCRIPTION | The rule's description |
RULE_STATE_NAME | The rule's state name |
ACTION_SEQ_NUM | Unique action sequence number |
RULE_OBJ Usage Examples
"$(RULE_OBJ.conditions.1.field)" -> "VOLTAGE"
"$(RULE_OBJ.crontabExpressions.0)" -> "* * * * *"
"$(RULE_OBJ.stateTimeCondition)" -> '{"minutes": 5}'
Device-Level Variables
| Variable | Description |
|---|---|
id | Unique identifier for the device |
shortName | Device short name |
name | Device name |
type | Device type |
extName | External ID or label assigned to the device |
extra | Additional device data (e.g., $(extra.diameter)) |
decoder | The decoder/protocol used by the device |
enableAlert | Whether alerts are enabled for the device |
timeout | Device timeout period |
workspace | The device's workspace ID |
Zone-Related Variables
| Variable | Description |
|---|---|
ZONE_ID | Zone ID associated with the device |
ZONE_NAME | Zone name associated with the device |
ZONE_TYPE | Zone type associated with the device |
Time Variables
| Variable | Description |
|---|---|
UNIX_TIME | Current Unix timestamp (seconds) |
UNIX_TIME_MS | Current Unix timestamp (milliseconds) |
UTC_DATE | Current UTC+8 date formatted as MMMM d, yyyy (EEEE) |
UTC_TIME | Current UTC+8 time formatted as HH:mm:ss 'GMT'Z |
Target Device Variables (TD_ prefix)
Variables prefixed with TD_ resolve against a different target device instead of the triggering device. Requires targetDevice to be set in the action meta (for http actions) or specified through other means.
Example: $(TD_extName) resolves extName from the target device specified in the action meta.
Workspace Variables
Any variable that doesn't match a built-in code is resolved as a workspace user-defined variable or secret (stored in MinIO). For example, $(WS_EMAIL_LIST_1) would resolve to a workspace configuration variable named WS_EMAIL_LIST_1.
Variable Resolution Order
- Rule-specific variables (
TRIGGER_*,RULE_*,ACTION_SEQ_NUM) - A field in the triggering payload matching the variable name
- A field on the device record matching the variable name (dot-path supported)
- A field in the payload (if not the same device)
- A configuration/environment variable
- Workspace user-defined variable (from MinIO)
- Workspace secret (from MinIO)
Variable Interpolation & Calculations
Traditional Variable References
- Format:
$(VARIABLE_NAME)or${VARIABLE_NAME} - Example:
$(TEMPERATURE_SENSOR)is replaced with the value of theTEMPERATURE_SENSORfield from the device data.
Calculation Expressions
$SUM(value1, value2, ..., valueN)
Adds all argument values.
$SUM($(VAR1), $(VAR2), 10) → adds VAR1 + VAR2 + 10
$SUB(value1, value2, ..., valueN)
Subtracts subsequent values from the first.
$SUB($(VAR1), $(VAR2), 5) → VAR1 - VAR2 - 5
$MULT(value1, value2, ..., valueN)
Multiplies all argument values.
$MULT($(VAR1), $(VAR2), 2) → VAR1 * VAR2 * 2
$DIV(value1, value2, ..., valueN)
Divides the first value by subsequent values sequentially.
$DIV($(VAR1), $(VAR2), 2) → VAR1 / VAR2 / 2
$MAX(value1, value2, ..., valueN)
Returns the maximum of all argument values.
$MAX($(VAR1), $(VAR2), 100) → max(VAR1, VAR2, 100)
$MIN(value1, value2, ..., valueN)
Returns the minimum of all argument values.
$MIN($(TEMP1), $(TEMP2), 0) → min(TEMP1, TEMP2, 0)
$BOUNDARY(value, min, max)
Clamps value to be between min and max.
$BOUNDARY($(TEMP), 10, 50) → clamp(TEMP, 10, 50)
$COALESCE(value1, value2, ..., valueN)
Returns the first non-null, non-undefined value.
$COALESCE($(SPEED), 0) → SPEED ?? 0
$CONCAT(value1, value2, ..., valueN)
Concatenates all values as strings.
$CONCAT($(PREFIX), '-', $(SUFFIX)) → "PREFIX-SUFFIX"
Notes
- All calculation results are returned as strings for compatibility.
- Mathematical operations are performed when all arguments are numbers.
- When any argument is a string, concatenation is performed instead.
- Division by zero is handled gracefully with error logging.
- Nested parentheses and quoted strings are properly parsed in arguments.
Time-Triggered Rules
Users specify cron job expressions to schedule rule execution. The rule system evaluates time-triggered rules every minute.
Cron Expression Format
* * * * *
┬ ┬ ┬ ┬ ┬
│ │ │ │ │
│ │ │ │ └── Day of week (0-7, 1L-7L; 0 or 7 is Sunday)
│ │ │ └───── Month (1-12)
│ │ └────────── Day of month (1-31, L)
│ └─────────────── Hour (0-23)
└──────────────────── Minute (0-59)
The cron expression is validated using the cron-parser library. Second precision is not supported — the system evaluates on a per-minute basis.
Important: If the Rule Group is not active (disabled or outside validity window), the cron job will not trigger.
Testing Cron Expressions
Use the dry-run endpoint to test if a cron expression matches a specific datetime:
POST /rule/v1/rules/cron-expression/dryrun
Body: { "crontabExpression": "* * * * *", "checkWithDate": "2025-01-01T12:00:00Z", "utcOffset": 0 }
Response: true/false
API Reference
Base URL: /rule/v1
Health
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /health | — | Health check (DB ping, memory RSS, NATS connectivity) |
Workspace Resources
Bulk operations for all rule resources in a workspace.
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /workspaceResources/:workspace | LV1 | Get all workspace resources (rule groups, rules, actions, validities) |
POST | /workspaceResources/:workspace | LV1 | Bulk create/import workspace resources |
DELETE | /workspaceResources/:workspace | LV1 | Delete all workspace resources |
Rules
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /rules/paginate | LV2 | Paginated rule listing |
GET | /rules/workspace/:workspace | LV2 | Get all rules for a workspace |
GET | /rules/workspace/:workspace/:ruleId | LV2 | Get a single rule by ID |
POST | /rules/workspace/:workspace | LV2 | Create a new rule |
PATCH | /rules/workspace/:workspace/:ruleId | LV2 | Update a rule |
DELETE | /rules/workspace/:workspace | LV2 | Delete all rules in a workspace |
DELETE | /rules/workspace/:workspace/:ruleId | LV2 | Delete a specific rule |
POST | /rules/workspace/:workspace/:ruleId/addTag | LV2 | Add a tag to a rule |
POST | /rules/workspace/:workspace/:ruleId/addAction | LV2 | Add an action to a rule |
PUT | /rules/workspace/:workspace/:ruleId/updateTag | LV2 | Replace all tags on a rule |
PUT | /rules/workspace/:workspace/:ruleId/updateAction | LV2 | Replace all actions on a rule |
POST | /rules/workspace/:workspace/dryrun | LV3 | Dry-run rule evaluation against sample data |
POST | /rules/cron-expression/dryrun | LV4 | Test a cron expression against a datetime |
GET | /rules/state | LV5 | Query rule states (with device/zone info) |
POST | /rules/state/:stateId | LV2 | Manually set a rule state |
Rule Groups
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /rulegp/paginate | LV2 | Paginated rule group listing |
POST | /rulegp | LV2 | Create a rule group |
PATCH | /rulegp/:id | LV2 | Update a rule group |
DELETE | /rulegp/:ruleGpId | LV2 | Delete a rule group and all its rules |
POST | /rulegp/:ruleGpId/enable | LV2 | Enable all rules in a group |
POST | /rulegp/:ruleGpId/disable | LV2 | Disable (soft-delete) all rules in a group |
POST | /rulegp/:ruleGpId/clone | LV2 | Clone a rule group with all its rules |
POST | /rulegp/:ruleGpId/addValidity | LV2 | Add a validity schedule to a group |
PUT | /rulegp/:ruleGpId/updateValidity | LV2 | Replace validity schedules on a group |
POST | /rulegp/:ruleGpId/rule | LV2 | Create a rule within this group |
PATCH | /rulegp/:ruleGpId/rule/:ruleId | LV2 | Update a rule within this group |
DELETE | /rulegp/:ruleGpId/rule/:ruleId | LV2 | Delete a rule from this group |
POST | /rulegp/:ruleGpId/rule/:ruleId/addAction | LV2 | Add an action to a group's rule |
PUT | /rulegp/:ruleGpId/rule/:ruleId/updateTag | LV2 | Update tags on a group's rule |
PUT | /rulegp/:ruleGpId/rule/:ruleId/updateAction | LV2 | Update actions on a group's rule |
Actions
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /action/workspace/:workspace | LV2 | Get workspace actions |
POST | /action/workspace/:workspace | LV2 | Create an action |
PATCH | /action/workspace/:workspace/:actionId | LV2 | Update an action |
DELETE | /action/workspace/:workspace/:actionId | LV2 | Delete an action |
POST | /action/parse-seer-variable | LV2 | Parse Seer variables in a meta string |
GET | /action/logs/paginate | LV2 | Get executed action logs (paginated) |
Tags
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /tags/workspace/:workspace | LV1 | Get workspace tags |
POST | /tags/workspace/:workspace | LV1 | Create a tag |
DELETE | /tags/workspace/:workspace/:tagId | LV1 | Delete a tag (soft-delete) |
Validities
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /validity/workspace/:workspace | LV2 | Get workspace validities |
POST | /validity/workspace/:workspace | LV2 | Create a validity |
PATCH | /validity/workspace/:workspace/:validityId | LV2 | Update a validity |
DELETE | /validity/workspace/:workspace/:validityId | LV2 | Delete a validity |
Auth Levels
| Level | Purpose |
|---|---|
| LV1 | Basic read/write access (workspace resources, tags) |
| LV2 | Standard workspace operations (rules, rule groups, actions, validities) |
| LV3 | Dry-run operations |
| LV4 | Cron expression testing |
| LV5 | State querying |
Action Execution Logging
Every action execution is recorded in the executed_actions table:
| Field | Description |
|---|---|
ruleGpId | Rule group ID |
ruleId | Rule ID |
ruleTriggerState | Trigger state value |
ruleTargetState | Target state value |
ruleTriggerType | Trigger type at execution |
ruleConditionType | Condition type at execution |
ruleConditions | Conditions that were matched |
actionType | Type of action executed |
actionSeqNum | Sequence number |
actionMeta | Action meta at execution time |
triggerData | Triggering payload data |
executionResult | Serialized execution result |
success | Whether execution succeeded |
errorMessage | Error details (if failed) |
deviceId | Device ID |
deviceType | Device type |
executedAt | Execution timestamp |
View logs via GET /rule/v1/action/logs/paginate.