<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Viam Documentation – Push Notification</title><link>https://docs.viam.com/tags/push-notification/</link><description>Recent content in Push Notification on Viam Documentation</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Mon, 05 May 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://docs.viam.com/tags/push-notification/feed.xml" rel="self" type="application/rss+xml"/><item><title>Reference: Trigger configuration</title><link>https://docs.viam.com/reference/triggers/</link><pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate><guid>https://docs.viam.com/reference/triggers/</guid><description>
&lt;p&gt;Triggers can alert you by email, webhook, or push notification when any of the following events occur:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.viam.com/monitor/alert/" &gt;Machine telemetry data syncs from your local device to the Viam cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.viam.com/data/trigger-on-data/" &gt;Data syncs from a machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.viam.com/vision/object-detection/alert-on-detections/" &gt;A vision service detects a specified object or classifies a specified label&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.viam.com/monitor/alert/" &gt;Machine logs contain errors, warnings, or info logs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This page provides a reference for the Trigger attributes.
For step-by-step configuration information, see the preceding links instead.&lt;/p&gt;
&lt;h2 id="json-configuration-templates" class="main-content-heading"&gt;
JSON configuration templates
&lt;div class="copied" id="copied-json-configuration-templates" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-json-configuration-templates-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h2&gt;&lt;h3 id="part-status-trigger-template" class="main-content-heading"&gt;
Part status trigger template
&lt;div class="copied" id="copied-part-status-trigger-template" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-part-status-trigger-template-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;p&gt;The following template demonstrates the structure of a JSON configuration for a trigger that alerts when a part is online or offline:&lt;/p&gt;
&lt;pre class="language-json line-numbers linkable-line-numbers"data-line-offset="0"&gt;
&lt;code&gt;&amp;#34;triggers&amp;#34;: [
{
&amp;#34;name&amp;#34;: &amp;#34;&amp;lt;trigger name&amp;gt;&amp;#34;,
&amp;#34;event&amp;#34;: {
&amp;#34;type&amp;#34;: &amp;#34;part_online|part_offline&amp;#34;
},
&amp;#34;notifications&amp;#34;: [
{
&amp;#34;type&amp;#34;: &amp;#34;&amp;lt;webhook|email|push&amp;gt;&amp;#34;,
&amp;#34;value&amp;#34;: &amp;#34;&amp;lt;webhook URL, email address, or all_machine_owners&amp;gt;&amp;#34;,
&amp;#34;seconds_between_notifications&amp;#34;: &amp;lt;number of seconds&amp;gt;
}
]
}
]&lt;/code&gt;
&lt;/pre&gt;
&lt;h3 id="data-sync-trigger-template" class="main-content-heading"&gt;
Data sync trigger template
&lt;div class="copied" id="copied-data-sync-trigger-template" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-data-sync-trigger-template-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;p&gt;The following template demonstrates the structure of a JSON configuration for a trigger that alerts when data syncs to the Viam cloud:&lt;/p&gt;
&lt;pre class="language-json line-numbers linkable-line-numbers"data-line-offset="0"&gt;
&lt;code&gt;&amp;#34;triggers&amp;#34;: [
{
&amp;#34;name&amp;#34;: &amp;#34;&amp;lt;trigger name&amp;gt;&amp;#34;,
&amp;#34;event&amp;#34;: {
&amp;#34;type&amp;#34;: &amp;#34;part_data_ingested&amp;#34;,
&amp;#34;data_ingested&amp;#34;: {
&amp;#34;data_types&amp;#34;: [&amp;#34;binary&amp;#34;, &amp;#34;tabular&amp;#34;, &amp;#34;file&amp;#34;, &amp;#34;unspecified&amp;#34;]
}
},
&amp;#34;notifications&amp;#34;: [
{
&amp;#34;type&amp;#34;: &amp;#34;&amp;lt;webhook|email|push&amp;gt;&amp;#34;,
&amp;#34;value&amp;#34;: &amp;#34;&amp;lt;webhook URL, email address, or all_machine_owners&amp;gt;&amp;#34;,
&amp;#34;seconds_between_notifications&amp;#34;: &amp;lt;number of seconds&amp;gt;
}
]
}
]&lt;/code&gt;
&lt;/pre&gt;
&lt;h3 id="conditional-trigger-template" class="main-content-heading"&gt;
Conditional trigger template
&lt;div class="copied" id="copied-conditional-trigger-template" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-conditional-trigger-template-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;p&gt;The following template demonstrates the structure of a JSON configuration for a conditional trigger:&lt;/p&gt;
&lt;pre class="language-json line-numbers linkable-line-numbers"data-line-offset="0"&gt;
&lt;code&gt;&amp;#34;triggers&amp;#34;: [
{
&amp;#34;name&amp;#34;: &amp;#34;&amp;lt;trigger name&amp;gt;&amp;#34;,
&amp;#34;event&amp;#34;: {
&amp;#34;type&amp;#34;: &amp;#34;conditional_data_ingested&amp;#34;,
&amp;#34;conditional&amp;#34;: {
&amp;#34;data_capture_method&amp;#34;: &amp;#34;&amp;lt;component&amp;gt;:&amp;lt;name-of-component&amp;gt;:&amp;lt;method&amp;gt;&amp;#34;,
&amp;#34;conditions&amp;#34;: {
&amp;#34;evals&amp;#34;: [
{
&amp;#34;operator&amp;#34;: &amp;#34;&amp;lt;lt|gt|lte|gte|eq|neq|regex&amp;gt;&amp;#34;,
&amp;#34;value&amp;#34;: &amp;lt;object, string, bool, regex, or int&amp;gt;
}
]
}
}
},
&amp;#34;notifications&amp;#34;: [
{
&amp;#34;type&amp;#34;: &amp;#34;&amp;lt;webhook|email&amp;gt;&amp;#34;,
&amp;#34;value&amp;#34;: &amp;#34;&amp;lt;webhook URL or email address or all_machine_owners&amp;gt;&amp;#34;,
&amp;#34;seconds_between_notifications&amp;#34;: &amp;lt;number of seconds&amp;gt;
}
]
}
]&lt;/code&gt;
&lt;/pre&gt;
&lt;h3 id="machine-logs-trigger-template" class="main-content-heading"&gt;
Machine logs trigger template
&lt;div class="copied" id="copied-machine-logs-trigger-template" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-machine-logs-trigger-template-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;
&lt;pre class="language-json line-numbers linkable-line-numbers"data-line-offset="0"&gt;
&lt;code&gt;&amp;#34;triggers&amp;#34;: [
{
&amp;#34;name&amp;#34;: &amp;#34;&amp;lt;trigger name&amp;gt;&amp;#34;,
&amp;#34;event&amp;#34;: {
&amp;#34;type&amp;#34;: &amp;#34;conditional_logs_ingested&amp;#34;,
&amp;#34;log_levels&amp;#34;: [
&amp;#34;error&amp;#34;,
&amp;#34;warn&amp;#34;,
&amp;#34;info&amp;#34;
]
},
&amp;#34;notifications&amp;#34;: [
{
&amp;#34;type&amp;#34;: &amp;#34;&amp;lt;webhook|email&amp;gt;&amp;#34;,
&amp;#34;value&amp;#34;: &amp;#34;&amp;lt;webhook URL or email address or all_machine_owners&amp;gt;&amp;#34;
}
]
}
]&lt;/code&gt;
&lt;/pre&gt;
&lt;h2 id="trigger-attributes" class="main-content-heading"&gt;
Trigger attributes
&lt;div class="copied" id="copied-trigger-attributes" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-trigger-attributes-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h2&gt;&lt;p&gt;Triggers support the following attributes:&lt;/p&gt;
&lt;!-- prettier-ignore --&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Required?&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Required&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The name of the trigger&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;event&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;object&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Required&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The trigger event object, which contains the following fields: &lt;ul&gt;&lt;li&gt;&lt;code&gt;type&lt;/code&gt;: The type of the event to trigger on. Options: &lt;ul&gt;&lt;li&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;: fire when data syncs&lt;/li&gt; &lt;li&gt;&lt;code&gt;conditional_data_ingested&lt;/code&gt;: fire when data that meets a certain condition syncs&lt;/li&gt; &lt;li&gt;&lt;code&gt;part_online&lt;/code&gt;: fire when the part is online&lt;/li&gt; &lt;li&gt;&lt;code&gt;part_offline&lt;/code&gt;: fire when the part is offline&lt;/li&gt; &lt;li&gt;&lt;code&gt;conditional_logs_ingested&lt;/code&gt;: check every hour and fire if logs of the specified log level are present&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;data_types&lt;/code&gt;: Required with &lt;code&gt;type&lt;/code&gt; &lt;code&gt;part_data_ingested&lt;/code&gt;. An array of data types that trigger the event. Options: &lt;code&gt;binary&lt;/code&gt;, &lt;code&gt;tabular&lt;/code&gt;, &lt;code&gt;file&lt;/code&gt;, &lt;code&gt;unspecified&lt;/code&gt;. &lt;/li&gt;&lt;li&gt; &lt;code&gt;conditional&lt;/code&gt;: Required when &lt;code&gt;type&lt;/code&gt; is &lt;code&gt;conditional_data_ingested&lt;/code&gt;. For more information about this field, see &lt;a href="https://docs.viam.com/reference/triggers/#conditional-attributes" &gt;Conditional attributes&lt;/a&gt;. &lt;/li&gt;&lt;li&gt; &lt;code&gt;log_levels&lt;/code&gt;: Required when &lt;code&gt;type&lt;/code&gt; is &lt;code&gt;conditional_logs_ingested&lt;/code&gt;. An array of log levels. Options: &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt;. &lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;notifications&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;object&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Required&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The notifications object, which contains the following fields: &lt;ul&gt;&lt;li&gt;&lt;code&gt;type&lt;/code&gt;: The type of the notification. Options: &lt;code&gt;webhook&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;value&lt;/code&gt;: The URL to send the request to, the email address to notify, or &lt;code&gt;all_machine_owners&lt;/code&gt; to notify all machine owners.&lt;/li&gt;&lt;li&gt;&lt;code&gt;seconds_between_notifications&lt;/code&gt;: The interval between notifications in seconds. This field is ignored for event type &lt;code&gt;conditional_logs_ingested&lt;/code&gt; where the interval is always one hour.&lt;/li&gt;&lt;li&gt;&lt;code&gt;application&lt;/code&gt;: Required when &lt;code&gt;type&lt;/code&gt; is &lt;code&gt;push&lt;/code&gt;. The application ID for push notifications. Use &lt;code&gt;com.viam.viammobile&lt;/code&gt; for the Viam mobile app, or provide your own custom application ID. To use a custom application ID, you must first upload your Firebase credentials to Viam with the &lt;a href="https://docs.viam.com/cli/reference/#organizations-firebase-config-set" &gt;&lt;code&gt;organizations firebase-config set&lt;/code&gt;&lt;/a&gt; CLI command.&lt;/li&gt;&lt;/ul&gt; For more information on webhooks, see &lt;a href="#webhook-attributes" &gt;Webhook attributes&lt;/a&gt;. For push notifications, the recipient specified in &lt;code&gt;value&lt;/code&gt; must be a machine owner or operator, and the recipient must have accepted push notification permissions for the application.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;notes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;Descriptive text to document the purpose, configuration details, or other important information about this trigger.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="conditional-attributes" class="main-content-heading"&gt;
Conditional attributes
&lt;div class="copied" id="copied-conditional-attributes" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-conditional-attributes-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;conditional&lt;/code&gt; object for the &lt;code&gt;conditional_data_ingested&lt;/code&gt; trigger type includes the following attributes:&lt;/p&gt;
&lt;!-- prettier-ignore --&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Required?&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;data_capture_method&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Required&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The method of data capture to trigger on. &lt;br&gt; Example: &lt;code&gt;sensor:&amp;lt;name-of-component&amp;gt;:Readings&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;conditions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;object&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;Conditions that, when true, fire the trigger. Evaluated each time data syncs from the linked component. When this object is empty or not present, the trigger fires each time data syncs from the linked component. &lt;br&gt; Options: &lt;ul&gt;&lt;li&gt;&lt;code&gt;evals&lt;/code&gt;:&lt;ul&gt;&lt;li&gt;&lt;code&gt;operator&lt;/code&gt;: Logical operator for the condition. &lt;/li&gt;&lt;li&gt;&lt;code&gt;value&lt;/code&gt;: An object containing a single field and value. The field specifies the path, in the synced data, to the left operand of the conditional. For nested fields, use periods as separators or define the nested structure in JSON. The value specifies an object, string, boolean, regular expression, or integer used as a right operand in the conditional. &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The &lt;code&gt;operator&lt;/code&gt; attribute supports the following values:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;less than&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;greater than&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lte&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;less than or equal to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gte&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;greater than or equal to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eq&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;equal to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;neq&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;not equal to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;regex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;matches regular expression&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="example" class="main-content-heading"&gt;
Example
&lt;div class="copied" id="copied-example" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-example-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;p&gt;The following condition defines a trigger that fires based on the value of the &lt;code&gt;cpu&lt;/code&gt; field of synced data:&lt;/p&gt;
&lt;pre class="language-json line-numbers linkable-line-numbers"data-line-offset="0"&gt;
&lt;code&gt;&amp;#34;conditions&amp;#34;: {
&amp;#34;evals&amp;#34;: [
{
&amp;#34;operator&amp;#34;: &amp;#34;gt&amp;#34;,
&amp;#34;value&amp;#34;: {
&amp;#34;cpu&amp;#34;: 50
}
}
]
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;The following sensor reading fires the trigger, since &lt;code&gt;80 &amp;gt; 50&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="language-json line-numbers linkable-line-numbers"data-line-offset="0"&gt;
&lt;code&gt;{
&amp;#34;readings&amp;#34;: {
&amp;#34;cpu&amp;#34;: 80
}
}&lt;/code&gt;
&lt;/pre&gt;
&lt;h3 id="nested-key-example" class="main-content-heading"&gt;
Nested key example
&lt;div class="copied" id="copied-nested-key-example" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-nested-key-example-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;p&gt;The following condition defines a trigger that fires based on a value nested in the &lt;code&gt;coordinate.latitude&lt;/code&gt; field of synced data:&lt;/p&gt;
&lt;pre class="language-json line-numbers linkable-line-numbers"data-line-offset="0"&gt;
&lt;code&gt;&amp;#34;conditions&amp;#34;: {
&amp;#34;evals&amp;#34;: [
{
&amp;#34;operator&amp;#34;: &amp;#34;lt&amp;#34;,
&amp;#34;value&amp;#34;: {
&amp;#34;coordinate&amp;#34;: {
&amp;#34;latitude&amp;#34;: 50
}
}
}
]
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;The following sensor reading fires the trigger, since &lt;code&gt;40 &amp;lt; 50&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="language-json line-numbers linkable-line-numbers"data-line-offset="0"&gt;
&lt;code&gt;{
&amp;#34;readings&amp;#34;: {
&amp;#34;coordinate&amp;#34;: {
&amp;#34;latitude&amp;#34;: 40
}
}
}&lt;/code&gt;
&lt;/pre&gt;
&lt;h2 id="webhook-attributes" class="main-content-heading"&gt;
Webhook attributes
&lt;div class="copied" id="copied-webhook-attributes" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-webhook-attributes-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h2&gt;&lt;h3 id="request-types" class="main-content-heading"&gt;
Request types
&lt;div class="copied" id="copied-request-types" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-request-types-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;p&gt;When an event occurs, Viam sends an HTTP request to the URL you specified for the trigger:&lt;/p&gt;
&lt;!-- prettier-ignore --&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trigger type&lt;/th&gt;
&lt;th&gt;HTTP Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;conditional_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;part_online&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;part_offline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="headers" class="main-content-heading"&gt;
Headers
&lt;div class="copied" id="copied-headers" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-headers-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;p&gt;The request includes the following headers:&lt;/p&gt;
&lt;!-- prettier-ignore --&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Header Key&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Trigger types&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Org-Id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The ID of the organization that triggered the request.&lt;/td&gt;
&lt;td&gt;all&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Organization-Name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The name of the organization that triggered the request.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_online&lt;/code&gt;, &lt;code&gt;part_offline&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Location-Id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The location of the machine that triggered the request.&lt;/td&gt;
&lt;td&gt;all&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Location-Name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The location of the machine that triggered the request.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_online&lt;/code&gt;, &lt;code&gt;part_offline&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Part-Id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The part of the machine that triggered the request.&lt;/td&gt;
&lt;td&gt;all&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Machine-Name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The name of the machine that triggered the request.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_online&lt;/code&gt;, &lt;code&gt;part_offline&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Robot-Id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The ID of the machine that triggered the request.&lt;/td&gt;
&lt;td&gt;all&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="body" class="main-content-heading"&gt;
Body
&lt;div class="copied" id="copied-body" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-body-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;p&gt;The request body includes the following data:&lt;/p&gt;
&lt;!-- prettier-ignore --&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data Key&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Trigger types&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;component_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The name of the component for which data was ingested.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;, &lt;code&gt;conditional_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;component_type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The type of component for which data was ingested.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;, &lt;code&gt;conditional_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;method_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The name of the method from which data was ingested.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;, &lt;code&gt;conditional_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;min_time_received&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Indicates the earliest time a piece of data was received.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_time_received&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Indicates the latest time a piece of data was received.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;machine_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The name of the machine that triggered the request.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;, &lt;code&gt;conditional_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;location_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The location of the machine that triggered the request.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;, &lt;code&gt;conditional_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;org_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The name of the organization that triggered the request.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;, &lt;code&gt;conditional_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;file_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The ID of the file that was ingested.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;trigger_condition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The condition that triggered the request.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;conditional_data_ingested&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;data&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The ingested sensor data. Includes &lt;code&gt;metadata&lt;/code&gt; with &lt;code&gt;received_at&lt;/code&gt; and &lt;code&gt;requested_at&lt;/code&gt; timestamps and &lt;code&gt;data&lt;/code&gt; in the form &lt;code&gt;map[string]any&lt;/code&gt;.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;part_data_ingested&lt;/code&gt;, &lt;code&gt;conditional_data_ingested&lt;/code&gt; (sensor data)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="example-cloud-function" class="main-content-heading"&gt;
Example cloud function
&lt;div class="copied" id="copied-example-cloud-function" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-example-cloud-function-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;p&gt;If you are using a cloud function or lambda to process the request from &lt;code&gt;viam-server&lt;/code&gt;, you can use this template.&lt;/p&gt;
&lt;p&gt;The following example function prints the received headers:&lt;/p&gt;
&lt;div class="table"&gt;&lt;h4&gt;Flask:&lt;/h4&gt;
&lt;div class="tab-content" id="tab-content-tabset-referencetriggers-2"&gt;
&lt;div id="tabset-referencetriggers-2-0" class="tab-pane show active" role="tabpanel" aria-labelledby="tabset-referencetriggers-2-0"&gt;
&lt;pre class="language-python line-numbers linkable-line-numbers"data-line-offset="0"&gt;
&lt;code&gt;from flask import Flask, request
app = Flask(__name__)
@app.route(&amp;#34;/&amp;#34;, methods=[&amp;#39;GET&amp;#39;, &amp;#39;POST&amp;#39;])
def trigger():
headers = request.headers
data = {}
if request.data:
data = request.json
# For logs the return type is an array
if isinstance(data, list):
data = {&amp;#34;logs&amp;#34;: data}
payload = {
&amp;#34;Org-Id&amp;#34;: headers.get(&amp;#39;org-id&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Organization-Name&amp;#34;: headers.get(&amp;#39;organization-name&amp;#39;, &amp;#39;&amp;#39;) or
data.get(&amp;#39;org_name&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Location-Id&amp;#34;: headers.get(&amp;#39;location-id&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Location-Name&amp;#34;: headers.get(&amp;#39;location-name&amp;#39;, &amp;#39;&amp;#39;) or
data.get(&amp;#39;location_name&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Part-Id&amp;#34;: headers.get(&amp;#39;part-id&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Part-Name&amp;#34;: headers.get(&amp;#39;part-name&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Robot-Id&amp;#34;: headers.get(&amp;#39;robot-id&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Machine-Name&amp;#34;: headers.get(&amp;#39;machine-name&amp;#39;, &amp;#39;&amp;#39;) or
data.get(&amp;#39;machine_name&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Component-Type&amp;#34;: data.get(&amp;#39;component_type&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Component-Name&amp;#34;: data.get(&amp;#39;component_name&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Method-Name&amp;#34;: data.get(&amp;#39;method_name&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Min-Time-Received&amp;#34;: data.get(&amp;#39;min_time_received&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Max-Time-Received&amp;#34;: data.get(&amp;#39;max_time_received&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Data-Type&amp;#34;: data.get(&amp;#39;data_type&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;File-Id&amp;#34;: data.get(&amp;#39;file_id&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Trigger-Condition&amp;#34;: data.get(&amp;#34;trigger_condition&amp;#34;, &amp;#39;no value&amp;#39;),
&amp;#34;Data&amp;#34;: data.get(&amp;#39;data&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Logs&amp;#34;: data.get(&amp;#39;logs&amp;#39;, &amp;#39;no value&amp;#39;)
}
print(payload)
return payload
if __name__ == &amp;#39;__main__&amp;#39;:
app.run(host=&amp;#39;0.0.0.0&amp;#39;, port=8080)&lt;/code&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4&gt;functions_framework:&lt;/h4&gt;
&lt;div id="tabset-referencetriggers-2-1" class="tab-pane" role="tabpanel" aria-labelledby="tabset-referencetriggers-2-1"&gt;
&lt;pre class="language-python line-numbers linkable-line-numbers"data-line-offset="0"&gt;
&lt;code&gt;import functions_framework
import requests
import time
@functions_framework.http
def hello_http(request):
headers = request.headers
data = {}
if request.data:
data = request.json
# For logs the return type is an array
if isinstance(data, list):
data = {&amp;#34;logs&amp;#34;: data}
payload = {
&amp;#34;Org-Id&amp;#34;: headers.get(&amp;#34;org-id&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Organization-Name&amp;#34;: headers.get(&amp;#34;organization-name&amp;#34;, &amp;#34;&amp;#34;)
or data.get(&amp;#34;org_name&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Location-Id&amp;#34;: headers.get(&amp;#34;location-id&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Location-Name&amp;#34;: headers.get(&amp;#34;location-name&amp;#34;, &amp;#34;&amp;#34;)
or data.get(&amp;#34;location_name&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Part-Id&amp;#34;: headers.get(&amp;#34;part-id&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Part-Name&amp;#34;: headers.get(&amp;#34;part-name&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Robot-Id&amp;#34;: headers.get(&amp;#34;robot-id&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Machine-Name&amp;#34;: headers.get(&amp;#34;machine-name&amp;#34;, &amp;#34;&amp;#34;)
or data.get(&amp;#34;machine_name&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Component-Type&amp;#34;: data.get(&amp;#34;component_type&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Component-Name&amp;#34;: data.get(&amp;#34;component_name&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Method-Name&amp;#34;: data.get(&amp;#34;method_name&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Min-Time-Received&amp;#34;: data.get(&amp;#34;min_time_received&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Max-Time-Received&amp;#34;: data.get(&amp;#34;max_time_received&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Data-Type&amp;#34;: data.get(&amp;#34;data_type&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;File-Id&amp;#34;: data.get(&amp;#39;file_id&amp;#39;, &amp;#34;no value&amp;#34;),
&amp;#34;Trigger-Condition&amp;#34;: data.get(&amp;#34;trigger_condition&amp;#34;, &amp;#34;no value&amp;#34;),
&amp;#34;Data&amp;#34;: data.get(&amp;#39;data&amp;#39;, &amp;#39;no value&amp;#39;),
&amp;#34;Logs&amp;#34;: data.get(&amp;#39;logs&amp;#39;, &amp;#39;no value&amp;#39;)
}
print(payload)
return &amp;#39;Received headers: {}&amp;#39;.format(payload)&lt;/code&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="troubleshooting" class="main-content-heading"&gt;
Troubleshooting
&lt;div class="copied" id="copied-troubleshooting" aria-hidden="true"&gt;
&lt;div class="copied-notification" id="copied-troubleshooting-text"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/h3&gt;&lt;p&gt;If the HTTP request Viam sends results in an error, you can see this error logged in the machine logs.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre class="language-txt "data-line-offset="0"&gt;
&lt;code&gt;9/18/2025, 12:52:59 PM error app.trigger.trigger-1 Trigger failed to notify https://testurl.com for robotPartId abc1234d-1a23-1a23-123a-1abc23d45e67. Component: N/A, Method: N/A, TriggerType: part_online, NotificationType: webhook, Error: received unretryable status code: 404 in webhook response, ResponseCode: 404&lt;/code&gt;
&lt;/pre&gt;</description></item></channel></rss>