Action blocks do something: call another system, publish a message, store a variable, start a timer, hand the message to another flow, or write a log line. The device, alarm and notification actions are on their own pages: IoT data blocks and Alarm, command and notify blocks.
Common behaviour of outbound blocks
HTTP request, MQTT out and Webhook share these rules:
| Topic | Behaviour |
|---|---|
| Risk | External: a deploy that contains one asks for a confirmation |
| Retries | Only transient failures retry; 3 attempts by default (retry_* settings), at most 5, with an exponential back-off from 1 s |
| Idempotency | Every attempt of one message carries the same key (X-Idempotency-Key, or the MQTT 5 user property idempotency-key), also after a crash or a replay, so a receiver can deduplicate |
| Delivery | At least once |
| Breaker | A block whose calls keep failing pauses its calls for a while (circuit_open) |
| Late messages | late: skip (default; the message stops, counted as Too old) or send (a data feed that must also get the backlog after an outage) |
| Tests | A test run sends nothing and reports what it would have sent |
| Order | HTTP request and MQTT out calls run separately from the run that made them: the device’s next message does not wait for the answer, and the order of messages after the call is not guaranteed |
| Addresses | Private and internal addresses are refused (ssrf_blocked) |
HTTP request
Calls an HTTP endpoint and puts the answer into the message. Scheme, host, port, authentication and TLS come only from the endpoint connection, never from the message. See Connections and secrets.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| endpoint | The HTTP endpoint connection | required | |
| host | Another host the endpoint allows | empty | a template; must match the endpoint’s allowed hosts |
| method | HTTP method | GET | GET, POST, PUT, PATCH, DELETE, HEAD |
| path | Appended to the endpoint’s base path | empty | a template, 1,024 characters |
| query | Query parameters | none | up to 16 rows |
| headers | Extra headers | none | up to 16 rows; Host, Authorization, Cookie, Proxy-*, Content-Length, X-Idempotency-Key and hop-by-hop headers are refused |
| body | What is sent | payload | payload, template, none (hidden for GET, HEAD, DELETE) |
| template | The body template | empty | up to 4,096 characters |
| template_format | How {{ }} values are written | text | text, json (each value as a JSON value; the body must be JSON) |
| timeout_ms | Time per attempt | 10,000 | 1,000 to 30,000 |
| parse | How the answer is read | auto | auto, json, text |
| max_bytes | Largest answer | 64 KiB | 1 to 256 KiB |
| response_headers | Answer headers kept in msg.metadata.headers | all | all, list, none (at most 32 headers, 8 KiB) |
| max_parallel | Calls in flight for this block | 0 (no cap) | 0 to 64 |
| inline | Keep the call inside the run, so the device’s next message waits for the answer (the deploy warns) | off | on, off |
| retry_* | Attempts and back-off | 3, from 1 s | |
| late | See above | skip | skip, send |
Outputs:
out: status below 400.msg.payloadis the body,msg.statusCode,msg.contentType,msg.metadata.headers. Redirects are not followed.error:http_status(400 or above, body inmsg.payload),timeout,connect,tls,ssrf_blocked,too_large,invalid_json,invalid_value,oauth_failed,function_error,circuit_open,limit.msg.error.attemptssays how many attempts were made.
Retried: timeouts, connection failures and HTTP 408, 425, 429 (honouring Retry-After), 500, 502, 503, 504.
For a JSON body built from values, use template_format: json and leave the placeholders unquoted: {"name": {{ msg.payload.name }}, "n": {{ msg.payload.n }}}.
HTTP response
Answers the caller of a synchronous Webhook trigger (reply: response). The first response of a run wins.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| status | HTTP status (msg.statusCode overrides it) | 200 | 100 to 599 |
| headers | Response headers | none | content-type, cache-control, location (3xx), x-* (not x-forwarded-*) |
| body | What is sent | payload | payload, template, none |
| template | Body template | empty | up to 4,096 characters |
| max_bytes | Largest body | 256 KiB | at most 256 KiB |
Errors: no_reply_pending, reply_sent, limit. Without a response the caller gets 204; after the hook’s timeout, 504.
MQTT out
Publishes the payload to a topic on your broker, then passes the message on. Text is sent as text, anything else as JSON.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| broker | The MQTT broker connection | required | |
| topic | The topic | {{ msg.topic }} | a template, 256 characters; a leading ~/ is the broker’s topic prefix |
| qos | Delivery guarantee | 0 | 0, 1, 2 |
| retain | Ask the broker to keep the message | off | on, off |
| timeout_ms | Time for the acknowledgement | 10,000 | 1,000 to 30,000 |
| max_parallel | Publishes in flight | 0 (no cap) | 0 to 64 |
| retry_*, late | As above |
Errors: bad_topic (empty, + or #, or ~/ without a prefix), timeout, connect, auth, ssrf_blocked, node_not_ready, not_configured, circuit_open, limit. Only timeouts and connection failures retry.
Webhook
Sends the message to one of your organisation’s webhook endpoints: signed, retried and listed in the endpoint’s deliveries. This is the guaranteed-delivery path.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| endpoint | The endpoint | required | active endpoints subscribed to Automation message |
| topic | Sent as topic | {{ msg.topic }} | a template, 256 characters |
| body | What is sent besides the topic | payload | payload, payload and metadata |
| metadata_keys | Metadata keys sent | none | at most 20 |
| late | See above | skip | skip, send |
The receiver gets the event automation.message with topic, payload, originator, flowId, flowVersion, nodeId, actor and the listed metadata. out carries msg.metadata.webhook.deliveryId once queued. Errors: endpoint_not_found, endpoint_inactive, enqueue_failed, not_configured, node_not_ready, circuit_open, limit (webhooks not in your plan). See Webhooks.
Emit event
Sends an event that Event triggers with source flow hear, in any flow.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| kind | The event’s name | required | a lower-case letter first, then lower-case letters, digits, _ and .; up to 32 characters |
| data | What it carries | msg.payload | any value kind; a non-object is wrapped as { "value": … } |
Listeners get msg.payload = the data and msg.topic flow/<kind>. Errors: rate_limited, invalid_value (a bad kind, or “emit: depth”: the fifth step of a chain). A deploy refuses a loop it can see (flow_cycle). A late message emits nothing.
Set variable
Stores a value in a flow or global variable.
| Setting | Meaning | Values |
|---|---|---|
| path | The variable | flow.<name> or global.<name>, deeper keys allowed; flow.persist:<name> for the persistent store |
| value | What to store | any value kind; nothing (null) removes it |
Errors: invalid_value, limit (store full; the old value stays). Limits: 1 MiB per flow, 4 MiB for global variables. In a test, the test’s own copy is written.
Timer
Starts, restarts or cancels a named timer. When it runs out, every Named timer trigger with that name fires.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| name | The timer, shared by all flows | required | |
| op | Start (again) or cancel | start | start, cancel |
| ms | Duration (msg.ms overrides it) | 1 min | 0 to 7 days |
Starting a running timer restarts it from zero: the watchdog pattern. Error queue_full “too many timers”: the organisation holds 64 timers of 60 s or less, or 10,000 longer ones. A late message starts or cancels nothing.
Enable or disable a flow
Switches another flow on or off, like the switch in the flow list.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| flow | The flow | required | a deployed flow of the organisation, not this one |
| state | Enable or disable | enable | enable, disable |
out carries msg.metadata.flow_enable { flow, enabled, changed }. Errors: not_configured, self_reference, not_found, not_approved, conflict, invalid, limit (more than 6 switches a minute). Deploying a flow with this block needs the typed confirmation.
Run flow
Hands the message to another flow’s Flow input and ends this branch.
| Setting | Meaning | Values |
|---|---|---|
| flow | The flow to run | another flow of the same host; never a root flow |
No out port; nothing comes back. Errors: not_configured, invalid_value (missing, disabled or stopped), forbidden (a root), loop (fifth hop). A flow that other flows run cannot be deleted until those blocks are removed. The message keeps its device, so Save telemetry works in the target flow.
Link out
Passes the message to Link in blocks by name, or returns the answer to a Link call.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| mode | link (to Link in blocks) or return (answer the caller) | link | link, return |
| targets | Link in names (link mode) | empty | up to 16 |
| name | The return’s name (return mode) | out | a return the caller declares |
No out port. A missing target is a warning in the debug panel, not an error. A deploy refuses unknown names and loops with no waiting block (cycle_sync).
System log
Writes a line to the flow’s log (Activity > Events > Log, kept 24 hours).
| Setting | Meaning | Default | Values |
|---|---|---|---|
| text | The line, with {{ }} placeholders | {{ msg.payload }} | up to 512 characters |
| level | Priority | info | info, notice, warn, err |
Debug
Shows the messages that reach it in the editor’s Activity > Debug tab. No out port.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| property | What to show | msg.payload | msg (the whole message) or a path |
| active | Show messages at all | on | on, off |
Debug entries are kept 24 hours and are visible to people who may debug. The button on the block switches it off and on without saving.
Write to an external time-series database
A block writes one point per message to an external time-series database server of your own, through a database server connection. Settings: the server, the bucket or database, the measurement, up to 16 tags, 1 to 32 fields (with a type: auto, float, int, string, bool), the time (default: the time of the first attempt, the same on every retry), timeout_ms (1,000 to 30,000), retries and late. out carries msg.metadata with the written measurement, fields and tags. For a general integration, the HTTP request block to your own API is often simpler.

