Skip to main content

Workflows Guide

Workflows automate actions in response to events. When tags are read by RFID readers and processed into scan events, workflows check their conditions and execute actions like sending notifications, moving inventory, updating custom fields, or calling external systems.

Overview​

flowchart LR
A[Scan Event] --> B[Workflow Queue]
B --> C[Workflow Engine]
C --> D{FROM: device matches?}
D -->|No| F[Skip, nothing recorded]
D -->|Yes| E{FOR: any tag matches?}
E -->|No tag matches| G[Record: no matching tags]
E -->|Tags match| H[Execute Actions]
H --> I[Execution Record]

A workflow's Conditions card reads top to bottom as one rule, WHEN, FROM, FOR, THEN, followed by the Actions card:

ClausePurpose
WHENWhat starts the workflow. Today: a scan event arrives, which fires when a scan session closes on a device
FROMWhether the workflow runs for this event at all: any device, or a device matching conditions on device, group, type and scope. A miss records nothing
FORWhich of the event's tags the actions apply to
THENPasses the matching tags, or all of them, to the actions below

FROM and FOR behave differently when they do not match, and that difference is deliberate. When FROM is not met, the workflow simply is not a candidate for that event: nothing is recorded, so a workflow written for yard portals leaves no trace on every stacker read fleet-wide. When FROM is met but no tag matches FOR, an execution is recorded with the status NoMatchingTags and a snapshot of the event, so you can see what arrived and why nothing happened.

Managing Workflows​

Every workflow has its own page at a stable, shareable URL. From the Workflows list, click a row (or choose Details from the row actions menu) to open a workflow's detail page. The detail page has Overview and Analytics tabs, plus a Change history tab for users with the View Audit Logs permission (see Change History), and its header carries an Actions menu (Edit, Copy, the Enable/Disable toggle, and Delete, plus Move to Shared for administrators on a workflow from before the beta) plus a Back to Workflows button.

The Overview tab mirrors the edit form's sections: Basics, Conditions (WHEN, FROM, and FOR, with ids shown as names), and Actions (each action row shows its type, a chip for its own FROM devices when set, its tag condition count, run condition, and the result of its last execution), plus an audit section. Above the sections, two cards sum up its activity: Runs (the last 7 days, with a sparkline) opens the Runs tab filtered to this workflow, and Last run opens the most recent run (it reads Never until the workflow first runs). The Analytics tab charts runs and action results under one shared time range.

Permissions​

PermissionWhat It Allows
View WorkflowsOpen the Workflows page: the list, the run order views, every workflow's detail page, and Runs
Manage WorkflowsCreate, edit, copy, enable, disable, and delete workflows (and message templates)

Workflows are managed by administrators. For the beta, Manage Workflows is held by the Admin role only: the built-in Contributor role sees workflows, the run order, and runs, but cannot change them. A custom role can hold Manage Workflows, and can create workflows only when it can write the shared scope. Changing the run order, Move to Shared, and the Diagnostics tab are administrator actions regardless of permissions. See Users, Roles & Access Scopes.

Creating a Workflow​

Choose Workflow from the Add menu in the page header to open the create page. Every new workflow is Shared: it belongs to your organization rather than to one site, so all workflows share one run order and one workflow can serve readers at every site. There is no scope to choose. To limit a workflow to one site's readers, give it a FROM condition on Device Scope (see FROM: which devices).

Fill in Basics (name and description), Conditions (WHEN the event, FROM which devices, FOR which tags), and Actions, using the section rail on the left to jump between them and see which sections still need attention.

When you click Save on a new or copied workflow, Tagnet asks "Enable workflow?": enabling starts it processing events immediately, or you can choose Keep disabled to review it first and turn it on later from the workflow's page. Editing an existing workflow never touches its enabled state; use the Enable/Disable action for that.

Copying a Workflow​

Choose Copy from the list row menu or the detail page's Actions menu to create a new workflow seeded from an existing one (/workflows/new?copyFrom={id}). All actions are duplicated with fresh internal identifiers, and any action that referenced another action (for a run condition or a template body) is remapped to point at its counterpart in the copy. The copy opens on the create page, ready to rename and save; it goes through the same Enable now / Keep disabled prompt as any other new workflow.

Workflows From Before the Beta (Admins)​

A workflow created at a site in an earlier release keeps running exactly as it did, for that site's devices only, and its detail page carries a note saying which site it belongs to. It takes part in the run order like any other workflow. Administrators can move it into the shared scope with Move to Shared, from the list row menu or the detail page's Actions menu. The move keeps the workflow's reach: Tagnet adds the event condition Device scope is {site} (replacing any device when that was the choice), so the workflow still runs for the same readers rather than for every site. Its other conditions and its actions stay as they are. Copying a site workflow creates a Shared copy with the same condition added. A workflow cannot be moved into a site.

Conditions​

Every workflow's Conditions card reads as one rule, from top to bottom: WHEN an event arrives, FROM which devices, FOR which tags, THEN the matching tags go to the actions below. Wherever the card asks for condition rows, a row is a field, an operator, and a value; the operator reads as a word (is one of, is not, contains, and so on, see Operators below), and rows within a clause are joined by a lowercase italic and, so all rows must match. is one of and is not one of are the any-of forms within one row: a device condition naming three devices matches an event from any of them.

WHEN: the event​

The WHEN clause names what starts the workflow. There is one choice today, a scan event arrives, which fires when a scan session closes on a device and carries the tags that session read. The event decides which clauses and which actions the editor offers: a future event that carries no tags (an alert, a schedule) will offer FROM only and just the actions that work without tags.

FROM: which devices​

The FROM clause is the gate on what executes at all. It is checked once per scan event, before anything is recorded. If it is not met, the workflow is not a candidate for that event and no execution is written. The choice is explicit; a workflow will not save until you make it:

  • any device (or any device in {site} on a site workflow): every scan event the workflow's scope admits, including devices added later. A workflow's own scope bounds which devices it can run for, not the other way around: a shared workflow runs for any device in the fleet, a site-scoped workflow only for that site's devices.
  • a device where…: at least one condition row is required. With none, Tagnet warns "Add at least one condition, or choose any device," and the workflow would never run.

The fields, all referenced by id, so renaming a device, group, type or scope never breaks a workflow:

