This guide explains how to configure your app to receive trigger lifecycle callbacks from Shopify Flow. When [creating a trigger](/docs/apps/build/flow/triggers/create), configuring a lifecycle callback enables your app to receive notifications from Shopify Flow about stores using the trigger and communicate changes in workflow status (e.g., enabling or disabling a workflow) back to the app. This helps optimize app performance by ensuring that trigger-related operations are only performed for stores that actually need them. Apps must be properly configured to respond to trigger lifecycle callbacks. When a merchant attempts to enable a workflow that uses the trigger, Shopify Flow sends a lifecycle callback to the app's web server. If it doesn't promptly receive a response or receives a response with an HTTP status code that isn't `2xx`, then the merchant can't enable the workflow and make use of the trigger. > Note: > Legacy trigger discovery webhook extensions created using the Partner Dashboard are deprecated and must [migrate to the CLI](docs/apps/build/flow/migrate-legacy-extensions) before they can be edited. ## How trigger lifecycle callbacks work Trigger lifecycle callbacks contain identifying information about the trigger and the store using it and indicate whether the trigger is being used. You can use this information to track the stores that are currently using your triggers and then send trigger requests to only those stores. ### Properties The trigger lifecycle callback (HTTP POST request) is formatted in JSON and it contains the following properties: <table> <tr> <th>Property</th> <th>Data type</th> <th width="40%">Description</th> <th>Example</th> </tr> <tr> <td><code>flow_trigger_definition_id</code></td> <td>String</td> <td>The unique identifier for your Shopify Flow trigger.</td> <td>Add row to spreadsheet</td> </tr> <tr> <td><code>has_enabled_flow</code></td> <td>Boolean</td> <td>Whether the store has an enabled workflow that uses your trigger. Valid values: <ul> <li><code>true</code>: There is at least one workflow that is enabled and that uses your trigger.</li> <li><code>false</code>: There are no enabled workflows that use your trigger.</li> </ul> </td> <td>true</td> </tr> <tr> <td><code>shop_id</code></td> <td>Number</td> <td>The unique identifier for the Shopify store.</td> <td>690933842</td> </tr> <tr> <td><code>shopify_domain</code></td> <td>String</td> <td>The myshopify domain of the Shopify store.</td> <td>johnsapparel.myshopify.com</td> </tr> <tr> <td><code>timestamp</code></td> <td><a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> date and timestamp</td> <td> <p>The time when the notification was created. Notifications with newer timestamps should take precedence. If you already have a timestamp in your datastore and you receive a newer timestamp, then overwrite this payload's information in your datastore. Conversely, if you receive a timestamp that is older than the information in your datastore, then ignore this payload.</p> </td> <td>2019-01-25T16:44:10.999Z</td> </tr> </table> The following is an example body of a usage notification (HTTP POST) request: ```json { "flow_trigger_definition_id": "Add row to spreadsheet", "has_enabled_flow": false, "shop_id": "690933842", "shopify_domain": "johnapparel.myshopify.com", "timestamp": "2019-01-25T16:44:10.999Z" } ``` ### Callback events Shopify Flow sends trigger lifecycle callbacks when the following events occur: - When a merchant activates a workflow that uses your trigger, the callback contains `"has_enabled_flow": true`. - When a merchant deactivates a workflow that uses your trigger, the callback contains `"has_enabled_flow": false`. ### Web server response time and status codes When a merchant tries to enable a workflow that uses your trigger, Shopify Flow sends a trigger lifecycle callback to your web server. If your web server doesn't respond within five seconds, or if it responds with a different status code, then the merchant can't enable that workflow. The merchant receives a notification in the Shopify Flow app that tells them to try enabling the workflow at a later time. ## 1. Configure your web server To begin, configure your web server to listen for Shopify Flow callbacks. 1. Configure a URL in your web server to listen for the trigger lifecycle callbacks from Shopify Flow. 2. Configure your web server to verify the HMAC header in the trigger lifecycle callback with your client secret. The HMAC header is located in the following HTTP header: `x-shopify-hmac-sha256`. If you are using a Ruby-based web framework, then the header is `http-x-shopify-hmac-sha256`. 3. Configure your web server to respond within 5 seconds when it receives a trigger lifecycle callback. ## 2. Process and store callback data After you've added support to listen for Shopify Flow callbacks, you can configure your web server to process and store the callback data. 1. Save the list of stores that are using your triggers in a persistent datastore. Use the <code>timestamp</code> property to make sure that you don't overwrite an existing entry with older information. 2. Edit your application to send your triggers only to stores that are using your triggers. ## 3. Configure the callback Finally, configure the callback in the CLI: 1. Run `shopify app generate extension`. 2. Select `Flow trigger lifecycle callback`. 3. Change the URL in the generated TOML to the URL configured on the web server. 4. Run `shopify app deploy`. ## Next steps - Familiarize yourself with [Shopify Flow](/docs/apps/build/flow) and learn about building connectors. - Connect your app to Shopify Flow so that events that occur in your app can [trigger workflows](/docs/apps/build/flow/triggers). - Connect your app to Shopify Flow so that your app receives data and information when a [workflow action](/docs/apps/build/flow/actions) runs.