Documentation
Flows
Automate responses to asset events, schedules and signed inbound webhooks by sending webhooks, emails, commands or tickets.
Overview
A flow is an automation: one or more triggers start it, and one or more actions run when it starts. Use flows to notify an endpoint when a new asset is discovered, to open a Jira or ServiceNow ticket every morning, or to let an external system start work in DeviceQuest through a signed webhook.
You need flows:read to open the page and flows:write to create, edit, run, activate or delete flows. A flow that contains a Run command action also needs flows:command.
Screen tour
- Active flows, Runs · 24h, Succeeded, Failed: live counts for the last 24 hours. Click Active flows to show only active flows. When a run failed, the sentence on the right names the last flow that failed; click its name to open it.
- 24h activity: one bar per hour for the last 24 hours. The red part of a bar is the share of failed runs. Hover a bar to see the counts.
- Search flows by name or description…: filters the list as you type. Press
/to jump here. - All, Active, Inactive: shows every flow, only active flows or only paused flows.
- Filters: opens Refine flows, where you filter by Trigger type and Action type. The badge shows how many filters are on.
- Export: downloads the flow list as
flows.csv. - New Flow: opens the two-step flow wizard.
- Route: the flow at a glance, its triggers on the left and its actions on the right.
- Last run: the health chip of the latest run, its age and duration.
- Status: the toggle activates or pauses the flow.
- Run now (play button) and the More actions menu (Edit definition, Delete flow).
Click a flow name to open its side sheet. When flows were added since your last visit, a line under the title says how many; click × to dismiss it.
Create a flow
The wizard has two steps.
- Name: required, up to 120 characters.
- Description: optional, up to 500 characters.
- Active: when on, the flow runs on matching events. When off, the flow is paused.
- Next: Triggers & Actions →: goes to step 2.
- Click New Flow (or press
n). - Enter a Name, an optional Description, and set Active.
- Click Next: Triggers & Actions →. If the name is empty, the wizard shows Name is required and stays on step 1.
- Under Triggers, choose a trigger type and fill in its settings. Click + Add trigger to add more triggers; any of them starts the flow.
- Under Actions, choose an action type and fill in its fields. Click + Add action to add more; the actions run in order.
- Click Create flow. A confirmation appears and the flow is added to the top of the list.
- Trigger type: On asset event, Schedule or Webhook.
- Event: the asset event that starts the flow.
- + Add trigger: adds another trigger. Remove deletes a trigger.
- Action type: Send webhook, Send email, Run command or Create ticket.
- The fields of the selected action. + Add action adds another action.
- ← Back returns to step 1. Create flow saves the flow.
To change a flow later, choose Edit definition from the More actions menu, or press e on a focused row. The wizard opens with the current values and the save button reads Save changes.
Triggers
| Trigger | Settings | When the flow starts |
|---|---|---|
| On asset event | Event: New asset discovered, Asset updated or Asset removed | Each time an asset event of that type happens. |
| Schedule | Schedule preset and Cron expression | On the cron schedule. The text under the field shows the schedule in plain words, for example “Weekdays at 9:00 AM”. |
| Webhook | None. The endpoint URL and HMAC secret are generated when the flow is saved. | Each time a correctly signed request reaches the flow’s webhook URL. See Webhook trigger. |
Schedule presets
| Preset | Cron expression |
|---|---|
| Daily at midnight | 0 0 * * * |
| Daily at noon | 0 12 * * * |
| Weekdays at 9:00 AM | 0 9 * * 1-5 |
| Monthly on the 1st | 0 0 1 * * |
| Every 15 minutes | */15 * * * * |
| Every 5 minutes | */5 * * * * |
To use your own schedule, type a standard five-field cron expression (minute, hour, day of month, month, day of week) in Cron expression.
Actions
| Action | Fields | What it does |
|---|---|---|
| Send webhook | URL (https://…), Method (default POST), Headers (JSON), for example {"Authorization":"Bearer …"} | Sends the event payload as JSON to the URL. |
| Send email | To, Subject, Body | Sends an email to the address in To. |
| Run command | Command, for example /usr/bin/notify.sh, and Working directory | Runs the command on the DeviceQuest server and passes the trigger payload to it as JSON on standard input. |
| Create ticket | Saved connection, Project key (required), Summary (required), Issue type (default Task), Description (optional) | Opens a ticket in Jira or ServiceNow through a saved connection. |
Create ticket
Saved connection lists the connectors you set up on the Integrations page, shown as “name · Jira” or “name · ServiceNow”. If the list is empty, add a connector there first (see Integrations).
Summary and Description accept event data in double braces:
{{asset.name}}: the name of the asset in the event.{{event.type}}: the event type, for exampleNEW_ASSET.{{payload.custom_field.value}}: any value from the event payload, by its path.
For example, New asset: {{asset.name}} becomes New asset: web-01.
Run command
Commands run on the DeviceQuest server, so they need extra care:
- Saving a flow with a Run command action needs the
flows:commandpermission in addition toflows:write. - The server runs only commands on its allowlist (by default common read-only tools such as
ls,cat,echo,grep,df,uptimeandhostname). Your administrator enables command actions and manages the allowlist. - When you click Run now on a flow with a command action, a Run flow dialog asks you to confirm: “This flow contains a command action that will execute on the server.” Click Run now to continue or Cancel to stop.
Webhook trigger
A Webhook trigger gives the flow its own inbound URL. Any system that knows the flow’s signing secret can start the flow by sending a signed HTTP POST to that URL.
- URL: the flow’s inbound path. Click Copy to copy it.
- Secret: the signing secret. It is shown only once, right after you create the flow.
- Signature: how to sign each request.
Get the URL and secret
- Create a flow with a Webhook trigger and click Create flow.
- Without reloading the page, open the new flow from the list. Under Triggers, the Webhook card shows the URL and the Secret.
- Click Copy next to Secret and store it in your secret manager now. For security, the secret is shown only once, when the flow is created, and cannot be retrieved later. Afterwards the card reads “Hidden for security.”
The inbound URL has this format:
https://<your-devicequest-host>/api/v1/flows/webhook/<webhook-id>
<webhook-id> is generated by DeviceQuest and looks like wh_a02ca7499c969a2f33512447.
Sign each request
Send the request body as JSON, and add the header X-DeviceQuest-Signature. Its value is the lowercase hex HMAC-SHA256 of the raw request body, keyed with the flow’s secret. There is no prefix such as sha256=.
Sign the exact bytes you send. If you pretty-print or re-encode the body after signing, the signature no longer matches.
Outbound webhooks from the Developer page use the same header but also sign the timestamp; see What each delivery contains.
WEBHOOK_URL="https://devicequest.example.com/api/v1/flows/webhook/wh_a02ca7499c969a2f33512447"
SECRET="paste-the-flow-secret-here"
BODY='{"source":"ci","asset":{"name":"web-01"},"build":"1842"}'
SIGNATURE=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | sed 's/^.*= //')
curl --fail-with-body -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "X-DeviceQuest-Signature: $SIGNATURE" \
--data-binary "$BODY"
A request that is accepted returns 200 with {"status":"ok"}, and the flow runs with the body as its trigger payload.
Verify a signature
To check a signature yourself, for example while testing a client, compute the HMAC of the saved body and compare it with the header value:
# body.json holds the exact bytes that were sent; RECEIVED holds the header value.
EXPECTED=$(openssl dgst -sha256 -hmac "$SECRET" -hex < body.json | sed 's/^.*= //')
if [ "$EXPECTED" = "$RECEIVED" ]; then
echo "signature valid"
else
echo "signature mismatch"
fi
Payload and responses
- A JSON object body becomes the trigger payload, so actions can use its fields, for example
{{payload.build}}. - A body that is not JSON is passed on as text in the
_rawfield of the payload.
| Response | Meaning |
|---|---|
200 {"status":"ok"} | The signature matched and the flow ran. |
401 missing signature | The X-DeviceQuest-Signature header is missing. |
401 invalid signature | The signature does not match the body and the flow’s secret. |
404 webhook not found | No active flow uses this webhook ID. Check the URL, and check that the flow is active. |
Flow details and executions
Click a flow to open its side sheet. It has three parts.
Header
- The health chip of the last run, an Active or Inactive badge, and Last run with its age.
- Activate / Deactivate: turns the flow on or off.
- Run now: runs the flow immediately. The trigger payload is
{"trigger":"manual"}. - More actions: Edit definition and Delete flow.
- Last error: the start of the last error message, when the latest run failed.
Definition
- Triggers: one card per trigger, with its settings. Webhook triggers show the URL, Secret and Signature rows.
- Actions: one card per action, with its settings. Copy copies the action as JSON.
Recent executions
- The 20 most recent runs, newest first, with status, start time and duration.
- Click a run to expand it. You see the Error (when the run failed), the Trigger payload and the Execution result. Values such as tokens, secrets and passwords are masked as
••••••. Copy copies the JSON.
After Run now, a message “Flow run complete — view executions.” appears. Click View executions to open the flow’s side sheet.
Run, pause or delete a flow
- Run now: click the play button on the row, or Run now in the side sheet. Flows with a Run command action ask you to confirm first.
- Pause or resume: click the Status toggle on the row, or Deactivate / Activate in the side sheet. Paused flows ignore their triggers.
- Delete: choose Delete flow from More actions. The Delete flow dialog warns that all execution history for this flow is also deleted. Click Delete flow to confirm.
Statuses
Health chip
| Chip | Meaning |
|---|---|
| Completed | The last run finished without errors. |
| Running / Pending | A run is in progress or queued. |
| Failed | The last run failed. Open the flow to see the error. |
| No runs (No runs yet in the side sheet) | The flow is active and has never run. |
| Inactive | The flow is paused. |
The chip is also marked as stale when an active flow’s last successful run is more than 30 days old.
Execution status
| Status | Meaning | Next possible status |
|---|---|---|
| Pending | The run is queued. | Running |
| Running | The actions are running. | Completed, Failed |
| Completed | Every action finished. | None |
| Failed | An action failed. The error is shown on the execution. | None |
Keyboard shortcuts
Shortcuts work when the focus is not in a text field. Press ? to show them on the page.
| Key | Action |
|---|---|
j / k | Next / previous row |
/ | Focus search |
n | New flow |
e | Edit focused flow |
r | Run focused flow |
a | Toggle active on focused flow |
d | Delete focused flow |
g then a | Filter: active only |
g then i | Filter: inactive only |
g then e | Filter: event triggers |
x | Close side sheet or wizard |
? | Show the shortcuts overlay |
Esc | Close side sheet, wizard or overlay |