FieldMatches whenNotes
DeviceThe triggering device is (any of) the selected devicesName a few readers directly. For a large set, name their group or type instead: one row holds about fifty devices
Device GroupThe triggering device belongs to (any of) the selected groupsDevices may join or leave a named group freely; the condition follows the group, which is the point of naming it. An ungrouped device matches only is not and is not one of
Device TypeThe triggering device's type is (any of) the selected typesA type defined in the shared scope lets one shared workflow say "yard portals" without naming a group at each site. An untyped device has no type: is and is one of never match it, is not and is not one of do
Device ScopeThe triggering device belongs to (any of) the selected scopesLets a shared workflow run for one site's devices, or several sites'

A device, group or type that a workflow, or one of its actions (see Run Conditions below), names in a FROM condition cannot be deleted; remove it from the workflow first.

flowchart TD
A[Scan Event from Device X] --> B{Workflow scope admits Device X's site?}
B -->|No| F[Not a candidate]
B -->|Yes| C{Any device, or a device where...?}
C -->|Any device| G[Candidate: evaluate FOR]
C -->|A device where...| D{Every FROM row matches Device X?}
D -->|Yes| G
D -->|No, or no rows| F

Note: There is no "Disabled" option here. To pause a workflow without deleting its configuration, use the workflow's own Enable/Disable action instead of narrowing FROM to nothing.

FOR: which tags​

The FOR clause selects which tags from a scan event the actions apply to. With every tag in the event, every tag is included. With only the tags where…, every condition row must match for a tag to be included. When FROM is met but no tag matches FOR, the execution is recorded as NoMatchingTags.

FOR exists at two levels:

  • Workflow FOR applies to all actions in the workflow
  • Action FOR (the action dialog's own FOR clause, see Run Conditions below) further narrows the tags for that one action

Workflow FOR runs once, when the workflow first evaluates the scan event, and doesn't change again during that execution. Action FOR runs fresh before each action and evaluates current data: if an earlier action in the same run mapped a tag, moved an inventory item, or updated a custom field, an action's FOR condition on a later action sees that change. This is what makes a workflow like "map unmapped tags, then only notify about tags now assigned to a particular item type" possible, since the notification's condition depends on what the mapping action just did.

THEN​

THEN is read-only. It names what happens to the result of FOR: "pass the matching tags to the actions below" when FOR narrows the tags, or "pass all the event's tags to the actions below" when every tag is included. The Actions card runs in order against whichever tags THEN names.

Tag Condition Fields​

Tag conditions can target tag data, inventory item properties, location data, and custom fields:

Field PathDescription
Tag.IsMappedWhether the tag is linked to an inventory item
Tag.MotionIndicatorMotion status: InMotion, Stationary, SlightMovement, Unknown
Tag.EpcThe tag's EPC identifier
Tag.ReadCountNumber of times the tag was read
Tag.AntennaCountNumber of antennas that detected the tag
Tag.PrimaryAntennaAntenna number of the strongest read
Tag.DwellTimeMsHow long the tag was observed (milliseconds)
Tag.ReadRateReads per second
Tag.PeakRssiStrongest signal strength
Tag.StatusRead signature match status: Match, Mismatch, TooFewReads (shown as Match status)
Tag.MismatchScoreHow far the tag strayed from its read signature (shown as Mismatch score)
Tag.StateZebra ATR7000 only: the state of the tag's latest directionality event, NEW, TRANSITION, TIMED_OUT or UPDATE (shown as Directionality state). Empty for other readers. See Moving inventory through a doorway
Tag.DirectionZebra ATR7000 only: IN, OUT, NONE, UNKNOWN or ERROR, set when the latest event is a time-out
Tag.ZoneZebra ATR7000 only: the zone number of the tag's latest event
Tag.ZoneNameZebra ATR7000 only: the zone name of the tag's latest event
InventoryItem.InstanceIdInventory item instance identifier
InventoryItem.DescriptionInventory item description
InventoryItem.QuantityItem quantity
InventoryItem.StateLifecycle state: New, Active, Closed
InventoryItem.Item.ItemIdCatalog item identifier
InventoryItem.Item.DescriptionCatalog item description
InventoryItem.Item.ItemType.NameItem type name. The picker offers your configured item types
InventoryItem.CurrentLocation.NameCurrent location name
InventoryItem.CurrentLocation.LocationType.NameLocation type name. The picker offers your configured location types
InventoryItem.CurrentLocation.LevelCurrent location's hierarchy level
InventoryItem.CurrentLocation.Parent.NameName of the location that contains the item's current location, for example the yard that holds a Yard or Shipped location. The picker offers your locations. Empty when the current location is at the top of the tree
InventoryItem.CurrentLocation.Parent.CodeCode of that containing location
InventoryItem.CurrentLocation.WithinReadPointWithin read point: true when the item is at the read point location of the triggering device (or its device group, or for a Zebra ATR7000 the tag's zone) or anywhere below it. An unmapped tag, an item with no location, or a device with no read point location is false
CustomField:{FieldKey}Custom field value, keyed by the field's field key

Within read point at the workflow level. As a workflow FOR condition it tests the item's location when the tag enters the workflow; an action FOR condition tests it again after earlier actions (for example a Move Inventory action) have moved the item. If the triggering device and its group have no location, no tag is within: an is true condition matches nothing and the execution is recorded as NoMatchingTags. Be careful with a doorway or portal workflow that has a Leaving action filtered on within and an Arriving action as the fall-through: a workflow FOR condition of Within read point is true removes every arriving tag before the actions run, so the Arriving action never fires. Keep that condition on the Leaving action instead.

Movement Result Fields​

An action's FOR clause can also read what an earlier Execute Movement Rules action decided for each tag. These fields appear in the Movement group of the field picker and are only offered on an action's own FOR clause, since the workflow FOR clause runs before any action.

Field PathDescription
Movement.StatusThe tag's outcome: Moved, NoMatch, Skipped, Error, or AlreadyHandled (a Move Inventory action earlier in the workflow already decided the tag)
Movement.MatchedRuleNameName of the movement rule that matched. The picker offers your configured rules
Movement.SourceWhat decided the outcome: Rule, Action (a Move Inventory action), or None. Older results may show DeviceDefault, from when a device's location was a fallback destination for unmatched tags; it is a read point now and no longer moves anything on its own
Movement.TransactionTypeCodeCode of the transaction type the move wrote, for example RECEIVE, SHIP, or CONSUME. The picker offers your configured transaction types. Empty when nothing was written
Movement.TransactionTypeNameDisplay name of that transaction type
Movement.ScopeTransferredtrue when the move also transferred the item to the destination's scope under the Cross-Scope Transfer policy. Route a notification or integration on it to be told about transfers
Movement.FromLocationNameWhere the item was before the move
Movement.FromLocationCodeThe origin location's code
Movement.ToLocationNameWhere the item was moved to
Movement.ToLocationCodeThe destination location's code

The fields read the results of the nearest movement action (Execute Movement Rules, or Move Inventory where it is enabled) above the conditioned action that decided each tag. A workflow with one movement action needs no setup; with several, each tag follows the movement action just above it that actually decided it. A movement action that was skipped, whether disabled with a Never run condition or because its own tag conditions matched nothing, is passed over rather than hiding the one above it, and so is a row that only says an earlier Move Inventory action already handled the tag.

A tag with no movement result never passes a Movement condition, whatever the operator. That covers a workflow with no movement action above and a tag that none of the movement actions above evaluated, because their tag conditions excluded it. So a NotEquals or NotIn route cannot accidentally send tags that were never evaluated. When that is the reason an action was skipped, the execution history says so. With several movement actions above, a tag follows the nearest one that evaluated it: two Move Inventory actions conditioned on different item types feed one route below them, and a route that should only see the nearer action's tags repeats that action's condition.

A tag the movement action evaluated but did not move (NoMatch, Skipped, or Error) has a result whose transaction type and destination are empty, and an empty value on such a row never passes a condition either, whatever the operator. A route written as Movement.TransactionTypeCode NotEquals SHIP receives the tags that moved with some other type and nothing else. Only a tag that actually moved can satisfy a negative route on a field it legitimately leaves empty: a device-default move has no rule name, and a close-out has no destination, so Movement.MatchedRuleName NotEquals and Movement.ToLocationCode NotEquals still match those. To route on the unmoved tags themselves, use Movement.Status instead.

The field picker only offers Movement fields on actions that come after an Execute Movement Rules action; reorder the actions first if the group is missing. If an action with Movement conditions is later dragged above the movement action, or the movement action is deleted or disabled with a Never run condition, the action row shows No movement action above and the workflow cannot be saved until the order is fixed, the movement action is enabled, or the conditions are removed.

This is what makes per-route integrations one action each. A shipment that should reach a shipping system is a Send HTTP Integration action with one tag condition, Movement.TransactionTypeCode Equals SHIP; the action's filtered_tags is exactly the set to send, and when no tag matches the action is skipped. The move declares what kind of movement it was through the transaction type it writes, so the integration subscribes to that meaning rather than to a from/to location matrix. Routing by Movement.MatchedRuleName works the same way when several rules write the same transaction type and only one of them should reach the integration. The location fields are there for the exception, such as a move from YARD to INTRANS that needs different handling from every other shipment: Movement.FromLocationCode Equals YARD and Movement.ToLocationCode Equals INTRANS.

Operators​

The editor shows each operator as a word, so a row reads as a sentence, for example "Device Group is one of Dock doors." The stored value behind it is unchanged:

OperatorShown asDescription
EqualsisExact match
NotEqualsis notDoes not match
Inis one ofMatches any value in a comma-separated list
NotInis not one ofDoes not match any value in a comma-separated list
GreaterThanis more thanNumeric or date comparison
LessThanis less thanNumeric or date comparison
GreaterThanOrEqualis at leastNumeric or date comparison
LessThanOrEqualis at mostNumeric or date comparison
ContainscontainsSubstring match (case-insensitive)
StartsWithstarts withPrefix match (case-insensitive)
EndsWithends withSuffix match (case-insensitive)

String comparisons are always case-insensitive. For date fields, dynamic tokens are supported: {{today}}, {{today-30d}}, {{today+7d}}.

Actions​

Actions define what happens when a workflow's conditions are met for a scan event. Actions execute sequentially in the configured order, and each action can pass data to subsequent actions through the execution context.

A workflow with no actions can still be saved and enabled. It runs for every event that matches its conditions and records an execution, but nothing else happens, which is a way to see which events a set of conditions matches before adding actions. Every Enable prompt says so when the workflow has no actions.

On the edit page, drag an action's row to reorder it. If another action's run condition depends on it, Tagnet blocks the drop and explains why: a dependent action can never be moved ahead of the action it depends on. Use Duplicate from an action's row menu to insert a copy directly after it, useful for building several similar notifications or HTTP calls without starting from scratch each time.

Action Types​

Notification​

Sends an in-app notification with a templated title and body.

  • Target types: Broadcast (all users), Scope (users in specific access scopes, optionally narrowed to users who hold selected roles), or User (specific users you pick)
  • Priority: Low, Normal, High, or Critical
  • Templates: Scriban templates with access to scan event data, variables, and previous action outputs
  • Body source: Write a template directly, use the output from a previous action (e.g., a RenderTemplate result), or link a shared Message Template

Update Live Reads​

Sends each matching tag's workflow result to the Live Reads tab of the Devices page in real time: the inventory item, its location, lifecycle state and item type. The update replaces the tag's row if it is already showing, or adds a row if it is not. Anyone watching can set Event Source to Workflow in the Live Reads settings to hide raw scans and see only these updates. Earlier versions called this action Broadcast to Event Viewer; actions saved under that default name keep it until you rename them.

Render Template​

Renders a Scriban template against the workflow execution context and stores the output in a variable for downstream actions. This is a preparatory action: it produces data but does not perform external work on its own.

Use this to format data for a notification body, HTTP request payload, or any action that needs pre-formatted content.

Move Inventory​

Moves each matching tag's item to one place and records the move as an inventory transaction. The action's tag conditions say which tags it applies to; the Target says where their items go.

TargetDestinationUse it for
Read point's locationThe location set on the triggering device, or on its device group when the device has none. For a Zebra ATR7000, the location linked to the zone the tag was last seen in comes firstA reader that stands in one place: a workstation, a cabinet, a shelf. Seen here means it is here. Tags from a device with no location are skipped, and the execution says so
Location by code in the device's scopeThe location whose Code matches the code you enter, looked up in the scope the triggering device belongs toOne shared workflow that resolves the same code to each scope's own location (every scope has a RECEIVING, and each device sends items to its own). Tags from a device in the shared scope are skipped; a code that does not exist in the device's scope is an error for that tag
Specific locationAlways the location you pick, whichever device triggeredA fixed destination such as a transit or quarantine location
Sibling location by typeThe location of the type you pick that has the same parent as the item's current location: an item in 1A1 Yard goes to 1A1 ShippedSites with several yards that share one layout, so one action keeps each item under its own yard. See Sibling location by type below
Remove from inventoryNo location. The item is closed out of inventoryShipping docks and consumption points

The controls under the target:

  • Location code (location by code only): the Code set on the location, not its name. The same code must exist in every scope whose devices trigger the workflow.
  • Location (specific location only): search by name; the parent is shown so same-named locations can be told apart.
  • Location type (sibling location by type only): the type of the location to move to, for example Shipped. A shared workflow offers every location type; a site workflow offers its own site's types and the shared ones.
  • Transaction type (required): what kind of movement this is. Every moved item gets a transaction of this type, and downstream actions can route on it with the Movement.TransactionTypeCode condition (see Movement Result Fields), so pick the type for its business meaning: Receive at an arrival point, Transfer at a departure point. For Remove from inventory, only types whose lifecycle effect closes the item are offered.

Two rules are built in. An item already at the target is left alone and still counts as handled. A tag one Move Inventory action handled is skipped by every later Move Inventory action in the same execution, so a Leaving action followed by an Arriving action never ping-pongs: put the actions in order and let their tag conditions decide. A move into a location owned by another scope is decided by the Cross-Scope Transfer policy: in Reject mode the tag is skipped and an alert is raised; in Transfer mode the item moves and its ownership follows it.

Sibling location by type​

The destination is worked out for each item from where that item is now, so one action serves every yard: an item in 1A1 Yard goes to 1A1 Shipped, and an item in 1A2 Yard goes to 1A2 Shipped. Tagnet looks at the item's current location, goes up one level to its parent (the yard, 1A1), and looks for a location of the chosen type directly under that parent.

The item is...Result in the execution historyCounts as handled?
Under a parent with exactly one location of the typeMoved to that location, with a transaction of the action's typeYes
Already in a location of the type (for example already in 1A1 Shipped)Skipped: Already at 1A1 Shipped. Nothing is writtenYes
In a location with no parent (a top-level location)Skipped: Item's current location has no parent, so it has no siblingsNo
Not in any locationSkipped: Item has no current location, so it has no siblingsNo
Under a parent with no location of the type (for example 1A3 has a Yard but no Shipped)Skipped: No sibling of type Shipped under 1A3No
Under a parent with two or more locations of the typeError: 2 sibling locations of type Shipped under 1A1. The item does not move; fix the locations so each yard has oneYes

"Counts as handled" means later Move Inventory actions in the same workflow skip the tag. A tag that is not handled can still be moved by a later action, which is how a portal's Arriving action picks up items the Leaving action could not place. The ambiguous case counts as handled on purpose: an item leaving through the gate should be flagged, not moved back into a yard by the fall-through action.

Only the location type matters, not the name, so yards can be named anything. The sibling can sit in the same scope as the item or another one; a move into another scope is decided by the Cross-Scope Transfer policy like any other target. A sibling whose Inventory is set to Not Allowed is skipped with a message saying so.

Recipe: a site portal with several yards. Each yard (for example 1A1) holds a Yard location and a Shipped location, and the portal reader's location is the site root. Two actions, in this order:

  1. Leaving: tag condition Within read point = true and nothing else, target Sibling location by type with Shipped. An item in 1A1 Yard moves to 1A1 Shipped, keeping 1A1 as its parent.
  2. Arriving: no tag conditions (it takes whatever Leaving did not handle), target Location by code in the device's scope or Specific location for this site's arrival yard.

Do not add a Location Type = Yard condition to Leaving. An item already in 1A1 Shipped that is read again at its own portal would fail that condition, fall through to Arriving, and be moved back into a yard. Without it, the sibling target sees the item is already in a Shipped location and leaves it alone.

Warning: The Within read point condition is required on the Leaving action. Without it, an item from another site read at this portal resolves to its own site's Shipped location, counts as already there, and is marked handled, so the Arriving action never sees it and the item silently never arrives.

Execute Movement Rules​

Deprecated. Evaluates configured movement rules against the matching tags and moves inventory items to their resolved destinations. Rules are evaluated in sequence order. Replaced by Move Inventory; see Converting rules to Move Inventory. Existing rules keep running until the feature is removed in a later release.

Later actions in the same workflow see the new location: a condition or template that reads location data afterward reflects where the item ended up, not where it was when the workflow triggered.

Update Custom Fields​

Updates custom field values on inventory items associated with matching tags.

Later actions in the same workflow see the updated values: a condition or template that reads the field afterward reflects the new value, not the one captured when the workflow triggered.

Available operations:

OperationDescription
SetSet to a specific value
ClearRemove the value
ToggleInvert a boolean value
SetToNowSet to the current UTC timestamp
IncrementAdd a numeric value
DecrementSubtract a numeric value
OffsetFromNowSet to a date offset from now (configurable days)

Send HTTP Request​

Sends an HTTP request to an external endpoint, waits for the reply, and makes the response available to later actions.

  • Endpoint: pick an integration endpoint. It supplies the URL, method, headers, body and content type, all versioned, so the contract with the external system lives in one place instead of inside the workflow. Actions created before endpoints existed keep their own URL, authentication, headers and body, and offer a one-click conversion; see Converting an existing action.
  • Authentication: comes from the endpoint's Connection Profile: none, an API key header, Basic auth, a static bearer token, or a token endpoint with automatic caching and refresh, plus any secret headers the profile carries. There is no inline credential option on a new action; a system that needs no credentials uses a profile with authentication None.
  • Retry: Configurable retry count with backoff: up to 5 retries after the initial attempt, so a single action can send the request up to 6 times (7 when a Token Endpoint profile performs its one automatic token-refresh retry). Only transient failures are retried: timeouts, network errors, and HTTP 408, 429, or 5xx responses. Other statuses, including ordinary 4xx errors, fail immediately without retry. When a transient response includes a Retry-After header, most commonly on a 429 or 503, Tagnet honors it for the next attempt's delay (capped at 60 seconds); otherwise the wait grows by about 2 seconds with each attempt. A retried request can reach the receiving system twice if the first attempt arrived but its response was lost, so endpoints that must not process duplicates should deduplicate on a field in the request body. Every attempt is recorded in the execution's output data (time, duration, outcome, and the wait before the next attempt), so the execution detail shows exactly what happened and when.
  • Timeout: Configurable per-attempt timeout. With retries enabled the total time can be several times the configured value; the action always gives up after 10 minutes regardless of settings.
  • Shared host limits: Requests to the same host, across every workflow that calls it, share a limited number of concurrent slots and a circuit breaker, set by the Integration / Throttle policy on the Policies tab of the System page. If a host fails repeatedly with timeouts or server errors, Tagnet briefly stops sending it new requests so one failing integration can't starve the others. Execution history reports the specific reason: circuit breaker open (the host has been failing and is cooling down), timed out waiting for a per-host request slot (too many concurrent requests to that host right now), or invalid URL. Ordinary 4xx responses never trip the circuit breaker, so a single misconfigured workflow calling the wrong endpoint won't block other workflows that call the same host correctly. See Policies to adjust the concurrency limit, failure threshold, or cooldown.

Note: If Tagnet restarts while a Send HTTP Request action is in progress, such as during a deployment, the action stops immediately. When an execution record is written it explains that the request was cancelled because the application was shutting down, but a restart can also interrupt the record itself from being saved, so a delivery attempted right at shutdown may leave no execution record at all. Either way this is expected and does not indicate a problem with the destination endpoint.

Retry count and timeout stay on the action even though the request itself comes from the endpoint. They describe how hard this particular call tries, not what the operation is, so two workflows can call the same endpoint with different patience. Actions store the endpoint by id, so renaming the endpoint or its profile later never breaks the action.

Tip: This action calls its endpoint inline and waits for the reply, so a later action can use the response, but it fails if the endpoint is unreachable. If you're posting an event to a system like an ERP or WMS and want Tagnet to keep retrying for hours rather than fail the workflow, use its sibling action, HTTP Integration (durable), instead.

Important: Workflows run one after another for a reader (see Workflow Run Order), so a Send HTTP Request step holds that reader's processing until the call returns: a timeout of up to 300 seconds, plus retries. The workflow editor shows a note on any workflow that contains this step. Use HTTP Integration (durable) unless the receiving system needs the call in real time, such as a PLC that must answer before the next step.

HTTP Integration (durable)​

Hands an HTTP request to the Integration Outbox for durable, automatically retried delivery, and continues immediately rather than waiting for a reply.

  • Endpoint: pick an integration endpoint. It supplies the URL, method, headers, body and content type, all versioned, so the contract with the external system lives in one place instead of inside the workflow. Actions created before endpoints existed keep their own configuration and offer a one-click conversion.
  • Authentication: comes from the endpoint's Connection Profile. There is no inline credential option, and no free-standing "no authentication" choice either: use a profile with authentication None for a system that needs no credentials. See Why a connection profile is required for the reasoning.
  • Retry and timeout: not configured on the action. They come from the Integration / Outbox policy, shared by every durable action in your system. See Policies.

This action's status is Queued, not Success, when it completes: the request was accepted for delivery, not necessarily delivered yet. This matters most for run conditions on later actions; see Run Conditions below and the full Integration Outbox guide for delivery behavior, retries, and current limitations.

Map Unmapped Tags​

Automatically creates inventory items for tags that are not yet linked to inventory. Creates the inventory item record, links the RFID tag, and places it at a specified location using a selected transaction type. Close-out transaction types are not available in this action because mapping creates a new item and brings it into inventory rather than removing it.

Later actions in the same workflow see the tag as mapped: a condition or template that checks Tag.IsMapped afterward reflects the new mapping. If a tag was already mapped by an earlier action in the same run, such as another Map Unmapped Tags action ahead of this one, this action treats it as already mapped and skips it rather than mapping it again. See Pending Mappings for how this affects deferred mapping.

Run Conditions​

Each action has its own Conditions section in its dialog, laid out as three clauses: RUN, FROM, and FOR. RUN and FROM gate whether the action runs at all; FOR picks which tags it runs on.

RUN​

RUN controls whether the action executes based on the outcome of an earlier action:

ChoiceBehavior
every timeRun regardless of any other action's outcome
only if "X" succeedsOnly run if action X completed with effect
only if "X" failsOnly run if action X failed
only if "X" has nothing to doOnly run if action X completed without error but had no effect
never (turned off)Skip this action (useful for temporarily disabling)

The dependency is part of the RUN choice itself: there is no separate Depends On picker. Picking "only if 'Map unmapped tags' succeeds" names the dependency and the condition together, with an option offered for every earlier action, nearest first. By default, before you choose otherwise, an action follows "the action just before it"; if you later reorder actions, one still on that default follows whichever action is now above it.

Important: If the dependency is an HTTP Integration (durable) action, "succeeds" and "fails" here see only whether the request was queued, not whether it was actually delivered. "Succeeds" fires as soon as the request is accepted, which happens almost immediately. "Fails" fires only if the request could not be queued at all; it will not fire because the receiving system was down or rejected the delivery. See the Integration Outbox guide for the full explanation.

flowchart TD
A[Action 1: Execute Movement Rules] --> B{Result?}
B -->|Succeeds| C["Action 2: Send Notification - RUN: only if Action 1 succeeds"]
B -->|Fails| D["Action 3: Send Alert - RUN: only if Action 1 fails"]
A --> E["Action 4: Update Custom Fields - RUN: every time"]

FROM: limiting an action to specific devices​

An action's FROM clause narrows it to specific devices within the workflow it already runs for. It offers the same choice as the workflow's own FROM: which devices: the workflow's devices (the default, and how every action behaved before this clause existed) or a device where…, with condition rows on Device, Device Group, Device Type, and Device Scope, using the same fields and operators. The values offered are limited to the workflow's own scope.

Use it when one workflow already covers a wide surface but a single action should only fire for part of it: a workflow that runs for every yard portal can have one Notification action set to a device where Device is one of Dock Door 3, while every other action stays on the workflow's devices.

When the triggering device does not match an action's FROM, the action is recorded as Skipped with the message "Skipped: event condition not met," and its FOR clause is never evaluated. The execution itself is still recorded, since the workflow ran; only that one action was skipped. An action after it set to every time still runs; an action set to only if "X" has nothing to do, where X is the skipped action, does not run, since a skipped action is not "has nothing to do."

A device, group or type named in an action's FROM rows cannot be deleted, the same delete guard that applies to the workflow's own FROM.

FOR: an action's own tag conditions​

An action's FOR clause works like the workflow's FOR: which tags: every tag passed to the actions (the default) or only the tags where…, with its own condition rows. It is evaluated fresh, against current data, immediately before the action runs, which is why it is the only place Movement Result Fields are offered: they read what an earlier action in the same run just decided.

Execution Context​

Actions share data through the execution context. Each completed action adds its output to the context, making it available to subsequent actions. The context also tracks the current state of tag and inventory data: after any action that can change data, such as Move Inventory, Update Custom Fields, or Map Unmapped Tags, runs, Tagnet re-reads the tags and inventory items it touched before the next action starts (Notification, Update Live Reads, Render Template, and the HTTP send actions never trigger this, and neither does the last action in the workflow), so that action's tag conditions and templates see the result instead of the data as it looked when the workflow triggered.

For example:

  1. A Send HTTP Request action calls a lookup endpoint on an external system
  2. A Render Template action formats the HTTP response together with scan event data and stores it as a variable
  3. A Notification action uses that variable as its body to notify users of the result

Give an action a name so a later action can reference its specific output (for a run condition dependency or a template variable); an unnamed action is referenced by its position instead. Names are normalized when you save a workflow: invisible characters that rich text editors like Word or Outlook can insert on paste, such as non-breaking spaces, are converted to plain spaces or stripped, so a pasted name always matches what you see on screen.

Working with Templates​

Notification and Render Template actions accept a template for their content, with two sources to choose from. The two HTTP actions send whatever body their integration endpoint defines, so the choice below applies to them only for actions configured before endpoints existed, which keep their own body until they are converted.

  • Inline Template: write the Scriban template directly in the action. The editor includes a Starters panel (starting-point templates you can apply and modify), a Variables panel (search or browse by group, then click a variable to insert it at the cursor), and a Preview panel that re-renders as you type.
  • Shared Template: link a template managed on the Message Templates page. The action always uses the template's current version at execution time, so editing the shared template updates every action that references it without touching the workflow.

Variables cover the scan event, its tags, mapped inventory items (including tag.inventory.location.code, the location's short code rather than its display name), catalog items, and any custom fields defined on your item types.

Preview sample data uses your organization's actual custom field keys and declared types, so a template written against your own schema resolves in preview instead of rendering blank; see Message Templates for how the preview shapes sample values and reports paths that found nothing.

Custom Field Values in Templates​

A custom field's value reaches a template as the type its field declares, not as text. A Number, Currency, or Percentage field renders as a bare number (19.99, no quotes needed, no currency symbol or % sign), a Boolean renders as true or false, and a Date or Date & Time field renders as a real timestamp you can pipe through date.to_string, msjson_date, or epoch_ms like any other date variable (see Date Formatting below). String, Color, and Select fields render as text.

This matters most for JSON bodies. A line like "unit_cost": {{ filtered_tags[0].inventory.custom_fields.unit_cost }} produces valid JSON only because the value renders unquoted; wrapping it in quotes in the template would incorrectly quote a value that is already a number.

Current Data vs Trigger Data​

Templates see two different views of tag and inventory data:

  • filtered_tags reflects current state at the moment the template renders, including any changes made by earlier actions in the same run. If a Move Inventory, Execute Movement Rules, or Update Custom Fields action ran first, filtered_tags already shows the new location or field value.
  • source_event is a fixed snapshot of the data as it looked when this workflow started. It never changes during the run, no matter what later actions do. This is also what the Source Data tab shows in execution history.

Both views include what the workflows above this one in the run order did. A tag mapped, an item moved, or a field updated by an earlier workflow for the same scan event is already in that state when the next workflow starts: its FOR conditions, its source_event, its action conditions, and its templates all agree on it. Only the scan record itself stays as the reader saw it, which is why an execution's Tags tab can show a tag as unmapped while its Source Data shows the item an earlier workflow mapped it to.

Use filtered_tags for anything that should reflect the outcome of the workflow so far, such as reporting where an item ended up after a move. Use source_event when you specifically need the data as the workflow started, such as recording where an item was before this workflow moved it.

Movement Results in Templates​

When an Execute Movement Rules action runs earlier in the workflow, each entry in filtered_tags carries that tag's result as tag.movement, so a body can write the movement delta directly instead of searching the action's output for the matching EPC:

VariableDescription
tag.movement.statusMoved, NoMatch, Skipped, Error, or AlreadyHandled
tag.movement.sourceRule, Action, or None
tag.movement.ruleName of the rule that matched (null for a Move Inventory action)
tag.movement.scope_transferredtrue when the move also transferred the item to the destination's scope
tag.movement.from.name, .code, .idWhere the item was before the move (null when it had no location)
tag.movement.to.name, .code, .idWhere it was moved to (null for a close-out)
tag.movement.transaction_idThe inventory transaction the move wrote, for a reference key in the payload
tag.movement.transaction_type.code, .nameThe transaction type the move wrote (RECEIVE, SHIP, CONSUME), so the payload carries what kind of movement it was (null when nothing was written)
tag.movement.correlation_idShared by every transaction the movement action wrote in that run
tag.movement.messageThe human-readable result message

tag.movement is null when no movement action ran above the template's action or the tag did not reach it, so use the null-safe form, for example {{ tag.movement?.to?.code ?? '' }}. It follows the same nearest-movement-action rule as the Movement filter fields and is listed under Filtered Tags in the Variables panel. The Inventory Movements starter templates use it.

Direction and Zone in Templates​

A tag read by a Zebra ATR7000 carries its latest directionality event, so a notification or integration that follows a doorway move can say which way the item went and where the reader last saw it:

VariableDescription
tag.zoneThe zone number of the tag's latest event, 1 to 6
tag.zone_nameThe zone's name as deployed, for example SOUTH
tag.directionIN, OUT, NONE, UNKNOWN or ERROR. Only a timed-out event has one
tag.directionality_stateNEW, TRANSITION, TIMED_OUT or UPDATE

The same four are on each source_event.tags entry, and the Variables panel lists them under both Filtered Tags and Source Event. They are empty for tags from any other reader. Inside quotes an empty value renders as an empty string, but tag.zone is a number and renders unquoted, so guard it in a JSON body, for example "zone": {{ tag.zone ?? 'null' }}.

Tip: The Full Payload Dump - JSON starter template, in the editor's Starters panel, dumps everything available to templates and tag conditions as JSON, using Scriban's object.to_json. Apply it to see the exact field names and shape of workflow, scan_event, and filtered_tags for your own data, which is useful when you're not sure what a variable is called or whether a field is populated.

Date Formatting​

Date and time variables (for example scan_event.end_time) open a dropdown instead of inserting directly, since a raw date rarely matches what the receiving system expects:

FormatWhat it doesExample
Default (ISO 8601)Inserts the variable with no formatting filter. This is what a timestamp renders as on its own2026-09-08T14:45:00Z
Date onlyThe date.to_string '%Y-%m-%d' filter, for a target that wants a calendar date without a time2026-09-08
FriendlyThe date.to_string '%d %b %Y' filter, for a notification someone reads08 Sep 2026
Friendly with timeThe date.to_string '%d %b %Y at %I:%M %p' filter08 Sep 2026 at 02:45 PM
Microsoft JSON dateThe msjson_date filter: the legacy .NET/WCF JSON date format some older ERP and SharePoint-derived integrations still expect/Date(0)/
Epoch millisecondsThe epoch_ms filter: milliseconds since the Unix epoch0

These map to Scriban filters you can also type directly, for example {{ scan_event.end_time | msjson_date }} or {{ scan_event.end_time | epoch_ms }}.

A bare date variable renders ISO-8601 (2026-09-08T14:45:00Z) by default. For anything else, pipe the variable through date.to_string with a strftime-style format string:

Format stringRenders as
'%Y-%m-%d'2026-09-08
'%d %b %Y'08 Sep 2026
'%A, %B %d, %Y'Tuesday, September 08, 2026
'%d %b %Y at %I:%M %p'08 Sep 2026 at 02:45 PM
'%H:%M:%S'14:45:00

Filters chain, so {{ scan_event.end_time | date.add_days 1 | date.to_string '%Y-%m-%d' }} shifts the date forward a day before formatting it.

Important: Format strings use %-prefixed strftime-style tokens (%Y, %b, %H), not .NET format strings. Anything the formatter does not recognize is passed through as literal text rather than raising an error: a mistyped token like '%Q' renders as %Q, and a .NET-style string like 'yyyy-MM-dd' renders as the text yyyy-MM-dd. Seeing your format string echoed back in the output means the tokens were not recognized. Month and day names (%A, %B, %b) always render in English, regardless of your Tagnet locale.

msjson_date and epoch_ms both expect a real timestamp: an entity property such as scan_event.end_time, or a custom field declared as a Date or Date & Time type (see Custom Field Values in Templates above), not a string. An empty value, an optional date nobody filled in, renders as empty rather than failing the whole template.

Tip: The Timestamp Formats - JSON starter template, in the editor's Starters panel, lays out every format above side by side. Insert it and preview it against your own data to see exactly which one matches what your target system expects.

Workflow Run Order​

How Workflows Run for One Scan Event​

One rule covers it, and it is the rule to keep in mind whenever two workflows touch the same data:

  • One order, top to bottom. All workflows share one run order, the # column on the Workflows list. When a scan event arrives, Tagnet takes every workflow whose FROM clause admits the event and runs them one at a time, in that order. Nothing runs in parallel for the same event.
  • Each workflow sees what the workflows above it did. A workflow that maps a tag, moves an item, or updates a field is seen by every workflow below it, whose conditions and templates read the new mapping, location, or value. Put a workflow that depends on another one below it. See Current Data vs Trigger Data.
  • Each reader processes its events in arrival order. Events from one reader, or from one device group acting as a single read point, never overlap: the second waits until the first has finished every workflow.
  • Different readers run in parallel. A reader whose workflow is waiting on a slow endpoint delays only itself. See Queue Processing for the limits and for the warning you get when a reader outpaces its workflows.

Because the order spans every scope, only an administrator can change it. The rule is the same whether a workflow is narrowed to one site's devices or built on a device type across every site.

Recipe: Update, Then Tell​

The most common chain is a data change followed by a message about it: receive an item at a dock door and post the receipt to an ERP, or move a pallet and push the move to the live reads view. Put both steps in one workflow, in this order:

  1. Update: a Move Inventory or Update Custom Fields action.
  2. Tell: an HTTP Integration (durable) action to post the change, or an Update Live Reads or Notification action. Its template reads filtered_tags, which already shows the new location or field value, and tag.movement carries the details of the move (see Movement Results in Templates).

HTTP Integration hands the request to the Integration Outbox, which delivers it in the background with retries, so a slow or unreachable receiver never holds up the reader. The two steps can also live in two workflows, the update above the tell in the run order, since the lower workflow sees what the upper one did.

Use the inline Send HTTP Request action for the tell step only when the receiver needs the call in real time and in order, such as a PLC on a stacker that acts on the response. An inline call holds that reader's lane until it returns (up to the endpoint's timeout, plus retries), so a slow or down endpoint delays that reader's later events, and only that reader's. The editor shows a reminder when a workflow contains one.

Reading the Order on the List​

The Workflows list leads with a # column showing each workflow's position, 1 to N, in the run order. Disabled workflows keep their position and appear muted, so re-enabling one never changes where it runs. The list sorts by # by default, and you can also sort by Name. Two other columns describe each workflow at a glance:

  • Actions: one icon per kind of effect the workflow has: Moves inventory, Updates fields, Maps tags, HTTP, Durable HTTP, Notification, and Live reads. Hover an icon to see the names of the actions of that kind.
  • Last run: when the workflow last ran, or Never if it has not run yet.

Changing the Order (Admins)​

Administrators have two ways to change a workflow's position. Non-administrators see the # column but not these controls.

  • Reorder: click Reorder next to the search box to switch the list to a drag list. Drag workflows into the order you want, then click Save order, or Cancel to leave without changing anything. Nothing is saved until you click Save order. Entering Reorder clears the search box and any scope filter, because the order spans every scope and a filtered list would hide rows you are moving around.
  • Move to position…: open a workflow's row menu (⋮) and choose Move to position…, then enter the position number it should take (1 runs first). This is faster than dragging on a long list, and it also clears the scope filter while the dialog is open. If you cancel, your scope filter comes back.

Each saved change is recorded in Change History, one entry per workflow whose position moved.

Run Order Views​

Position alone does not answer the question you usually have: "when this reader reads, what runs, and in what order?" The view selector next to the search box answers it. Choose from List, Run order by device type, and Run order by scope (offered only when your organization has more than one scope). Your choice is remembered for the session and kept in the page address (?view=order or ?view=scope), so you can share a link to it.

In a run order view, there is one expandable section per device type (or per scope). Each lists the workflows that can fire for that section's devices as a numbered pipeline, in run order. Click a row to open the workflow. These views are read-only: to change the order, switch back to List and use Reorder or Move to position….

Badges show how widely a workflow applies within a section:

BadgeMeaning
All devicesThe workflow has no device conditions, so it runs for every device the section covers
Some devicesThe workflow is narrowed by device, device group, or scope conditions, or it belongs to one scope (not Shared) and appears in a section spanning more than that scope. Hover the badge to see the device conditions
(no badge)The workflow's only device conditions are on the section's own device type (or scope), so it runs for the whole section

Use Show disabled workflows to include disabled workflows, shown muted and unnumbered. Use For one device to pick a single device and see the exact pipeline for it. Workflows that would not run for that device are dimmed with the reason: the workflow is disabled, it belongs to another scope, or the device does not match its device conditions.

Tip: In an RFID deployment where one dock door reader feeds several workflows (map new tags, move inventory, notify a supervisor, post to an ERP), check For one device after any change. It shows the pipeline a real read from that reader goes through, in order.

Execution Tracking​

Every workflow whose FROM clause matches a scan event is recorded as an execution record, providing an audit trail of what ran. This includes runs where the FOR clause matched no tags, which are recorded as No matching tags. A workflow whose FROM clause does not match is not a candidate for that event and records nothing. See Workflow Executions for how to review execution history.

Trigger Statuses​

StatusMeaning
ConditionsMetFROM and FOR were met and actions were executed
ConditionsNotMetReserved; the engine records nothing when FROM is not met
NoMatchingTagsFROM was met, but no tag in the scan event matched the workflow's FOR condition

Execution Results​

ResultMeaning
SuccessAt least one action completed successfully with effect
NoEffectAll actions completed without error but none performed work
PartiallyFailedSome actions succeeded, some failed
FailedAll actions failed
NotExecutedNo actions ran

Action Statuses​

Each action within an execution is tracked individually:

StatusMeaning
SuccessAction executed and performed work
NoEffectAction executed but had no effect (e.g., no items to move)
FailedAction encountered an error
SkippedAction was skipped due to its RUN condition, its own FROM devices, or its own FOR tags
QueuedAn HTTP Integration (durable) action accepted its request for delivery. Says nothing about whether delivery has actually happened yet; the execution's detail page shows the delivery's current status in place of Queued, once you can see deliveries, and links to it.

Note: On an execution's Overview tab, each action is shown as a numbered step colored by its status. Skipped steps are grey, since a run condition not being met is normal, not a problem. See Execution Details in the Workflow Executions guide.

What Gets Recorded​

Each execution record includes:

  • Which workflow was evaluated and which scan event triggered it
  • The trigger status and overall execution result
  • Source tag count and matched tag count (how many tags met the tag conditions)
  • A snapshot of the source event data as it looked when this workflow started, including what the workflows above it did for the same scan event (this is fixed, and is what execution history and the Source Data tab show)
  • Individual action execution records with status, affected count, timing, and result data

During the run itself, tag conditions and templates on actions after the first use current data, not this snapshot. If an earlier action moved an item, updated a custom field, or mapped a tag, later actions saw the new values. See Current Data vs Trigger Data.

Queue Processing​

Scan events are processed in one lane per read point. A read point is a reader, or a device group acting as one large read point: every reader in a group shares the group's lane, because they all see the same tags.

  • Within a lane, events run one at a time, in the order they arrived. Two events from the same reader never run at once, so a workflow that moves an item or updates a field can never race an earlier event from the same reader.
  • Different lanes run in parallel. A reader whose workflow is waiting on a slow endpoint only delays itself. Other readers keep going.
  • Each lane has its own limit of 200 events, counting the one being processed. A reader that sends events faster than its workflows finish fills only its own lane, and once the lane is full its newest events are dropped (logged, not processed). The drop is counted against that reader and never affects another reader's events. There is also an overall limit of 1,000 waiting events across all lanes.
  • Lanes share a pool of processing slots. A lane holds a slot only while it is running an event and gives it back between events. The pool has 16 slots on SQL Server and 4 on SQLite, where writes are serialized by the database anyway.

When a lane's oldest waiting event has waited more than 30 seconds, more than 50 events are waiting in it, or the event it is processing has sat on one action for more than 30 seconds, Tagnet logs a warning naming the reader ("Reader 'Dock 3' is receiving scan events faster than its workflows finish") and shows the same warning on the Diagnostics tab. The usual causes are a reader in Immediate mode without a cooldown, or a workflow calling an endpoint that is slow or down.

Workflow processing is best-effort downstream of ingest: a backlog never blocks or rejects reads from a reader. The queue is in memory, so events waiting when Tagnet restarts are not in it afterward. At startup the Workflows / CatchUp policy decides whether they are run or marked Skipped (see After a Restart). Events dropped because a lane was full are marked Dropped on the scan event.

Diagnostics​

Runs tells you what happened. Diagnostics, a tab on the Workflows page for administrators, tells you what workflow processing is doing right now, which is where to look when a reader's workflows are running late and you want to know why.

  • Waiting is how many events are queued across all lanes. Lanes running shows how many lanes hold a processing slot against the size of the pool. Per second is the rate over the last minute. Processed, Failed and Dropped are counts since the Tagnet service started; Dropped is highlighted when it is not zero.
  • Lanes lists each reader or device group that has events running or waiting, or has dropped events since startup, worst first. For each lane you see how many events are waiting, how long the oldest has waited, and what it is running: the workflow and action in progress, the event's tag count, when it was queued and started, and how long it has been running. An action that has run for more than 30 seconds is flagged slow; an inline Send HTTP Request waiting out its timeout looks like this. A lane held on a Send HTTP Request shows the host it is calling and whether Tagnet is currently holding back requests to it; the full per-host view is on Integrations Diagnostics. When any endpoint is rejecting or probing, a banner above the tiles says so and links to Endpoint health. For a reader's lane, the Runs link opens the execution history filtered to that reader (device group lanes have no link).
  • Last minute shows events completed in the last 60 seconds, the rate per second, and the median and 95th percentile of the time an event spent waiting in its lane and the time it took to process.
  • Waiting events charts the queue across all lanes while you have the page open. The chart needs two samples, so for the first few seconds (or until you press Refresh with Live off) the section shows a Sampling note in its place.
  • Restart catch-up alert: after a startup that found scan events the last stop had cut off, an alert above the tiles says how many were queued to run, how many were marked not run (the Workflows / CatchUp policy is off, or the events were older than its maximum age), and how many did not fit in the queue and were marked dropped. It is informational when everything was queued and turns to a warning when any event was skipped or dropped. Like the counters, it describes the current run of the service.

The page refreshes every five seconds while Live is on. Everything on it is live server state: the counters start again from zero when the Tagnet service restarts, and the permanent record of each run stays on Runs. Per-host request limits and circuit state for Send HTTP Request are shared with integrations and shown on Integrations Diagnostics.

Configuration Checklist​

When setting up a workflow:

  1. Name and describe the workflow so its purpose is clear
  2. Check WHEN (a scan event arrives is the only choice today)
  3. Choose FROM: any device, or a device matching conditions on device, device group, device type or scope (a Device Scope condition is how a Shared workflow serves one site)
  4. Choose FOR to target the right tags (mapped vs unmapped, motion status, item type, etc.)
  5. Configure actions in the order they should execute
  6. Set RUN, and FROM if needed, on actions that should only run conditionally or for specific devices
  7. Check its position in the # column of the run order if it depends on what other workflows do first, and use For one device to see the whole pipeline a reader goes through
  8. Enable the workflow when ready, either at save time or from its page later