# Welcome to MESA

We’re delighted to have you here! Whether you’re a new user or a seasoned pro, the following documents are designed to guide you through MESA and help set you up for success.

MESA unlocks the power of automation by transforming mundane tasks into cloud-based workflows that bring a touch of magic to your online store. With MESA, you can wave goodbye to manual labor and embrace a world where marketing, service, sales, and all essential processes are seamlessly automated.

## Quickstart

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>New users</strong></td><td><ul><li><a href="https://docs.getmesa.com/readme/installing-mesa">Installing MESA</a></li><li><a href="/pages/6lu1xx8sGQ8cRS8HB5jL">Core Concepts</a></li><li><a href="/pages/RYt6i8z3yYKlsDv5y906">Template Library</a></li><li><a href="/pages/cQFgGqtuzA62t7KiuTwr">Getting Help</a></li></ul></td><td></td><td><a href="/files/xw1xdM5oYbRkUUh6lKft">/files/xw1xdM5oYbRkUUh6lKft</a></td></tr><tr><td><strong>Advanced users</strong></td><td></td><td><ul><li><a href="/pages/BgoOdUt0me8qNzyhZlWq">Workflow Builder</a></li><li><a href="/pages/MXhvQ2sAg4eG2DUQEzrO">Workflow Activity</a></li><li><a href="/pages/zF7uybRHAM8QHwFk5E2v">Apps</a></li><li><a href="/pages/EhRUF74RdXzERxTaOrp5">Built-in Tools</a></li></ul></td><td><a href="/files/qXIwEPZQVq3cY23rdNL2">/files/qXIwEPZQVq3cY23rdNL2</a></td></tr><tr><td><strong>Developers</strong></td><td><ul><li><a href="/pages/pFnrDzMf8wPA7FCuQvPF">Admin API</a></li><li><a href="/pages/silqHzIzMJS7DrkKV6Ei">Command Line Interface</a></li><li><a href="/pages/xMw0SNYHR3fENPipvRID">Liquid Templating</a></li><li><a href="/pages/f8sQicgungAtnGUUJ1L0">Platform Thresholds &#x26; Limits</a></li></ul></td><td></td><td><a href="/files/8My9CpsDj47GLX3WVO5j">/files/8My9CpsDj47GLX3WVO5j</a></td></tr></tbody></table>

Before diving into our docs, check out our short introduction to MESA. This video covers the essential steps to get you started—whether you’re beginning a new project or exploring a new topic. Our goal is to give you a clear roadmap to make the most of our content and help you achieve your goals.

{% embed url="<https://www.youtube-nocookie.com/embed/fS9N1VB-lyk?rel=0>" %}


# Installing MESA

Get started with just a few easy clicks

## Install from getmesa.com

{% stepper %}
{% step %}
Navigate to <https://www.getmesa.com/pricing>
{% endstep %}

{% step %}
Select a plan to start your 7-day free trial

<figure><img src="/files/jN1nw8872YmZZxvGehCj" alt="Screenshot of the getmesa.com pricing page for starting a 7-day free trial. Spotlight a plan selection button."><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Sign up with your Google account or an email address and password

<figure><img src="/files/hHd0MB84g81yGOLIZqCv" alt="Screenshot of the MESA sign up screen offering Google account or email and password. Spotlight the sign up form."><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Enter your payment info to start your trial

<figure><img src="/files/9hmHo6kfLl5sWsATLu40" alt="Screenshot of the MESA payment info screen for starting the trial. Spotlight the payment details form."><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Tell us about yourself and get started!

<figure><img src="/files/Bz9gYrtyvsGCRkkgJnYm" alt="Screenshot of the MESA onboarding tell us about yourself form. Spotlight the get started button."><figcaption></figcaption></figure>
{% endstep %}
{% endstepper %}

## Install from Shopify

{% stepper %}
{% step %}
Navigate to <https://apps.shopify.com/mesa>
{% endstep %}

{% step %}
Click "Install" to add MESA from Shopify's App Store

<figure><img src="/files/fQiqZ31E8wIPN8ABHmdg" alt="Screenshot of the MESA listing on the Shopify App Store. Spotlight the Install button."><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Click "Install" to begin installing

<figure><img src="/files/6s3zw8PWr0mfysX2lXcN" alt="Screenshot of the Shopify install confirmation screen for MESA. Spotlight the Install button."><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Create your MESA account

<figure><img src="/files/yPAs6ZN7dvEI8zCd301R" alt="Screenshot of the Create your MESA account screen during Shopify install. Spotlight the account creation form."><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Select a plan and click "Continue" to start your 7-day free trial

<figure><img src="/files/17hJZevud3AlEl0ePRmr" alt="Screenshot of the MESA plan selection screen during Shopify install. Spotlight the Continue button."><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Pick the apps you use and press "Continue"

<figure><img src="/files/V3QpMYjlQNyLcDiRavfw" alt="Screenshot of the MESA onboarding screen for picking the apps you use. Spotlight the Continue button."><figcaption></figcaption></figure>

{% hint style="info" %}
You can always change which apps you've picked later.
{% endhint %}
{% endstep %}

{% step %}
You're ready to automate!

<figure><img src="/files/xn4h1NoDvhSxbs2RbcsB" alt="Screenshot of the MESA ready to automate welcome screen after install. Show the full dashboard view."><figcaption></figcaption></figure>
{% endstep %}
{% endstepper %}


# Dashboard

Once you've successfully installed MESA, you'll be directed to your **Dashboard** page.\
\
Here, you'll find an overview of your active workflows and template suggestions to help get you automating. If you navigate away from this page, you may return by selecting the MESA icon at the top left of your screen.

<figure><img src="/files/vBdzmpcYgZtfDIx2ozNW" alt="Screenshot of app homepage"><figcaption></figcaption></figure>

Additionally, at the bottom of your dashboard, you'll find a section for getting started with our Expert Workflow Setup service, our support links, and informative blog articles on [www.getmesa.com](https://www.getmesa.com)

<figure><img src="/files/BbNsV2J15LiANTsrDoJ2" alt="Screenshot of app homepage scrolled to the bottom"><figcaption></figcaption></figure>


# Core Concepts

**Steps** are the smallest building blocks of MESA. Every step has exactly one task to perform before handing things off to the next step, but the types of tasks are varied. For example, tasks can listen for new information ("a customer signs up"), make a decision ("does the customer live in California?"), or talk to other apps ("send them an email!"). Each step will perform its task and pass the result to the next step until MESA reaches the last one.

When you have more than one step, that sequence is collectively called a **workflow**. A workflow is made up of steps and describes a job to be done. For example, "When a customer signs up, check if they live in California, and send those that do a welcome email" is one workflow made up of three discrete steps.

MESA has hundreds of pre-built, fully customizable workflows called [**templates**](/templates). Templates can be a helpful starting point when building your own workflow, or in some cases, even used right out of the box.

The first step in a workflow is called a [**trigger**](/workflow-builder/triggers)**.** The trigger tells MESA what circumstances should cause your workflow to be executed. A trigger is either based on an event ("a customer signs up") or a schedule ("every Monday at 9 am Pacific time"). All of the steps after the trigger are called [**actions**](/workflow-builder/actions). Every workflow you create in MESA will have one trigger and one or more actions.

MESA comes with a ton of helpful triggers and actions; these are called [**tools**](/tools). MESA also has [**apps**](/connect) that bring in triggers and actions from all of the popular apps and services that e-commerce businesses need.

When a trigger tells MESA it is time to execute (or "run") your workflow, this is called an **automation**. If workflows are like a script in a play, then automations are the live performance. The automation runs through each step of a workflow in sequential order in order to complete the job you've described.


# Getting Help

## Educational Tutorials

The MESA blog hosts an extensive series of [workflow tutorials](https://www.getmesa.com/blog/category/workflow-tutorials/) that are designed to provide step-by-step guidance on automating the various aspects of your Shopify store. These tutorials are created with the intention of offering actionable insights for users at all levels of technical proficiency. Whether you are new to automation or looking to enhance your current setups, the tutorials cover a wide range of topics, from initiating your first automation workflow to integrating more sophisticated processes that complement your store's operations.

Our [YouTube channel](https://www.youtube.com/@getmesa) offers a library with hundreds of videos that walk viewers through a diverse range of popular and cutting-edge automation use cases.

We also post educational content and tutorials on Twitter, so be sure to follow us [@GetMESA](https://twitter.com/getmesa)

## Customer Success

Our MESA support team can assist you if you have questions, need help dialing in an automation, or would like help creating a workflow from scratch. Beyond reaching out to our MESA support team for general questions and inquiries, we offer several other support options based on the level of service you need.

Our friendly, knowledgeable MESA support team is available Monday - Friday, 9:00 am - 5:00 pm PT via [email](mailto:services@getmesa.com) and chat to help you with your MESA questions and inquiries. Available on all MESA plans.\
\
**Community Slack Channel**\
Join our slack community channel to get product updates, share feedback, feature requests and spark new ideas with follow MESA builders.\
\
[Click here to join](https://join.slack.com/t/mesacommunity/shared_invite/zt-2ng173hpu-USr4c7WKQcjyfCHRQd5~zA)

**Complimentary setup with a launch manager**

Work closely with your dedicated launch manager for help with simple to sophisticated workflows, from start to ongoing support. Available on the Flex, Advanced, and Unlimited plans.

✏️ Examples of what your dedicated launch manager can do with a complimentary setup:

* Personalized onboarding and ongoing support
* Brainstorm new workflow ideas

{% hint style="info" %}
When the MESA support team builds a workflow or adjusts a template on your behalf, we will confirm your workflow requirements first and then double-check that your plan supports the workflow we’ll be building. If we determine that the workflow will require an upgrade because it includes an app available on a higher plan or is a more detailed workflow than your plan allows, we’ll let you know first so you can determine if you’d like us to continue.
{% endhint %}

### Expert Workflow Setup

Let MESA's team of expert automators turn your idea into a workflow! Our Expert Workflow Setup follows our 3-step process for automation success:

1\. The process of building the workflow will begin within one business day of receiving your request, relative to having all of the information necessary to begin building your workflow. The actual amount of time from submission to workflow delivery will vary depending on the complexity of your request. You will be notified of the expected timeframe within one business day.

2\. After about one business day your workflow will be ready and our team will send you an email with directions to view, test, and turn on your new workflow.

3\. We'll walk you through the steps of your new workflow in simple, easy to understand language, so you can make adjustments and automate with confidence.

### Requesting the Expert Workflow Setup

In your MESA dashboard, scroll to the bottom of the page and click the Expert setup button to get started.

<figure><img src="/files/LGGgpENPH94VVe2O4K5N" alt="Screenshot of app homepage scrolled to the bottom with Expert setup selected"><figcaption></figcaption></figure>

You can also navigate to your account settings on the top right of the MESA app dashboard and select **Help**. You'll then need to click the **Request workflow setup** option. The Expert Workflow Setup service is currently free.

<figure><img src="/files/z1RaU0WS1bmWeAOR31P4" alt="Screenshot of the help sheet with Request workflow setup selected"><figcaption></figcaption></figure>


# Templates

## Ready-Made and Customizable

Create workflows effortlessly with MESA by starting with one of our many pre-built templates.

MESA templates are pre-built workflows featuring a trigger and one or more actions that simplify your workflow creation. They’re an ideal starting point, and because they’re fully customizable, they can easily be adapted to suit your specific requirements.

<div align="center"><img src="/files/Ds6M5oCISSTmcltVALqc" alt="Screenshot of the MESA Templates gallery showing ready-made customizable workflow templates. Spotlight the featured template cards."></div>

## Template Library

Discover the **Template Library** to find pre-designed workflows that align with your automation goals. If you’re looking for inspiration or are uncertain how or where to start, MESA's library of templates should be your go-to spot.

<figure><img src="/files/91eFaPGcjeGJ3YH6T7xp" alt="Screenshot of the MESA Template Library page listing pre-designed workflow templates. Spotlight the template cards grid."><figcaption></figcaption></figure>

Once you've selected a template to try, click **View** for details or hit **Add template** to dive in.

<figure><img src="/files/oCXVynvEcPuFEV2YS1JF" alt="Screenshot of a template in the MESA Template Library showing the View and Add template options. Spotlight the Add template button."><figcaption></figcaption></figure>

## Installing & Editing

### Setting Up <a href="#installing-a-pre-built-workflow-template" id="installing-a-pre-built-workflow-template"></a>

Let's install a template together! One popular MESA use case is tagging customers as "VIP" after they spend $500 or more.

After selecting "Start with this templat&#x65;**,**" you'll be directed to a screen highlighting the workflow's details.

<figure><img src="/files/z2L2LDWGcnC2yy0PfQZa" alt="Screenshot of the workflow details screen shown after selecting Start with this template. Spotlight the workflow details panel."><figcaption></figcaption></figure>

This template uses our setup wizard, which helps walk you through the next steps of setting up and making any adjustments to this template.

{% hint style="info" %}
Some templates will have setup instructions instead of a setup wizard. If so, you'll be taken straight to the workflow builder.
{% endhint %}

For example, you can change $500 to $1,000 based on your VIP program. Don't want to call them a "VIP"? You can also customize that tag!

<figure><img src="/files/iX91oLUP3MIJjjB84g5p" alt="Screenshot of the setup wizard for the VIP customer tagging template where the spend amount and VIP tag can be changed. Spotlight the spend amount and tag fields."><figcaption></figcaption></figure>

You can select **More Options** within each step to further customize the step with optional fields.

<figure><img src="/files/0qRbXCmdqt5qsV1Ync4F" alt="Screenshot of a template step in the setup wizard with optional fields available. Spotlight the More Options link."><figcaption></figcaption></figure>

In this example, we are adding additional rules to the **Filter** step:

<figure><img src="/files/XKw0k1rkxW1W8JdODimT" alt="Screenshot of the Filter step in the template setup with additional rules being added. Spotlight the add rule controls."><figcaption></figcaption></figure>

Perhaps the template is close, but not quite how you want it. You can add or remove steps from any template to customize it to your requirements.

For example, if you wanted to to add an extra step to notify the customer, you could add an **Email** step to the end of the workflow.

<figure><img src="/files/T382BpxUpYVfgCCMA813" alt="Screenshot of the workflow builder with an Email step added to the end of the VIP tagging workflow. Spotlight the new Email step."><figcaption></figcaption></figure>

Alternatively, if tagging the customers is irrelevant to your process, you can even completely remove the **Customer Add Tag** step to replace it with an entirely different step that would fit your needs.

<figure><img src="/files/CgaEGrVNjLn92MUtQUWS" alt="Screenshot of the workflow builder showing the Customer Add Tag step that can be removed or replaced. Spotlight the Customer Add Tag step remove option."><figcaption></figcaption></figure>

For example, you can replace the **Customer Add Tag step** to send information over to a Google Sheet. Hover over the arrow where you want to add the step, then select **Action**.

<figure><img src="/files/bbk02qIH3JUE2UjSDEXn" alt="Screenshot of the workflow builder while hovering over the add arrow between steps. Spotlight the Action button."><figcaption></figcaption></figure>

When the search bar pops up, you can search for Google to populate the different actions offered for it.

<figure><img src="/files/Iu32KBriK70H8jk0HvKn" alt="Screenshot of the workflow builder action search bar with Google typed in showing the available Google actions. Spotlight the search results list."><figcaption></figcaption></figure>

If you already have a Google Sheet that you would like to use, you can select the **Add Row** action.

<figure><img src="/files/baYChjyF4dREHQ6UQB5u" alt="Screenshot of the Google Sheets actions list in the workflow builder. Spotlight the Add Row action."><figcaption></figcaption></figure>

Once you've completed setting up the template to fit your needs, you are ready to [**run a test**](/workflow-builder/testing)**.** 🎉

<figure><img src="/files/3WQtyqigCmbEC1D9StXF" alt="Screenshot of the completed template workflow in the builder, ready to run a test. Spotlight the Test button."><figcaption></figcaption></figure>

### Resources

There will be corresponding instructions for each template offered in our library to help provide guidance.

<figure><img src="/files/jtEG7Az8Vh1nVynFTSri" alt="Screenshot of a template workflow with its setup instructions shown on the right-hand side. Spotlight the instructions panel."><figcaption></figcaption></figure>

These instructions will appear on the right-hand side of the screen or when you select "[Help](https://www.getmesa.com/support)" while in the workflow.

<figure><img src="/files/9zWtfxtWRVCz8X3sGA6K" alt="Screenshot of a template workflow in the builder where the setup instructions can be reopened. Spotlight the Help link."><figcaption></figcaption></figure>


# Template Library

The **Template library** allows you to search and find a pre-designed workflow template to align with your automation goals. If you’re unsure about where to begin, it’s a great place to get started with automation. Use the search bar to input keywords, third-party apps, or tasks you’d like to complete, and let MESA show you the templates ready for your use!

<div align="center"><img src="/files/ZUNFP5G0IZLDyMnQcjJ9" alt="New to automation, start here with the many templates built and ready for your use."></div>

Once you find a template you’re interested in, simply click **View** to see additional details or jump right in and **Add template**. The **Template library** is the lamp of automation wishes ready for you to snap your fingers to begin.

Who needs a magic carpet when you have these options? (Ok, we'd still love a magic carpet)


# Installing & Editing

## Installing a Pre-built Workflow Template <a href="#installing-a-pre-built-workflow-template" id="installing-a-pre-built-workflow-template"></a>

* Jump into the **Template library** page
* Use the search bar to type in keywords
* Select an App or Category from the left-side menu

<figure><img src="/files/uMhT9a863HhpzdRnQ7Gx" alt="Screenshot of the MESA Template library page. Spotlight the search bar and the left-side App and Category menu."><figcaption></figcaption></figure>

Once you find a template that matches your need, simply select "Add template" and you are on your way to customizing this workflow for your store.

Let's walk through installing a template together. A popular MESA use case is tagging, and for this example, we'll tag customers as a "**VIP"** after they spend $500 or more.

In the search, enter the keywords "tag customer" and also select "Shopify" as the desired app. Voila! Templates that match these keywords appear. Let's choose the template **Tag Customers with "VIP" after they spend $500 or more.**

<figure><img src="/files/NxDWLXZfHyaB7RS3iGdm" alt="Screenshot of the MESA Template library search results for the keywords tag customer with the Shopify app selected. Spotlight the Tag Customers with VIP after they spend 500 or more template card."><figcaption></figcaption></figure>

After selecting "**Add template,**" you'll be directed to a screen that highlights the details of the workflow. Feeling good about this template? Great, hit continue to start setup!

<figure><img src="/files/ZggMKKIOxiWOAPxjPhJG" alt="Screenshot of the MESA template details screen shown after selecting Add template. Spotlight the Continue button to start setup."><figcaption></figcaption></figure>

This template uses our setup wizard, which helps walk you through the next steps of customizing this template. For example, you can change $500 to $1,000 based on your VIP program. Don't want to call them a "VIP"? You can also customize that tag!

<figure><img src="/files/V4k5EYc8Ai4W4U7X1hJw" alt="Screenshot of the MESA setup wizard for the VIP tagging template, customizing the spend threshold and tag. Spotlight the customer spend amount field."><figcaption></figcaption></figure>

After you have customized the template, you are ready to **Run a test** workflow. Feel free to pause and celebrate your new workflow 🎉

<figure><img src="/files/uCnpmqAChosDuRf8cNcT" alt="Screenshot of the customized MESA workflow ready for testing. Spotlight the Run a test button."><figcaption></figcaption></figure>

All of our pre-built workflow templates come with instructions to help guide you through the setup and optional customizations. You'll find these instructions will appear on the right-hand side of the screen or when you select "[Help](https://www.getmesa.com/support)" while in the workflow.

<figure><img src="/files/4RX6he5KdBAvjRvtD4TI" alt="Screenshot of a MESA workflow with the pre-built template instructions panel on the right-hand side. Spotlight the instructions panel and the Help link."><figcaption></figcaption></figure>

{% hint style="info" %}
Note, that our setup wizard is not yet available on all templates as demonstrated above, however, if you find yourself stuck our team is here to help answer your questions. Find contact options next to the template instructions to drop us an SOS.
{% endhint %}


# Workflow Builder

The workflow builder lets you create workflows from scratch. To begin your step-by-step journey, select New workflow on the right side of the **My workflows** page.

<figure><img src="/files/KUNOl66w3HXlz47hcdLF" alt="Screenshot of the MESA My workflows page where you start building a workflow from scratch. Spotlight the New workflow button on the right side."><figcaption><p>My workflows page</p></figcaption></figure>

Clicking this blue button will open the **workflow builder**, where you can design and edit your custom workflow.

If you install a [Template](/templates), the workflow comes pre-built and the steps populate automatically. Selecting the installed template on the **My workflows** page will open the builder, where you can expand each step and make any necessary changes.

## Adding your trigger

The trigger is the first step in your workflow, which describes the event that needs to occur for your workflow to run. When building a new workflow, you'll see a list of apps to choose from. As you can see below, MESA integrates with numerous third-party apps.

<figure><img src="/files/KshaLVJ4Fdy95Iwxdnyd" alt="Screenshot of the MESA workflow builder adding a trigger, showing the list of third-party apps to choose from for the first step. Spotlight the app selection list."><figcaption></figcaption></figure>

Once the app is selected, a list of events displays. You can browse the pre-populated list or use the filter field to search for a specific trigger. Here is an example of what displays when the Shopify app is chosen.

<figure><img src="/files/qVmy7WSOoopJBje0xASK" alt="Screenshot of the MESA workflow builder after selecting the Shopify app, showing the list of trigger events with a filter field. Spotlight the trigger events list and filter field."><figcaption></figcaption></figure>

Click [here](/workflow-builder/triggers) to learn more about the different types of triggers and some of our commonly used triggers.

## Adding your first action

After selecting your trigger, three options will display: **Action**, **Filter**, and **Path**

<figure><img src="/files/fx92lqxE4Q4ys8fNWXyO" alt="Screenshot of the MESA workflow builder after selecting a trigger, showing the three next-step options. Spotlight the Action, Filter, and Path options."><figcaption><p>Available options after your trigger step</p></figcaption></figure>

[**Actions**](/workflow-builder/actions) will continue the process of displaying apps that you can select an event from. Some common examples of these are adding a Shopify tag or sending an email.

[**Filter**](/tools/filter) allows you to set criteria that needs to pass in order for the workflow to proceed to the next step.

[**Paths**](/tools/paths) will split the workflow into multiple paths, where you can set criteria for each segment to run.

{% hint style="info" %}
After selecting your first action, a pop-up will suggest a pre-built template depending on the trigger and action chosen. If the proposed template is not what you're looking to achieve, feel free to click the X at the top right of the pop-up.
{% endhint %}

## Difference between tools & steps

<figure><img src="/files/CioAsftygPfti2f2Zcze" alt="Screenshot of the MESA workflow builder showing what displays when selecting Action, with the list of apps and built-in tools to add as a step. Spotlight the Action app and tool list."><figcaption><p>Here's what displays when selecting Action</p></figcaption></figure>

Our MESA team creates built-in tools in-house. These tools provide flexibility and allow you do more with your workflows. For example, you can use **Loop** to cycle through products in an order, then use **Filter** to see if a specific product was ordered.

Steps, on the other hand, are simply any trigger, action, or tool in your workflow. Every time a new block is added to the workflow, that counts as a step.

## Configuring steps

When adding an action, especially in the case of third-party apps, you'll sometimes see a sub-menu for **Setup**. Expand this to include any additional details specific to that step.

For example, the **Setup** section in the **Form** trigger is where you can edit your form, copy the Form embed code, and copy or view the Form URL.

<figure><img src="/files/htSr3XBcCtEvh0ORJO9f" alt="Screenshot of the MESA Form trigger step expanded to show the Setup sub-menu where you edit the form, copy the embed code, and copy or view the Form URL. Spotlight the Setup section."><figcaption></figcaption></figure>

## Saving changes

Once all of your steps are properly configured and everything looks complete, click **Save changes** at the top right of the page.

MESA will autosave new steps as they are added for ease of use.

When configuring a step or adding any other details to the workflow, you will see a yellow "Unsaved changes" message appear to the left of the **Save changes** button. This is a good indicator to save your workflow changes before conducting a manual run or exiting the page.

<figure><img src="/files/MOjOGEmhe5JBQtR5SMXg" alt="Screenshot of the MESA workflow builder showing the yellow Unsaved changes message next to the Save changes button at the top right. Spotlight the Save changes button."><figcaption></figcaption></figure>

## Manually run steps & Manually run the entire workflow

It is important to manually run your automation setup as a final check before activating your workflow. Manual runs can be done on a step-by-step basis, or you can manually run the entire workflow in one go.

You can manually run an individual step by selecting the blue **Run step** button at the bottom of the step.

Alternatively, select the blue **Run workflow** button at the bottom of the workflow, or at the bottom of the trigger step, to manually run your completed workflow.

For more details and step-by-step instructions on Manual Runs, follow this [link](/workflow-builder/testing).

## Enabling your workflow

Congrats on completing and successfully running your workflow!

The last step is to enable it so that it begins to run in real-time on live data. This can be done simply by toggling the Off button to On, which is located to the right of the Save Changes button.


# Triggers

A Trigger is the initial step that activates your workflow in MESA. There are various types of triggers you can utilize, each initiating workflows based on different criteria.

We'll go through the difference between each type of trigger and how to identify if your trigger is an event-based trigger or a polling trigger.

Every workflow begins with a Trigger, the spark that gets everything rolling. Here’s a rundown of the various trigger types you can play with in MESA.

## Event-Based

These triggers kickstart your workflow in response to specific events. For instance, when a Shopify order is created, the corresponding workflow runs immediately. Event-based triggers allow for real-time processing for your automation without waiting for scheduled times.

Event-Based Triggers are like the prompts that kickstart your workflows based on specific activities or actions happening.

## Polling

Certain Triggers use/offer a polling system to initiate the workflow at specific time intervals. Depending on the Trigger, you may be able to select the polling interval or it may be native to the third-party service's data send. Whoa - that's technical, so what does that mean? Every hour, or whatever frequency the polling is set at, MESA will look for any recent activity associated with the trigger and process all the updates gathered within the hour (or another time interval).

Polling triggers operate by regularly checking for new data or updates at set intervals, such as hourly. They initiate workflows based on this scheduled checking, processing all updates gathered during the interval. This ensures that changes are handled efficiently in bulk.

There is a default schedule set for a polling trigger once it's added to a workflow, but you can adjust the polling frequency in the trigger’s **Configure** submenu.

While the trigger step is open, click the **Configure** submenu, then select **More Options**. This will expand the additional setup options for the trigger where you can select the **Schedule** checkbox and reference the default frequency or change it.

<figure><img src="/files/zVo4bRs8lfwnqhCrmK9c" alt="Screenshot of a MESA polling trigger Configure submenu with More Options expanded showing the Schedule checkbox and default frequency. Spotlight the Schedule checkbox."><figcaption></figcaption></figure>

In that view, you will be shown the next time that the trigger is scheduled to run after selecting a frequency, as long as the workflow is enabled.

<figure><img src="/files/jK5QTOhFTIqeuWuUvPOc" alt="Screenshot of a MESA polling trigger Configure showing the next scheduled run time after selecting a frequency. Spotlight the next scheduled run time."><figcaption></figcaption></figure>

You can change the polling frequency you'd like by navigating to the configure step of the trigger:

<figure><img src="/files/CpHrk8zqjLMpsGZlk9oh" alt="Screenshot of a MESA polling trigger Configure step, changing the polling frequency. Spotlight the frequency selector."><figcaption></figcaption></figure>

Every hour, or whatever frequency the polling is set at, MESA will look for any recent activity associated with the trigger and process all the updates gathered within the hour (or another time interval).

{% hint style="info" %}
All polling triggers will show the scheduled frequency underneath the title of the trigger in the builder.
{% endhint %}

## Connection

For many triggers, especially those involving third-party apps, successful authentication is crucial. This process ensures MESA has the necessary permissions to access and interact with the apps used in your workflows. Please refer to our [Connections](https://docs.getmesa.com/going-further/credentials) support guide for detailed instructions on authentication.

## Other Common Triggers

### Schedule

The [**Schedule**](/tools/schedule) trigger enables scheduling automated workflows either on a recurring basis or as a one-time event. For recurring schedules, workflows can be triggered at regular intervals, such as hourly or daily. Alternatively, the one-time option triggers a workflow at a specific date and time you select, occurring just once. This feature provides flexibility in automating tasks according to precise timing requirements.

[Schedule](https://docs.getmesa.com/tools/schedule) triggers allow your workflow to run either on a recurring basis (hourly, daily, weekly) or as a one-time event at a specific date and time. This feature provides flexibility in automating tasks according to precise timing needs.

### Webhooks

[**Webhooks**](/tools/webhook) are a popular standard on the internet for sending event notifications. MESA's Webhook trigger allows you to integrate any 3rd party service that supports them, even ones that don't have an [**integration**](/connect) yet.

[Webhooks](https://docs.getmesa.com/tools/webhook) enable real-time data transfer from one application to another by sending HTTP requests to a specified URL. MESA’s Webhook Received trigger allows integration with any third-party service supporting webhooks, even if it lacks direct [integration](https://www.getmesa.com/apps).

### Web Request

While webhooks are a great way to send "back end" event notifications, [**Web Requests**](/tools/web-request) allow a "front end" web client to send data to a workflow and receive a response.

Webhooks are excellent for backend event notifications, whereas [Web Requests](https://docs.getmesa.com/tools/web-request) facilitate frontend data transfers, allowing a web client to send data to a workflow and receive responses.

### Email

The [**email**](/tools/email) trigger allows you to initiate an automation by sending an email to a unique MESA email address. The details within the email, including the subject, message body, and sender information, can be used as variables in subsequent steps of your workflow, enabling dynamic and responsive automation processes based on the content of the received email.

[Email](https://docs.getmesa.com/tools/email#trigger) triggers start workflows when an email is sent to the unique MESA address located in the trigger. The email’s subject, body, and sender information become variables in the workflow, allowing you to tailor your automation based on the received content.

### Forms

Automations can also be started every time a [**form**](/tools/forms) is filled out. The form can be hosted on a MESA URL or embedded within your site. Like email, the contents of the form will be turned into variables that can be used within your workflow to customize the actions and drive the logic.

[Form](https://docs.getmesa.com/tools/forms) triggers initiate workflows when a form is submitted, either hosted on a MESA URL or embedded within your site. Similar to email triggers, the form responses are converted into variables used to customize the workflow actions.

The [Google Forms](https://docs.getmesa.com/apps/google-forms) trigger has the same process, but it will run based on a submission received from your linked Google Form.


# Actions

An Action is any step that follows the first step in a workflow. MESA has many different actions, each with its unique functionality.

We will discuss authenticating and configuring an action, premium steps, and some of our most common actions.

Let's review an example. In this workflow, the Trigger is Shopify Order Created, and the action is **Google Sheets Add Row**.

<figure><img src="/files/xQBQFfOTSoVv8TATqq7G" alt="Screenshot of a MESA workflow with a Shopify Order Created trigger followed by a Google Sheets Add Row action. Spotlight the Google Sheets Add Row action step."><figcaption></figcaption></figure>

## Connection

Many MESA actions require a successful connection, especially those involving third-party apps. If the action has a sub-menu called Authenticate or Authenticated, link your connections to that app. Please refer to our [Connections](https://docs.getmesa.com/going-further/credentials) support guide for detailed instructions on how to do this.

## Configuring Actions

To set up your action, open the **Configure** sub-menu:

<figure><img src="/files/qryjvqdFq8mMDuEtARAC" alt="Screenshot of an action step in the MESA workflow builder with the Configure sub-menu open. Spotlight the Configure sub-menu."><figcaption></figcaption></figure>

Configuring an action involves filling out [Fields](/workflow-builder/fields) specific to that step. Required fields will be marked with a red asterisk.

## Premium steps

Premium steps include Email, SMS, Image, Weather, and AI actions. Since we incur the cost for these steps, we limit the number of Premium steps we provide for free. Follow [this link](/going-further/plans-and-billing#premium-steps) to see how many premium credits come with your plan and how these credits are applied.

## Mid-workflow actions

Some actions will not complete a workflow because they are used to connect other actions. These actions include steps retrieving data (Retrieve Order, Customer, etc.), Filter, Loop, Delay, or Virtual Output steps.

## Paths

[Paths](#paths) allow you to split a workflow into multiple segments based on specific criteria. This tool lets you account for different scenarios in your process. For instance, if a customer orders Product A, do this, if a customer orders Product B, do something else.

## Other Common Actions

### Filter

The [filter](/tools/filter) action allows you to create one or more `if/then` statements. If the condition is met, the workflow will proceed to the next step in the workflow. Otherwise, the automation will stop.

### Loop

With the [loop](/tools/loop) action, you can iterate over items in a list. A common example is looping over products, referred to as line items, in an order.

### Delay

The [Delay](/tools/delay) step will pause your workflow for a specific time interval before continuing. We recommend using a retrieve action (e.g., "Retrieve Order") *after* a delay step to ensure you retrieve the most up-to-date details.

### Data

The [data](/tools/data) action provides an easy way to store and retrieve information during your automation runs. With a PostgreSQL structure, the data action can support advanced queries for custom databases.

### Approvals

The [approval](/tools/approvals) action halts execution where the approval is added and will not proceed until a human manually "approves" it by clicking a button on the workflow's Approvals tab. This can be helpful if you want an editor to review a title or description before posting.

### API

Like our [Webhook](/tools/webhook) trigger, MESA's [API](/tools/api) actions provide a way to connect with 3rd party services that do not have a supported [integration](/connect).

### Custom Code

The [Custom Code](/tools/custom-code) action allows you to write and execute custom scripts within your workflow. This step is useful for adding specialized logic or functionality, such as data manipulation or external API calls.

### Transform

The [transform](/tools/transform) action provides an easy way to convert fields using key-value pairs to be used later in your workflow.

### Virtual Output

[Virtual Output](/tools/virtual-output) allows you to batch multiple events into one subsequent automation. This lets you automate a group of tasks at once, for example, creating a file of the days' orders or automatically sending an email with all products added in the last thirty days.


# Fields

Fields are powerful features that simplify the configuration of actions and triggers by capturing data. Each field is crafted with care including a field name, field label, and field placeholder.

### Required vs. Optional Fields

When referencing a field in your workflow's steps, you'll want to identify whether it's a required or optional field. All required fields are marked with a red asterisk.

To ensure the workflow is completed successfully, please make sure to fill in any required fields you see in a step. Your attention to these details will help you move forward smoothly!

## Text

Text fields are a key feature in MESA, making configuration a breeze. The field name sets up the configuration, the field label gives clear details on how to use it, and the placeholder offers a handy example of the expected input. Here’s a great example of a text field in action:

<figure><img src="/files/H3CCgYes6fHgT6UKohxF" alt="Screenshot of an example text field in a MESA step showing the field name, label, and placeholder, spotlight the text field input."><figcaption></figcaption></figure>

## Drop-down Menus

Drop-down menu fields are fantastic for selecting from a list of predefined options. You'll recognize them by the arrow pointing down at the end of the field. There are a few different kinds of drop-down menus within steps:

**Typeahead**

The drop-down menu shows suggestions as you type, letting you quickly choose from a list of matching options.

**Select List**

The drop-down menu with predefined options will appear for you to select from. Here is an example of where to select:

<figure><img src="/files/ShQ3GFCkFAoSb6qkQof2" alt="Screenshot of a Select List drop-down menu field in a MESA step with its predefined options open, spotlight the drop-down menu."><figcaption></figcaption></figure>

**Custom Value**

In certain instances, you will want to use a [variable](/workflow-builder/fields/variables) from a previous step or a hard-coded value that did not appear in the drop-down list. Simply select "Enter custom product ID" to access the variable selector or enter your own custom value:

<figure><img src="/files/mX1Xq3hTvOCR1SuTUbKh" alt="Screenshot of a Custom Value drop-down field in a MESA step, spotlight the Enter custom product ID option."><figcaption></figcaption></figure>

**Custom Option with a Text Input**

<figure><img src="/files/1p3uWTi7Q1XjORlOUI02" alt="Screenshot of a Custom Value drop-down field in a MESA step with a custom text input open, spotlight the custom text input."><figcaption></figcaption></figure>

**Custom Option with a Variable**

<figure><img src="/files/lFxr9SPlElZsCIxDugwB" alt="Screenshot of a Custom Value drop-down field in a MESA step using the variable selector, spotlight the selected variable."><figcaption></figcaption></figure>

**Multi-select List**

The drop-down menu allows you to pick more than one option from a list

**Boolean**

The drop-down menu lets you select between two options, such as "Yes" or "No" or "True" or "False."

## Files

File fields work like text fields but are designed to accept a URL. This URL needs to be publicly accessible and should not require authentication for MESA to access it. Currently, Google Drive and Dropbox URLs are not supported, and direct file uploads aren’t available in MESA. Instead, we suggest uploading your files to a service like [Shopify Files](https://help.shopify.com/en/manual/shopify-admin/productivity-tools/file-uploads) and then using the URL provided.

Here is an example file field:

<figure><img src="/files/0kXQLvhqlYSoiBlwdLCM" alt="Screenshot of an example file field in a MESA step that accepts a publicly accessible URL, spotlight the file URL input."><figcaption></figcaption></figure>

## Mapping

Mapping fields are straightforward and powerful, consisting of two parts: 'Key' and 'Value.' They’re often used to create key/value pairs from static, manually entered data. Sometimes, you’ll enter the key of a property manually while pulling the value from another service.

They’re also great for passing extra information to or from an API. When needed, mapping fields allow you to send key/value pairs, which are then converted into an object by the API.

Here is an example of the mapping fields:

<figure><img src="/files/IG48ohqgMou4V8lckTUj" alt="Screenshot of example mapping fields in a MESA step showing the Key and Value pairs, spotlight the Key and Value inputs."><figcaption></figcaption></figure>

### Additional Fields

{% hint style="info" %}
Additional fields enhance the functionality of your workflows beyond the standard capabilities MESA provides.
{% endhint %}

Sometimes, you may want to capture more specific information or add preferences. Selecting the **More Options** button allows you to add optional fields to a step. Here is an example of where to find that:

<figure><img src="/files/X6vfVVNWon4fMLxcdun7" alt="Screenshot of a MESA step where additional optional fields can be added, spotlight the More Options button."><figcaption></figcaption></figure>

<figure><img src="/files/Y4b68wHSwLBDS9ucwmTA" alt="Screenshot of a MESA step with the More Options list expanded showing the additional fields available to add, spotlight the list of additional fields."><figcaption></figcaption></figure>


# Variables

## What is a variable?

Variables are representations of data, and when a workflow runs, variables are replaced with real data. Think of variables as the stand-in for the data you want to use, and once the show begins (we hear you yelling action!) that's when the real data comes in to steal the scene.

## Find and Use Variables

Let's begin with an example! Using one of our pre-built templates, [Receive an SMS message when someone creates a fraudulent order](https://app.getmesa.com/discover/send-an-sms-message-if-a-customer-places-a-fraudulent-order). Let's look at the SMS Send Message step. Here, you can see that the **Order Created > Phone** variable is used. When this workflow runs, this will be replaced with your customer's actual phone number.

<figure><img src="/files/PNBoE2ZoWUwKD2zwLenf" alt="Screenshot of MESA workflow builder, SMS Send Message step of the fraudulent order template. Spotlight the Order Created > Phone variable in the To phone number field."><figcaption></figcaption></figure>

Where do you find the variable that fits the part? You can find the Variables menu by clicking the \[**<>]** icon in the To phone number field. A menu will be displayed on the right-hand side.

<figure><img src="/files/LkSlfsXDOFmY5DND9qhY" alt="Screenshot of MESA workflow builder, SMS Send Message step To phone number field. Spotlight the <> icon that opens the Variables menu."><figcaption></figcaption></figure>

In the right-hand menu, feel free to use the search bar for "Phone" to find the Phone variable easily.

Since the variable data comes from an earlier step in the workflow, we'll want to select the step that best fits what we're looking to use for the customer's phone number. You'll notice there are several options.

You can click open the different objects that contain the variable you searched for to decide on the best one.

In this example, it's best to select the variable **Order Created > Phone.**

<figure><img src="/files/H24pHgUAVFdOx507wsiK" alt="Screenshot of MESA workflow builder, right-hand Variables menu searched for Phone with objects expanded. Spotlight the Order Created > Phone variable."><figcaption></figcaption></figure>

Once triggered, the order data will determine the customer's phone number for the SMS notification. For example, if an order is received from Jenny Smith (555-867-5309), the workflow will send a text message to 555-867-5309 when the order is flagged as fraudulent. In this particular case, it is recommended to add your phone number so you are notified of these flagged orders.

## Advanced Variable Use

Next, we're going to get technical about variables you can create without the variable menu.

### **Using global store settings**

Use the `{{context.shop.PARAMETER}}` variables to pull in settings from your Shopify store. Some common variables:

* `{{context.shop.email}}`: Your store's contact email. Set in the General page of your Shopify settings.
* `{{context.shop.domain}}`: Your store's url. Example: [www.mystore.com](http://www.mystore.com) if you have a custom domain, mystore.myshopify.com if you have not configured a custom domain.
* `{{context.shop.myshopify_domain}}`: Your .myshopify.com domain. Example: mystore.myshopify.com.
* `{{context.shop.name}}`: Your store's name. Example: My Store.

<figure><img src="/files/l0dkZHpZJAWbqLo7Vx4b" alt="Screenshot of MESA workflow builder, field using context.shop global store settings variables. Spotlight the {{context.shop.PARAMETER}} variable in the field."><figcaption></figcaption></figure>


# Formatting Variables

Formatting variables is a way to filter and format your [variables](https://docs.getmesa.com/workflow-builder/fields/variables) that produce strings, numbers, arrays, and dates.

This is a great feature to use when you want to simplify complex data like dates produced in [ISO 8601 date and time](https://www.iso.org/iso-8601-date-and-time-format.html) formatting (2008-01-10T11:00:00) and have the values converted to a more readable format like MM/DD/YY (10/01/08).

<figure><img src="/files/rQ78hW6Qqd0pN1znYWbb" alt="Screenshot of the MESA workflow builder formatting a variable, converting an ISO 8601 date into a readable MM/DD/YY format. Spotlight the formatted date variable."><figcaption></figcaption></figure>

## How to Format Variables

To format variables, click the vertical 3-dot icon at the right of any variable to open the Step Options, then click Format.

<figure><img src="/files/UCfIkFc7n7fypTslHiN2" alt="Screenshot of the MESA workflow builder, open the Step Options with the vertical 3-dot icon on a variable. Spotlight the Format option."><figcaption></figcaption></figure>

You will then be able to format your variable's output using the formatting options that populate within the sidebar menu.

<figure><img src="/files/sc6TrhGzvjBWUr1SVemd" alt="Screenshot of the MESA workflow builder Formatting Options sidebar menu for a variable. Spotlight the formatting options in the sidebar."><figcaption></figcaption></figure>

## Formatting Options

Within the Formatting Options sidebar menu, you'll be able to adjust the value your variable produces based on its type.

<details>

<summary>Date</summary>

* **Add time:** Adds a specified amount of time to a date.
* **Format:** Converts a date into a different format.
* **Start of day:** Converts a date to the start of the day (00:00:00).
* **End of day:** Converts a date to the end of the day (23:59:59).
* **Subtract time:** Subtracts a specified amount of time from a date.
* **Time between:** Calculates the time difference between two dates.
* **Time since:** Calculates the time difference from a date to now.

</details>

<details>

<summary>String</summary>

* **Append:** Adds text to the end of a string.
* **Capitalize:** Capitalizes the first word in a string and downcases the remaining characters.
* **Downcase:** Converts all letters to lowercase.
* **Prepend:** Adds text to the beginning of a string.
* **Remove last:** Removes the last instance of a substring inside a string.
* **Replace:** Replaces all occurrences of specific text within a string.
* **Replace last:** Replaces only the last occurrence of specific text within a string.
* **Split:** Breaks a string into an array based on a separator.
* **Strip:** Removes spaces from the beginning and end of a string.
* **Strip HTML:** Removes all HTML tags from a string.
* **Upcase:** Converts all letters to uppercase.

</details>

<details>

<summary>Math</summary>

* **At least:** Ensures a number is no smaller than a set minimum.
* **At most:** Ensures a number is no larger than a set maximum.
* **Divided by:** Divides a number and keeps the same type (integer or decimal).
* **Minus:** Subtracts one number from another.
* **Plus:** Adds two numbers.
* **Round:** Rounds a number to the nearest whole number.
* **Times:** Multiplies a number by another number.

</details>

<details>

<summary>Array</summary>

* **Compact:** Removes empty values from an array.
* **Concat:** Combines two arrays into one.
* **First:** Retrieves the first item in an array.
* **Join:** Combines all of the items in an array into a single string, separated by a space.
* **Last:** Retrieves the last item in an array.
* **Map:** Extracts values from a specific property in an array of objects.
* **Size:** Returns the length of a string or the number of items in an array.
* **Sort by an array item property:** Sorts the items in an array in case-insensitive alphabetical order.
* **Sum:** Adds up all numbers in an array.

</details>

To apply your formatting, fill out one of the options based on the type you're working with and click apply.

<figure><img src="/files/ddh8DqX28XU9PwitHaRC" alt="Screenshot of the MESA Formatting Options sidebar, fill out an option based on your variable type. Spotlight the Apply button."><figcaption></figcaption></figure>

You can add multiple combinations of formatted options to create the precise variable value that you need. They will be listed in the order that you apply them within the top of the Formatting Options sidebar.

<figure><img src="/files/wS9ReDMs7nm1XeHumAOI" alt="Screenshot of the MESA Formatting Options sidebar with multiple applied format options listed in order. Spotlight the list of applied formatting options at the top."><figcaption></figcaption></figure>


# Liquid Templating

[Liquid](https://shopify.github.io/liquid/) is a popular templating language originally created by [Shopify](https://www.shopify.com) and used throughout the web. MESA uses a specialized version of Liquid that makes it easy to use and modify text or variables within your workflows.

Liquid displays dynamic content by combining objects, tags, and filters.

## Objects

In MESA, an object is created to contain the output for each step when the workflow is run. Each step has a unique key that can be referenced in later steps as a Liquid object. Objects and variables are displayed when enclosed in double curly braces: `{{` and `}}`.

{% code title="INPUT" %}

```liquid
{{shopify.customer.email}}
```

{% endcode %}

{% code title="OUTPUT" %}

```
jannette.parks@getmesa.com
```

{% endcode %}

In this case, Liquid is rendering the content of the `customer.email` property that contains the text `jannette.parks@getmesa.com.` MESA created the `shopify` object when a **Shopify Order Created** trigger with a unique key of `shopify` has been run.

## Tags

Tags create the logic and control flow for templates. The curly brace percentage delimiters `{%` and `%}` and the text that they surround do not produce any visible output when the template is rendered.

{% code title="INPUT" %}

```liquid
{% if shopify.customer.email %}
    The customer's email is {{shopify.customer.email}}
{% endif %}
```

{% endcode %}

{% code title="OUTPUT" %}

```
The customer's email is jannette.parks@getmesa.com
```

{% endcode %}

### Basic operators

Liquid includes many logical and comparison operators. You can use operators to create logic with control flow tags.

| `==`  | equals                   |
| ----- | ------------------------ |
| `!=`  | does not equal           |
| `>`   | greater than             |
| `<`   | less than                |
| `>=`  | greater than or equal to |
| `<=`  | less than or equal to    |
| `or`  | logical or               |
| `and` | logical and              |

### Contains

`contains` checks for the presence of a substring inside a string. `contains` can also check for the presence of a string in an array of strings. `contains` can only search strings. You cannot use it to check for an object in an array of objects.

### If

Executes a block of code only if a certain condition is `true`.

{% code title="INPUT" %}

```liquid
{% if shopify.customer.email == "jannette.parks@getmesa.com" %}
    Hey, I know her!
{% endif %}
```

{% endcode %}

{% code title="OUTPUT" %}

```
Hey, I know her!
```

{% endcode %}

### Unless

The opposite of `if` – executes a block of code only if a certain condition is **not** met.

{% code title="INPUT" %}

```liquid
{% unless shopify.customer.email contains "@getmesa.com" %}
    I don't know them :(
{% endunless %}
```

{% endcode %}

{% code title="OUTPUT" %}

```
I don't know them :(
```

{% endcode %}

### Elsif / else <a href="#elsif--else" id="elsif--else"></a>

Adds more conditions within an `if` or `unless` block.

### Case/when <a href="#casewhen" id="casewhen"></a>

Creates a switch statement to execute a particular block of code when a variable has a specified value. `case` initializes the switch statement, and `when` statements define the various conditions.

A `when` tag can accept multiple values. When multiple values are provided, the expression is returned when the variable matches any of the values inside of the tag. Provide the values as a comma-separated list, or separate them using an `or` operator.

An optional `else` statement at the end of the case provides code to execute if none of the conditions are met.

### Whitespace Control

By including hyphens in your Liquid tag, you can strip any unneeded whitespace (extra spaces) that may appear. Here is how to make this adjustment:

```liquid
{%- if shopify.customer.email -%}

    {{ shopify.customer.email }}
    
{%- endif -%}
```

### Comment

Allows you to leave un-rendered code inside a Liquid template. Any text within the opening and closing `comment` blocks will not be printed, and any Liquid code within will not be executed.

### Raw

Temporarily disables tag processing.

### Assign

Creates a new named variable.

{% code title="INPUT" %}

```liquid
{% assign ecomm_automation = "awesome" %}
Ecommerce automation is {{ ecomm_automation }}!
```

{% endcode %}

{% code title="OUTPUT" %}

```liquid
Ecommerce automation is awesome!
```

{% endcode %}

### For

Repeatedly executes a block of code.

{% code title="INPUT" %}

```liquid
{% for tag in product.tags %}
  {{ tag }}
{% endfor %}
```

{% endcode %}

{% code title="OUTPUT" %}

```liquid
apparel womens summer shirt sale
```

{% endcode %}

### Else

Specifies a fallback case for a `for` loop which will run if the loop has zero length.

{% code title="INPUT" %}

```liquid
{% for tag in product.tags %}
  {{ tag }}
{% else %}
  The product has no tags
{% endfor %}
```

{% endcode %}

{% code title="OUTPUT" %}

```liquid
The product has no tags
```

{% endcode %}

### Break

Causes the loop to stop iterating when it encounters the `break` tag.

### Continue

Causes the loop to skip the current iteration when it encounters the `continue` tag.

## Filters

Filters change the output of a Liquid object or variable. They are used within double curly braces `{{ }}` and are separated by a pipe character `|`. Multiple filters can be used on one output, and are applied from left to right.

{% code title="INPUT" %}

```liquid
{{ "Ecommerce automation is " | append: "awesome!" }}
```

{% endcode %}

{% code title="OUTPUT" %}

```
Ecommerce automation is awesome!
```

{% endcode %}

### abs

Returns the absolute value of a number. `abs` will also work on a string that only contains a number.

### append

Adds the specified string to the end of another string. `append` can also accept a variable as its argument.

### capitalize

Makes the first character of a string capitalized and converts the remaining characters to lowercase. Only the first character of a string is capitalized, so later words are not capitalized:

### ceil

Rounds an input up to the nearest whole number. Liquid tries to convert the input to a number before the filter is applied.

### date

Converts a timestamp into another date format.

{% code title="INPUT" %}

```liquid
{{ order.created_at | date: "%A, %B %-d" }}
```

{% endcode %}

{% code title="OUTPUT" %}

```liquid
Wednesday, July 3
```

{% endcode %}

To get the current time, pass the special word `"now"` to `date`. The store's default timezone, which is set in Shopify, will be used.

{% code title="INPUT" %}

```liquid
{{ "now" | date: "%Y-%m-%d %H:%M" }}
```

{% endcode %}

{% code title="OUTPUT" %}

```liquid
2024-07-03 16:18
```

{% endcode %}

Modifiers can be added to `now` to get a specific time in the past or future:

Yesterday

{% code title="INPUT" %}

```liquid
{{ "now -1 day" | date: "%Y-%m-%d" }}
```

{% endcode %}

Two months from now

{% code title="INPUT" %}

```liquid
{{ "now +2 months" | date: "%Y-%m-%d" }}
```

{% endcode %}

Valid units of time: `year`, `month`, `day`, `hour`, `minute`, `second`.

#### Date formatting

| Format character | Example                   | Description                                                                                                                                                                              |
| ---------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `%a`             | `Sun`                     | Weekday as locale’s abbreviated name.                                                                                                                                                    |
| `%A`             | `Sunday`                  | Weekday as locale’s full name.                                                                                                                                                           |
| `%w`             | `0`                       | Weekday as a decimal number, where 0 is Sunday and 6 is Saturday.                                                                                                                        |
| `%d`             | `08`                      | Day of the month as a zero-padded decimal number.                                                                                                                                        |
| `%-d`            | `8`                       | Day of the month as a decimal number. (Platform specific)                                                                                                                                |
| `%b`             | `Sep`                     | Month as locale’s abbreviated name.                                                                                                                                                      |
| `%B`             | `September`               | Month as locale’s full name.                                                                                                                                                             |
| `%m`             | `09`                      | Month as a zero-padded decimal number.                                                                                                                                                   |
| `%-m`            | `9`                       | Month as a decimal number. (Platform specific)                                                                                                                                           |
| `%y`             | `13`                      | Year without century as a zero-padded decimal number.                                                                                                                                    |
| `%Y`             | `2013`                    | Year with century as a decimal number.                                                                                                                                                   |
| `%H`             | `07`                      | Hour (24-hour clock) as a zero-padded decimal number.                                                                                                                                    |
| `%-H`            | `7`                       | Hour (24-hour clock) as a decimal number. (Platform specific)                                                                                                                            |
| `%I`             | `07`                      | Hour (12-hour clock) as a zero-padded decimal number.                                                                                                                                    |
| `%-I`            | `7`                       | Hour (12-hour clock) as a decimal number. (Platform specific)                                                                                                                            |
| `%p`             | `AM`                      | Locale’s equivalent of either AM or PM.                                                                                                                                                  |
| `%M`             | `06`                      | Minute as a zero-padded decimal number.                                                                                                                                                  |
| `%-M`            | `6`                       | Minute as a decimal number. (Platform specific)                                                                                                                                          |
| `%S`             | `05`                      | Second as a zero-padded decimal number.                                                                                                                                                  |
| `%-S`            | `5`                       | Second as a decimal number. (Platform specific)                                                                                                                                          |
| `%f`             | `000000`                  | Microsecond as a decimal number, zero-padded to 6 digits.                                                                                                                                |
| `%z`             | `+0000`                   | UTC offset in the form ±HHMM\[SS\[.ffffff]] (empty string if the object is naive).                                                                                                       |
| `%Z`             | `UTC`                     | Time zone name (empty string if the object is naive).                                                                                                                                    |
| `%j`             | `251`                     | Day of the year as a zero-padded decimal number.                                                                                                                                         |
| `%-j`            | `251`                     | Day of the year as a decimal number. (Platform specific)                                                                                                                                 |
| `%U`             | `36`                      | Week number of the year (Sunday as the first day of the week) as a zero-padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0.         |
| `%-U`            | `36`                      | Week number of the year (Sunday as the first day of the week) as a decimal number. All days in a new year preceding the first Sunday are considered to be in week 0. (Platform specific) |
| `%W`             | `35`                      | Week number of the year (Monday as the first day of the week) as a zero-padded decimal number. All days in a new year preceding the first Monday are considered to be in week 0.         |
| `%-W`            | `35`                      | Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0. (Platform specific) |
| `%c`             | `Sun Sep 8 07:06:05 2013` | Locale’s appropriate date and time representation.                                                                                                                                       |
| `%x`             | `09/08/13`                | Locale’s appropriate date representation.                                                                                                                                                |
| `%X`             | `07:06:05`                | Locale’s appropriate time representation.                                                                                                                                                |
| `%%`             | `%`                       | A literal '%' character.                                                                                                                                                                 |

### default

Sets a default value for any variable with no assigned value. `default` will show its value if the input is `nil`, `false`, or empty.

### divided\_by

Divides a number by another number.

### downcase

Makes each character in a string lowercase. It has no effect on strings which are already all lowercase.

### escape

Escapes a string by replacing characters with escape sequences (so that the string can be used in a URL, for example). It doesn’t change strings that don’t have anything to escape.

### escape\_once

Escapes a string without changing existing escaped entities. It doesn’t change strings that don’t have anything to escape.

### first

Returns the first item of an array.

### floor

Rounds an input down to the nearest whole number. Liquid tries to convert the input to a number before the filter is applied.

### join

Combines the items in an array into a single string using the argument as a separator.

### last

Returns the last item of an array.

### lstrip

Removes all whitespace (tabs, spaces, and newlines) from the **left** side of a string. It does not affect spaces between words.

### map

Creates an array of values by extracting the values of a named property from another object.

### minus

Subtracts a number from another number.

### modulo

Returns the remainder of a division operation.

### newline\_to\_br

Inserts an HTML line break (`<br />`) in front of each newline () in a string.

### plus

Adds a number to another number.

### prepend

Adds the specified string to the beginning of another string.

### remove

Removes every occurrence of the specified substring from a string.

### remove\_first

Removes only the first occurrence of the specified substring from a string.

### replace

Replaces every occurrence of the first argument in a string with the second argument.

### replace\_first

Replaces only the first occurrence of the first argument in a string with the second argument.

### reverse

Reverses the order of the items in an array. `reverse` cannot reverse a string.

### round

Rounds a number to the nearest integer or, if a number is passed as an argument, to that number of decimal places.

### rstrip

Removes all whitespace (tabs, spaces, and newlines) from the **right** side of a string. It does not affect spaces between words.

### size

Returns the number of characters in a string or the number of items in an array.

### slice

Returns a substring of one character or series of array items beginning at the index specified by the first argument. An optional second argument specifies the length of the substring or number of array items to be returned. String or array indices are numbered starting from 0. If the first argument is a negative number, the indices are counted from the end of the string.

### sort

Sorts items in an array in case-sensitive order.

### split

Divides a string into an array using the argument as a separator. `split` is commonly used to convert comma-separated items from a string to an array.

### strip

Removes all whitespace (tabs, spaces, and newlines) from both the left and right sides of a string. It does not affect spaces between words.

### strip\_html

Removes any HTML tags from a string.

### strip\_newlines

Removes any newline characters (line breaks) from a string.

### times

Multiplies a number by another number.

### truncate

Shortens a string down to the number of characters passed as an argument. If the specified number of characters is less than the length of the string, an ellipsis (…) is appended to the string and is included in the character count.

`truncate` takes an optional second argument that specifies the sequence of characters to be appended to the truncated string. By default this is an ellipsis (…), but you can specify a different sequence.

### truncatewords

Shortens a string down to the number of words passed as an argument. If the specified number of words is less than the number of words in the string, an ellipsis (…) is appended to the string.

`truncatewords` takes an optional second argument that specifies the sequence of characters to be appended to the truncated string. By default this is an ellipsis (…), but you can specify a different sequence.

### uniq

Removes any duplicate items in an array.

### upcase

Makes each character in a string uppercase. It has no effect on strings which are already all uppercase.

### url\_decode

Decodes a string that has been encoded as a URL.

### url\_encode

Converts any URL-unsafe characters in a string into percent-encoded characters. Note that `url_encode` will turn a space into a `+` sign instead of a percent-encoded character.

### where

Creates an array including only the objects with a given property value, or any truthy value by default.


# Manual Runs

Run some checks and give your workflow a manual run before enabling!

Manually running your workflow in MESA is an important final check of your automation setup. It allows you to see how your workflow will behave before going live with automatic runs.

You can (and should) manually run your workflow steps to confirm each one is working properly as you build. Manually running automations on a per-step basis doesn't impact the rest of the workflow and provides clarity on the order of operations as you go.

When you complete your workflow, you can manually run it from beginning to end as a final sanity check.

With access to live, example, or custom data, MESA allows you to manually run the workflow with real results directly in the builder.

## Manually Run When No Data is Available

Sometimes, you will not have any data available for the trigger you're using. If that's the case, you'll see the following message in the Manual run submenu of an open trigger:

*"**Records are required to run your workflow**"*

<figure><img src="/files/95FCqkYywKmAqQjgqdnj" alt="Screenshot of MESA workflow builder, open trigger with the Manual run submenu showing the Records are required to run your workflow message. Spotlight the message."><figcaption></figcaption></figure>

When you see this message, you will want to follow the instructions:

1. Check your connection
2. [Turn on](https://docs.getmesa.com/workflow-builder#enabling-your-workflow) your workflow
3. Perform the event in your connected app

For the example in the screenshot, you would need to create a new row in your connected Google Sheet while the workflow is enabled. After doing that, check back in on the workflow to view your available record.

## Manually Run With Your Data

Manual runs can be done with Live data, Saved data, or Advanced payloads.

Manually running your workflow with live data allows you to see the results of your automation with real examples from your store or third-party app.

The **Live records** list can be found by clicking the **Manual run** submenu in an open trigger.

<figure><img src="/files/0kJgZyE8C7evsVcWxVac" alt="Screenshot of MESA workflow builder, open trigger with the Manual run submenu. Spotlight the Live records list."><figcaption></figcaption></figure>

From there, you can choose recent records from your store's data to edit, or conduct a manual run with as-is. Clicking **View record** next to any record allows you to view and edit the data included in your run.

<figure><img src="/files/ra5efN35wDQktxo4bCW6" alt="Screenshot of MESA workflow builder, Manual run submenu Live records list. Spotlight the View record button next to a record."><figcaption></figcaption></figure>

Once a manual run is conducted with any of your records, you will see the record and information of your run populate in the **Saved data** list of the Manual run submenu. This allows you to replay the same record multiple times, or slightly alter it with different information if you choose to edit the payload.

If you'd like to manually run the workflow with your own custom JSON or raw text payload, you will want to use the JSON field found in the **Advanced** tab of the Manual run submenu.

<figure><img src="/files/mmd6TANTbYmtRtBAEw0p" alt="Screenshot of MESA workflow builder, open trigger Manual run submenu Advanced tab. Spotlight the JSON payload field."><figcaption></figcaption></figure>

{% hint style="warning" %}
Conducting a Manual run will act as if the workflow is turned on, which means the impact of the workflow outcome will be live.

For example, if you have a workflow that sends an email to the customer, you may want to set up a test order under your email address or change the email recipient field to your address instead. This will ensure that emails are not sent to your customers during manual runs.
{% endhint %}

## Manually Run Per-step

Manually running a single step can be done from the **Run step** button at the bottom of your opened action or trigger.

<figure><img src="/files/6reN1F0W0dXLIZ3aRaWD" alt="Screenshot of MESA workflow builder, opened action step. Spotlight the Run step button at the bottom."><figcaption></figcaption></figure>

The manual run will process every step through (but not beyond) the step you ran. After this initial run, the prior steps will not be re-run if they have already been run once.

The previously run values of those steps will be preserved until they are re-run.

For example, if the previous step retrieved a product, running subsequent steps will have a cached version of the product that is used for future manual runs. If the product is updated in Shopify, then the product retrieve step will have to be run again for the rest of the steps to have the updated data.

{% hint style="info" %}
You will need to manually run the workflow from the trigger step before you can run a single step.
{% endhint %}

## Manually Run Your Entire Workflow

You can manually run your completed workflow via the **Run workflow** button at the bottom of the builder or in the trigger step with the Manual run submenu opened.

<figure><img src="/files/fBsPqEerTv9Jw0FR0p9f" alt="Screenshot of MESA workflow builder. Spotlight the Run workflow button at the bottom of the builder."><figcaption></figcaption></figure>

<figure><img src="/files/UHR5L5Yxz07UMuHGuuAz" alt="Screenshot of MESA workflow builder, open trigger with the Manual run submenu opened. Spotlight the Run workflow button in the trigger step."><figcaption></figcaption></figure>

Once you begin the run, the builder will update to a view that shows the run's results on each step as they play out. By default, the manual run will stop if there is an error or if a Filter does not meet its conditions.

## View Your Results

Once your manual run has been completed, you can view the results in the steps themselves or within the workflow [Activity](https://docs.getmesa.com/workflow-activity).

<figure><img src="/files/AcncOFAjWcPyT0ZlHbH4" alt="Screenshot of MESA workflow builder after a manual run, showing the run results on each step. Spotlight the per-step results in the builder."><figcaption></figcaption></figure>

If you open a step after it has been manually run, you'll see the values associated with your run populate under the field representing the variable you're using.

<figure><img src="/files/E1a1DeJEsx7nJ7HnnjMA" alt="Screenshot of MESA workflow builder, opened step after a manual run. Spotlight the field showing the populated variable value."><figcaption></figcaption></figure>

You can also see a more detailed breakdown of your run by viewing it in the [Activity](https://docs.getmesa.com/workflow-activity) tab of your workflow.

<figure><img src="/files/5PhEqPHjtiG1Cghh3YNg" alt="Screenshot of MESA workflow Activity tab showing the manual run results. Spotlight the run in the Activity list."><figcaption></figcaption></figure>

<figure><img src="/files/GMvJWlCDgzjmXQagHwxQ" alt="Screenshot of MESA workflow Activity tab, expanded manual run showing the detailed breakdown per step. Spotlight the expanded run details."><figcaption></figcaption></figure>

## Connectors With Unique Requirements for Manual Runs

The following triggers and actions have unique processes for manual runs.

#### [Webhook](https://docs.getmesa.com/tools/webhook)

You will want to conduct a manual run with your Webhook trigger by sending a notification from your third-party application.

To check the payload coming from your third-party application, click on the **Activity** tab of your workflow in the MESA dashboard. Then expand the recent run of your workflow, click the 3 vertical dots on the right side of the **Webhook** text, and then click **Request Details**.

<figure><img src="/files/xZxGXWCuCmBhDGqTSFyY" alt="Screenshot of MESA workflow Activity tab, expand the recent run, open the three vertical dots menu on the Webhook step. Spotlight the Request Details button."><figcaption></figcaption></figure>

#### [Web Request](https://docs.getmesa.com/tools/web-request)

You will need to send a POST request to the URL, or pass in a test payload in the Advanced tab of the Manual run menu. Once you conduct a manual run, the data will be available as variables for the next steps.

<figure><img src="/files/imUaZS7uPpneKRbcXuJ7" alt="Screenshot of MESA workflow builder, Web Request trigger with the Manual run menu Advanced tab. Spotlight the test payload field."><figcaption></figcaption></figure>

#### [Forms](https://docs.getmesa.com/tools/forms)

To conduct a manual run for your Forms workflow, make sure that you enable your workflow. Locate the **Form URL** field and click on the external link icon to view your Form. Then, make a test submission.

<figure><img src="/files/zFthSL4sfbPEVuyNjNsB" alt="Screenshot of MESA workflow builder, Forms trigger. Spotlight the external link icon next to the Form URL field."><figcaption></figcaption></figure>

#### [Email](https://docs.getmesa.com/tools/email#trigger)

You can manually run the Email trigger by sending an email to the custom MESA email address associated with your step in the **Manual run** submenu while your workflow is enabled.

<figure><img src="/files/zxDpEhLZlXSJVvZfk2Nz" alt="Screenshot of MESA workflow builder, Email trigger Manual run submenu. Spotlight the custom MESA email address."><figcaption></figcaption></figure>

## Additional Notes

* Steps that send notifications ([Email](https://docs.getmesa.com/tools/email), [Slack](https://docs.getmesa.com/apps/slack), [SMS](https://docs.getmesa.com/tools/sms), etc) will execute in manual runs, providing updates to these services with the information populated in the action. We strongly recommend replacing real data with your own info if you don't want others to see the results.


# Workflow Activity

The **Activity** tab in each workflow offers a chronological list of tasks that MESA has taken on your behalf. Here, you can view the status of each automation run and the steps within the task by clicking on the **>** icon next to the dates. Reminder, you can find this tab in your workflow menu just below the title.

<figure><img src="/files/WOrDoCguUV99fQRGWOhy" alt="Screenshot of the Activity tab in a MESA workflow showing the chronological list of automation runs. Spotlight the > expand icon next to the dates."><figcaption></figcaption></figure>

## Features

There are several features within the Activity tab that you may find useful. But first, let's review the activity statuses and what they mean.

* Ready - An automation task is in the queue and ready to run.
* Error - One or more steps have experienced an error in the automation task.
* Completed - Confirmation the automation task has been completed without error.
* Paused - Automations that were not completed due to an unmet condition. For example, when an automation is triggered but does not pass the filter within the workflow to complete the next or final action.
* Replayed - An automation task that has been replayed.
* Skipped - Automation tasks that have not been run, common status for when a workflow has been turned off or when the automation limits for your plan have been met.

### Status Filter <a href="#status" id="status"></a>

Did you know? Each of the above statuses is available in the activity tab as a filter. Select the **Status** filter underneath Workflow Runs in the Activity tab.

<figure><img src="/files/GCVID7clY6PRN5ahROGH" alt="Screenshot of the Activity tab in a MESA workflow with the status options shown under Workflow Runs. Spotlight the Status filter."><figcaption></figcaption></figure>

### Timeframe <a href="#date" id="date"></a>

If you're looking for activity that occurred on or between specific dates, click **Select** **Timeframe** and **custom** to open up the date filter options.

<figure><img src="/files/ygfYDNPyAfYwjor321Ou" alt="Screenshot of the Activity tab in a MESA workflow with the date filter open. Spotlight the Select Timeframe control set to custom."><figcaption></figcaption></figure>


# Tasks

On the **Activity** tab, each automation task can have the following options: Replay from this task, Variables, Request Details, Logs, and Copy link to task. To find these task options, hover on the three dots on the right of the task and click to view the menu.

<figure><img src="/files/4adpEG4ETfB1Mfr2a61U" alt="Screenshot of the MESA Activity tab with the three dots menu open on a task, revealing the task options Replay from this task, Variables, Request Details, Logs, and Copy link to task. Spotlight the three dots task options menu."><figcaption></figcaption></figure>

## Replay from this task <a href="#replay" id="replay"></a>

Replaying from this task will copy the workflow's configuration and data into a new task that immediately runs. This is helpful if there was an issue with your Trigger/Action setup, script logic, third-party API, or if there was a minor issue with your data.

<figure><img src="/files/ILMmdHOKtARSGVBFZR5M" alt="Screenshot of the MESA Activity tab task options menu highlighting the Replay from this task action that copies the configuration and data into a new task. Spotlight the Replay from this task option."><figcaption></figcaption></figure>

Replaying a task will continue executing the rest of your workflow steps that follow the replayed step.

{% hint style="info" %}
FTP Inputs will require that the original file is copied back to the original location on the FTP server (as listed in the `source` field).
{% endhint %}

## Request Details <a href="#payload" id="payload"></a>

The Request Details of a task allows you to view the details of the data initiating the automation task.

<figure><img src="/files/SC7wPrp2HsaqNorlTh3I" alt="Screenshot of the MESA Activity tab after selecting Request Details, showing the data that initiated the automation task. Spotlight the Request Details view."><figcaption></figcaption></figure>

<figure><img src="/files/XTmkMevJlEZjq5igQdmX" alt="Screenshot of the MESA Activity tab Request Details view expanded to show the request data details for the task. Spotlight the expanded request data."><figcaption></figcaption></figure>

## Variables

Selecting the Variables option displays the data that was sent to the specific step when it ran and what variables the data offers.

<figure><img src="/files/lVYPBSNzyY2jIW2OrpnW" alt="Screenshot of the MESA Activity tab after selecting the Variables option, showing the data sent to the step and the variables it offers. Spotlight the Variables data view."><figcaption></figcaption></figure>

Variables is especially helpful when setting up new automations and testing. This option can assist in identifying the fields of available data in the steps and target the variables that match your end goal.

Expand the details by clicking the arrows in the data to view all the variables available in each listed object.

<figure><img src="/files/j6T645F4hYck4P5cW2Gk" alt="Screenshot of the MESA Activity tab Variables view with a data object expanded to reveal all available variables. Spotlight the expand arrows in the data."><figcaption></figcaption></figure>


# Troubleshooting

Learn the steps to patch up your workflow when it needs a quick fix! 🛠️

When your workflow isn't running as intended, you have the ability to troubleshoot and get things back on track.

## Where to Start

The first step to understanding what's gone wrong is to check out the [Activity tab](https://docs.getmesa.com/workflow-activity) within your workflow.

<figure><img src="/files/pvw3H29R9RSt5z0e47NH" alt="Screenshot of Create Orders from Split Fulfillments workflow. Test workflow, full run to get an error. Spotlight the Activity tab."><figcaption></figcaption></figure>

Using the Status filtering under Workflow runs, filter by "Fail."

<figure><img src="/files/P39ajdtnAyr3UoZp0Fen" alt="Screenshot of Create Orders from Split Fulfillments Activity tab, Select Status Fail, Spotlight the select."><figcaption></figcaption></figure>

Once you can see the activity runs with errors, click one to expand the details of how the automation ran for each step. When you locate the step with the error, the next goal is to understand the error.

Below are some important things to consider when viewing the error message associated with your run.

### **Did the error come from a connected app or MESA?**

* [Connected apps](https://www.getmesa.com/apps) often have their own error messaging related to API requirements associated with the service. If you have a knowledge of APIs, you can often refer to API documentation for the specific app, if it's publicly accessible, to help break down the error message.
* Errors related to MESA built-in tools are specific to MESA requirements.

### **Common types of error messages**

* ***Access denied***
  * Connection issues often provide this message, meaning you may need to check, update, or re-add your [connection](https://docs.getmesa.com/going-further/credentials) to the step.
* ***Not found (404 error)***
  * This typically occurs when a step requires an ID (e.g., Product ID, Order ID, Customer ID, etc.), but the value passed for the required ID field is invalid.
    * To troubleshoot, [look at the data](https://docs.getmesa.com/workflow-activity/tasks/troubleshooting#inspecting-tasks) sent via the requested details or variables available.
* ***Bad request***
  * This message can mean that the data being used was not accepted by the service you're using.
    * To troubleshoot, [look at the data](https://docs.getmesa.com/workflow-activity/tasks/troubleshooting#inspecting-tasks) that was sent and double-check your [connection](https://docs.getmesa.com/going-further/credentials) setup.
* ***Timeout***
  * An error message that mentions "timeout" typically means the service you're using has received too many requests within a short period of time or simply didn't process the request properly.
    * To troubleshoot these errors, you have a few recommended options:
      * [Replay](https://docs.getmesa.com/workflow-activity/tasks/replay) the activity run (and [set up automatic replay](https://docs.getmesa.com/workflow-activity/tasks/replay#automatically-replay) for error handling)
      * Contact support
      * Upgrade [your plan](https://www.getmesa.com/pricing)
* ***503 and 502 errors***
  * These errors are likely related to a temporary disruption with the service you're trying to connect to.
    * To troubleshoot, [replay](https://docs.getmesa.com/workflow-activity/tasks/replay) the activity run (and [setup automatic replay](https://docs.getmesa.com/workflow-activity/tasks/replay#automatically-replay) for error handling)

### **Look at app documentation for integration-specific errors**

* [Shopify technical error codes and explanations](https://docs.getmesa.com/apps/shopify/technical-notes#troubleshooting)

## Inspecting Tasks

Inspecting a task allows you to dive into further technical details about the step and how it ran. With this additional insight, you can help make connections to what the error message is referring to regarding your errored run.

One way to inspect a task is to view the Request details. To do this, click on the three vertical dots icon on the right-hand side of the task in the Activity to reveal the Task Options.

<figure><img src="/files/LkmINk2MU74cWxUcoUVT" alt="Screenshot of Create Orders from Split Fulfillments Activity tab, open ... menu on error, spotlight Request details button."><figcaption></figcaption></figure>

With the Request details open, you can identify what the step attempted to send and what was returned.

<figure><img src="/files/ds6yrJJyH61WpZTKKXdG" alt="Screenshot of Create Orders from Split Fulfillments Activity tab, open ... menu on error, click Request details. Spotlight side sheet."><figcaption></figcaption></figure>

The Returned Body message contains information that acknowledges the problem that created the error. Confirm whether or not this messaging makes sense compared to the information available in the Sent Body details.

Another way to breakdown activity data and determine what went wrong is to check the **Variables** from steps in the workflow prior to the step that errored. This is especially helpful if you know the error is related to a variable that didn't pass its value properly (e.g. an Order ID or Product ID variable).

To check the variables view, click on the three vertical dots icon featured on the right-hand side of a task in the Activity to reveal the Task Options.

<figure><img src="/files/rjCM1kNoY90IkBJJ82cJ" alt="Screenshot of Create Orders from Split Fulfillments Activity tab, open ... menu on error, spotlight Variables button."><figcaption></figcaption></figure>

With the variables view open, click open a step to reveal the variables associated with that step. From here, you can confirm whether or not all of the variables you used in your workflow setup passed the values you were expecting.

<figure><img src="/files/L9qW4Aw8a4zgBKT21d6j" alt="Screenshot of Create Orders from Split Fulfillments Activity tab, open ... menu on error, click Variables, spotlight Trigger (Shopify) button."><figcaption></figcaption></figure>

## Turn on Debug Logs for Additional Visibility

If you cannot resolve the error, you can perform additional troubleshooting by turning on Logging debug mode in the workflow's Activity tab.

1\. In the Activity tab, turn on **Debug logs** from the Activity Settings (three-vertical dot icon) next to the Clear button. Once you are done troubleshooting, you can turn off Debug logs mode.

<figure><img src="/files/8kETjWXpFj6geKgFmOoK" alt="Screenshot of Create Orders from Split Fulfillments Activity tab, open ... menu on trigger, spotlight the Debug logs setting."><figcaption></figcaption></figure>

2\. Scroll or search within the **Activity** tab and locate the failed task with an **Error** status on the left-hand side.

3\. Click on the checkbox to the left of the run.

4\. Replay the entire workflow from the [Trigger](https://docs.getmesa.com/workflow-builder/triggers) while Logging debug mode is turned on after clicking the arrow next to where it says "Bulk actions for 1 selection."

<figure><img src="/files/ASKaQXtH9VpCli05p1Az" alt="Screenshot of Create Orders from Split Fulfillments Activity tab, click on Bulk actions menu, spotlight Replay entire workflow."><figcaption></figcaption></figure>

5\. MESA provides a more detailed layout under the [Logs](https://docs.getmesa.com/workflow-activity/logs) page. Logs enable you to search for past tasks or to view an entire chain of actions and its information for a specific task. You click on the Task options of the desired task and select **Logs**.

<figure><img src="/files/lcmb9lDWJpNgjO0H8wZG" alt="Screenshot of Create Orders from Split Fulfillments Activity tab, open ... menu on error, spotlight Logs button."><figcaption></figcaption></figure>

Since **Logging** and **Logging debug mode** are turned on, you will see more information related to the failed task appear.

The messages with the red **Error** tag will be the most important to review.

<figure><img src="/files/0rnjeaRHIqSdkQEMMJem" alt="Screenshot of Create Orders from Split Fulfillments Activity tab, open ... menu on error, click Variables. Spotlight Logs expand arrow in the top right."><figcaption></figcaption></figure>

<figure><img src="/files/74hoDolsJCkJLfhoSrKh" alt="Screenshot of Create Orders from Split Fulfillments Activity tab, open ... menu on error, click Variables. Click Logs click arrow in the top right, screenshot the logs fullscreen page."><figcaption></figcaption></figure>

6\. Once you have made adjustments to your workflow to fix the error, you can replay the failed task.

Debug logging details will show for any new activity runs that occur after enabling debug logging, so replaying a task or running a test allows you to recover these additional details from a previous run.

You can also see your outputs by using an [Activity Log](https://docs.getmesa.com/tools/activity-log) step in your workflow for testing purposes.

## Best Practices

* [Enable failure notifications](https://docs.getmesa.com/best-practices/enable-failure-notifications) for your workflows.
* Set up [automatic replay](https://docs.getmesa.com/workflow-activity/tasks/replay#automatically-replay) for errored task runs.


# Replay

Hooray, you fixed the error in your workflow. You are the Ghostbuster of workflow errors! We recommend replaying the failed step to ensure you vanquished the error completely.

It's a quick walk-through, so let's go!

## Automatically Replay

Steps can be configured to automatically retry when there is a failure. To configure this, open the step Settings and select **Automatically replay** under Failed step handling:

<figure><img src="/files/C98ygdc1idKl34I2oaTU" alt="Screenshot of a MESA step Settings panel, configuring Failed step handling to retry on failure. Spotlight the Automatically replay option under Failed step handling."><figcaption></figcaption></figure>

This step will now be automatically replayed up to five times with an increasing delay between each try:

* After the first try: 31 second delay
* Second try: 2 minute, 32 second delay
* Third try: 5 minute, 4 second delay
* Fourth try: 10 minute, 8 second delay

{% hint style="info" %}
The [Google Sheets](/connect/google-sheets) app will automatically set the Failed step handling to **Automatically replay**. Other apps use **Log as an error in activity logs** as the default.
{% endhint %}

## Replay in your Activity Tab <a href="#replay-in-your-activity-tab" id="replay-in-your-activity-tab"></a>

In each workflow, you will find an **Activity** tab under the title. This is where the status of all your automations runs will be viewable. Go ahead and dive into that tab.

Activity for test and live workflows will appear here.

The **Activity** tab offers several ways to find and filter this view. For errors, you may select **Status** under Workflow runs and filter by **Fail** to find all automation runs with errors, or scroll down the Activity list to see where they came in within the history of your automation runs.

<figure><img src="/files/6LvMtYELIUhwlt4vsUI1" alt="Screenshot of a workflow Activity tab, using the Status filter under Workflow runs to filter by Fail and find automation runs with errors. Spotlight the Status filter set to Fail."><figcaption></figcaption></figure>

After you've updated the workflow and banished the error, click on the checkbox to the left of the run and select Replay the entire workflow after clicking the arrow next to where it says "Bulk actions for 1 selection."

<figure><img src="/files/9SE78RT0cn2dfgspLVyq" alt="Screenshot of a workflow Activity tab with a run checkbox selected, opening the Bulk actions for 1 selection menu. Spotlight the Replay the entire workflow option."><figcaption></figcaption></figure>

{% hint style="info" %}
Should you run into another error when you replay a task, the error message guides you on the next steps for troubleshooting.
{% endhint %}


# Logs

You can use Logs to search for past actions for a specific task or view an entire chain of actions for a specific task. By default, only errors will be logged for all workflows, however, additional logging can be turned on in each workflow, in the Activity tab from the Settings (three-vertical dot icon next to Clear button).

<figure><img src="/files/3sbqFKyYisqSbXKS9nMm" alt="Screenshot of a workflow Activity tab in MESA with the Settings menu (three-vertical dot icon next to the Clear button) open. Spotlight the Logging and Debug Logs toggles."><figcaption></figcaption></figure>

Our standard **Logging** will add simple log entries when each workflow task runs, including when it started, completed, and basic information from the step. Any calls to [Mesa.log.info()](https://docs.getmesa.com/tools/custom-code/sdk#vendor-mesa.js-mesa.log.info) and [Mesa.log.warn()](https://docs.getmesa.com/tools/custom-code/sdk#vendor-mesa.js-mesa.log.warn) in your custom script will also be logged.

Turning on **Debug Logs** goes further and will add log entries with the request and response payload for every API call. Any calls to [Mesa.log.debug()](https://docs.getmesa.com/tools/custom-code/sdk#vendor-mesa.js-mesa.log.debug) in your custom script will also be logged.

## **Features**

### **Search Bar**

At the bottom of the Logs, there is a search bar that allows you to put in keywords, task IDs (if you have them), and other data to search for a task.

![Keywords might be the name of the step or the response, such as "Error."](/files/EavEixoqZd6bBNMtatFo)

### Jump to date

Next to the **Search Bar**, you can jump to an action of a specific task by selecting a date and time. Once you click on **Search**, the Logs will display actions starting from the time selected. This helps sort through the log of actions for a specific task. If you want to review the whole task, scroll up to the first log.

<figure><img src="/files/UoNDaf8NgyZdlht4NjOH" alt="Screenshot of the MESA Logs with the Jump to date control open next to the Search Bar. Spotlight the date and time picker."><figcaption><p>Target logs by date and time.</p></figcaption></figure>

### **Clear**

Next to the Date Filter, you'll find the Clear button. Selecting this will clear your most recent search leading you back to the most recent action performed by a task.

### **Expand/Collapse**

You can expand the Logs screen by clicking on **Expand** in the top right-hand corner. This will allow you to view more actions on a single screen.

If you wish to view fewer actions or need to use other features from MESA, click on **Collapse**.

### Search by: Status, Task Title, Task ID

Simply click on the status of a step to see all the related actions in that sequence. You'll leave the original search and get a closer look at the details of that specific task, each marked with a unique identifier.

<figure><img src="/files/6nDuc97xYlbu8lDoQXT9" alt="Screenshot of a MESA Logs entry showing the clickable Status, Task Title (Order Created), and unique task identifier. Spotlight the status, step title, and task ID that can be clicked to drill in."><figcaption><p>Several options to drill into your logs.</p></figcaption></figure>

Clicking on **Debug**, **System,** **Info**, **Warn**, **or Error** will show you logs of similar types.

Clicking on the title of the step (Order Created above) will query the logs with a full-text search to find other logs triggered by the same Input or Output.

Clicking on the unique identifier of this task (6674c2f16c above) will show you all the logs related to this task and if the task has any children, those logs will appear as well.

### **Jumping from Logs to the Activity**

Hovering over a particular log line will also reveal a small arrow icon on the left.

<figure><img src="/files/FMjvN5Xaf5eL0vIfAB74" alt="Screenshot of the MESA Logs while hovering over a log line. Spotlight the small arrow icon that appears on the left."><figcaption><p>Don't worry, it's not the eye of Sauron.</p></figcaption></figure>

Once clicked on, this will show additional options:

<figure><img src="/files/M7lFOdIBnLqYOikvexxK" alt="Screenshot of the MESA Logs after clicking the arrow icon on a log line, showing the additional options. Spotlight the View in Activity option."><figcaption><p>Thanks, logs! We're heading back to activity.</p></figcaption></figure>

Clicking on **View in Activity** will take you to that item in activity, where you can view the request details, payload, and replay tasks. You can find more information here: [Understanding Activity Status.](/workflow-activity#status)

Clicking on the title of the workflow (in the above example: Go to Add Order Tag for Free Gift) will take you to the associated workflow.

Now you know how to get your Log on to understand automation activity details in greater detail. Don't want to hang out in logs? That's ok! Most MESA users don't spend time here, but it's good to have this knowledge in your tool kit for troubleshooting.


# Time Travel

MESA's **Time Travel** feature is a way to bring historical data through a MESA workflow.

Please ensure your workflow is set up properly and a [manual run](https://docs.getmesa.com/workflow-builder/testing) has been conducted before running Time Travel. **Using Time Travel without properly vetting and manually running a workflow can lead to unintended results.**

{% hint style="info" %}
Time Travel is currently only available for workflows using the following [triggers](https://docs.getmesa.com/workflow-builder/triggers): Shopify Order, Shopify Customer, Shopify Product, Shopify Refund, Recharge, Infinite Options, Uploadery, Tracktor, Gorgias, and Salesforce.
{% endhint %}

For our **Recharge** integration, Time Travel only supports the following triggers: Customer Created, Customer Updated, Address Created, Address Updated, Subscription Created, Subscription Updated, Onetime Created, Onetime Updated, Charge Created, Charge Updated, Order Created, Order Updated, Product Created, Product Updated.

## Running Time Travel <a href="#running-time-travel" id="running-time-travel"></a>

Navigate to the **Time Travel** menu that can be found in the Activity tab of your workflow by clicking Run a Time Travel while the workflow is enabled.

<figure><img src="/files/pc5uZJVfKmPqJ2schgjF" alt="Screenshot of a MESA workflow Activity tab with the workflow enabled, opening the Time Travel menu. Spotlight the Run a Time Travel button."><figcaption></figcaption></figure>

**Before you can run Time Travel you will need to:**

1\. [Test the workflow](/workflow-builder/testing) to make sure that the workflow will run as expected. Once you begin Time Travel, it will run to completion so errors or mistakes in the workflow could lead to unintended consequences.

See the [Is it safe to run Time Travel on my workflow?](#is-it-safe) section below for more information.

{% hint style="info" %}
Please keep in mind that at this time MESA does not have a way to *stop* the activity from processing after the time travel is underway.
{% endhint %}

2\. **Enable** the workflow.

## Is it appropriate to run Time Travel on my workflow? <a href="#is-it-safe" id="is-it-safe"></a>

The answer to this question is most likely "it depends" because of MESA's flexibility and the enormous creativity of all MESA's users! However, some short questions can quickly vet many common scenarios.

**Question:** Is my workflow's final action a blank state?

If the end goal of your workflow is something like sending information to an empty Google Sheets or a new service that you are filling out, it is **probably appropriate** to run Time Travel since information would not get duplicated or overwritten.

**Question:** Does my workflow's final action rely on "up to the second, real-time" information?

If the service or application that you are sending information to in your workflow requires up-to-date/real-time data reliability, it is **probably NOT appropriate** to send historical records with Time Travel.

**Question:** Does my workflow's final action already have information related to the historical records?

It depends on the service or application in question. But in many cases, if customer or order data already exists in the service or application, it is **probably NOT appropriate** to send historical records. A Time Travel will most likely duplicate information.

**Question:** Are my historical Shopify records newer/more up-to-date than the data at my workflow's final action?

Even though information may already exist in a service or application, what is in Shopify might be newer. Therefore, it **COULD BE appropriate** to send to the final action. In these cases, it would still be important to limit the potential impact of the Time Travel by making sure to only send recent records, or add a [Filter step](/tools/filter) to check on external data to see if it already exists.

{% hint style="info" %}
✋ If you still have questions or need help determining if Time Travel will work for your use case, please don't hesitate to reach out! Email us at **<contact@getmesa.com>**.
{% endhint %}

## Configuring a Time Travel <a href="#configure" id="configure"></a>

### Choosing a time frame <a href="#time-frame" id="time-frame"></a>

Edit the date filter to find the appropriate records for your use case.

As an optional feature, you can choose **All time** if you'd like as many orders as possible, or you can choose **Last 30 days** for all records from the last 30 days.

<figure><img src="/files/FmmylH8b8LmGLEuRMzCp" alt="Screenshot of the MESA Time Travel date filter for choosing a time frame. Spotlight the All time and Last 30 days options."><figcaption></figcaption></figure>

For **Custom**, you can select a range of dates (in your browser's timezone) for the specified records.

<figure><img src="/files/KTFFZz1oO1pt1u8Ceuld" alt="Screenshot of the MESA Time Travel date filter set to Custom for selecting a range of dates. Spotlight the Custom option."><figcaption></figcaption></figure>

<figure><img src="/files/Wamn11l4dMYjrIO2BIzw" alt="Screenshot of the MESA Time Travel Custom date range picker for selecting start and end dates in your browser&#x27;s timezone. Spotlight the date range selector."><figcaption></figcaption></figure>

### Previewing results <a href="#previewing" id="previewing"></a>

You can see potential records by clicking the **Preview** button. **It is highly recommended** to make sure that the preview reflects the time frame and number of records you chose in the filters.

<figure><img src="/files/C08ml2yC4Ck5vOBIHaXl" alt="Screenshot of the MESA Time Travel configuration showing previewed records for the chosen time frame. Spotlight the Preview button."><figcaption></figcaption></figure>

### Starting Time Travel <a href="#starting" id="starting"></a>

Once you are satisfied that your filtered values are correct, start the Time Travel by clicking the **Run Time Travel** button. The Time Travel, depending on the number of records you selected, can take anywhere from seconds to hours to complete. The Time Travel will process records from newest to oldest. Feel free to close your screen if you'd rather not wait. An email will be sent to you once your Time Travel is complete.


# Best Practices


# Set Titles & Descriptions

Context can be crucial if other members of your team are looking at workflows. The following title does not give many contexts to the function of the workflow.

## Workflow Titles

Within your workflow, there is an option to adjust the title of each step. This is oh so helpful at placing a clear and purposeful title to each step. Your future self will thank you for adding a descriptive title so you won't have to dig into the details later.

Let's fix it! Click the title of your workflow or the **Dashboard** to bring up the **Manage workflow** details options to make changes.

<figure><img src="/files/mrdUpfLF3qdQDtk9qAhH" alt="Screenshot of a workflow in the MESA Dashboard. Spotlight the workflow title used to open the Manage workflow details."><figcaption></figcaption></figure>

<figure><img src="/files/VbJW5Mu0pTm8ca8sEUrS" alt="Screenshot of the Manage workflow details options in MESA. Spotlight the workflow name field."><figcaption></figcaption></figure>

Enter your new workflow name and select **Save Changes.** Whoa, this is a much better title!

<figure><img src="/files/1CFV08BMI0lgPgh6BQ2n" alt="Screenshot of the Manage workflow details with a new workflow name entered. Spotlight the Save Changes button."><figcaption></figcaption></figure>

## Workflow Descriptions

But wait, you can add more context! You can adjust the description in the **Manage workflow** details of your workflow. While you're updating that workflow name, in the same box find the **Description** field. The text can describe the goal, the steps, or anything else that is helpful to note.

<figure><img src="/files/1jVZEO9M3JqOFYf7XmFY" alt="Screenshot of the Manage workflow details in MESA. Spotlight the Description field."><figcaption></figcaption></figure>

Hit **Save Changes** and your new description will appear on the right-hand side of your workflow **Dashboard** page in the **Details** section.

<figure><img src="/files/7WbiQwQ2DH8yRKhVLY5U" alt="Screenshot of the workflow Dashboard page after saving. Spotlight the Details section on the right-hand side showing the new description."><figcaption></figcaption></figure>

## Step Titles

Within your workflow, there is an option to adjust the title of each step. This is oh so helpful at placing a clear and purposeful title to each step. Your future self will thank you for adding a descriptive title so you won't have to dig into the details later.

To add a new step title description, select the **Settings** section within the step. Next, add your updated or new title in the **Description** box and **Save**. Bravo, you have a descriptive title for your step!

<figure><img src="/files/dXDoi2THAm5O0fJpKIaQ" alt="Screenshot of the Settings section within a workflow step in MESA. Spotlight the Description box and the Save button."><figcaption></figcaption></figure>


# Organizing Workflows

## Adding Workflows to Groups

The **Groups** feature offers a valuable way to organize your workflows effectively. By adding workflows to groups, you can categorize and arrange your automations, making them easier to find and manage.

This grouping capability is particularly beneficial as it brings organization and structure to your MESA dashboard. When you have multiple workflows, grouping them logically helps streamline your view and improves overall accessibility and efficiency when working with your automations.

To add your workflows to a group, click the plus icon next to Groups in the Workflows menu.

<figure><img src="/files/TKuKBI3aaKHMKvckQuhh" alt="Screenshot of the MESA Workflows menu. Spotlight the plus icon next to Groups."><figcaption></figcaption></figure>

Enter your group name, then click create.

<figure><img src="/files/NBQ6mAoLkMQOAhRhnuyz" alt="Screenshot of the MESA create group dialog. Spotlight the group name field and the Create button."><figcaption></figcaption></figure>

Next, locate the workflows you would like to add to the group and individually click the settings (three-vertical dot icon) to the right of the workflow title to get them added.

<figure><img src="/files/mf7K985m4Bgxer8PQQu2" alt="Screenshot of the MESA Workflows list. Spotlight the three-vertical-dot settings icon to the right of a workflow title."><figcaption></figcaption></figure>

Select the checkbox of the group that you will be adding the workflow to. De-selecting a checkbox removes the workflow from that group.

<figure><img src="/files/xfKNje5vRmH7KWC1EkDN" alt="Screenshot of the MESA workflow group selection menu. Spotlight the checkbox of the group to add the workflow to."><figcaption></figcaption></figure>

Repeat this process for each workflow that you would like to add to a group. Workflows can be associated with multiple groups at the same time.

## Accessing and Managing Groups

You will be able to see and access the groups you have created on the left side of the Workflows menu.

<figure><img src="/files/SFoaL1FY6d4OlG0EDvuq" alt="Screenshot of the MESA Workflows menu. Spotlight the list of groups on the left side."><figcaption></figcaption></figure>

You can always edit your group name or remove it completely from the group settings (three-vertical dot icon) on the right of the group title.

<figure><img src="/files/MZa9HmYjO69m561W1uX0" alt="Screenshot of the MESA Workflows menu. Spotlight the three-vertical-dot group settings icon to the right of a group title."><figcaption></figcaption></figure>


# Track Time Saved

This feature allows you to set a **Time Saved** metric. This is an excellent way to show how much work MESA has saved your team.

For example, a Google Sheets Order Export workflow saves an average of 3 minutes each time the workflow runs. If the store receives 1,000 orders in a month, this workflow would save 3,000 minutes. That's 50 hours saved that month! What would you do with hours of saved time? 🤯

You can find the **Time Saved** feature on the Dashboard page when selecting **Manage workflow** in your actions. It's the same spot you'll name and describe your workflow so you can complete all three in one magnificently organized swoop!

<figure><img src="/files/5SEBIB6srxnEIDI9JHIN" alt="Screenshot of a MESA workflow Dashboard page, open the actions menu to find the Time Saved feature. Spotlight the Manage workflow option."><figcaption></figcaption></figure>

<figure><img src="/files/lDFFD1D8EpRnjMgq5Ap3" alt="Screenshot of the MESA Manage workflow panel where you name, describe, and set the workflow metric. Spotlight the Time Saved field."><figcaption></figcaption></figure>


# Enable Failure Notifications

Your workflow may experience an error, it happens and it can be fixed. Turning on your failure notifications allows you to stay on top of any errors and troubleshoot them quickly. Failure can occur for multiple reasons and the [Logs will give more details on each failure](/workflow-activity/logs).

Also, you don't have to be in the troubleshooting business alone! Notifications can be sent to several team members by adding their email addresses to the workflow's notifications settings.

You can turn on **Notifications** and add emails in the **Dashboard** tab of your workflow. Either select the notifications box to the right of your workflow activity or **Manage Workflow**. On the Notifications tab, turn on notifications and enter the email addresses to be notified.

![Catch those workflow gremlins with notifications.](/files/qQk2L6THBFZwbYApdgaD)


# Avoid Infinite Loops

If your workflow triggers an infinite loop, it could flood your message queue, slow down workflow processing, or worse, result in large overage charges.

Workflows with an Update trigger can be at risk of causing an infinite loop in a couple different situations:

## Bi-directional sync

Consider a scenario to copy orders and keep inventory levels in sync with two workflows:

* When a Shopify order is created, create an order in Salesforce
* When a Salesforce order is created, create an order in Shopify

When a Shopify order is placed, the first workflow will run which will create a Salesforce order. This will trigger the second workflow, which will in turn trigger the first workflow. Now you have a never-ending loop of new orders.

## Workflows affecting the same object

Consider this workflow that begins with a Product updated step and contains an Update product step:

<figure><img src="/files/eEggl7RLxvjTSux8fFkt" alt="Screenshot of a MESA workflow that begins with a Product updated trigger and contains an Update product step. Spotlight the Update product step."><figcaption><p>Uh oh, how do I make it stop?!</p></figcaption></figure>

When a Shopify product is updated, this workflow will be triggered and the same product will be updated. This will in turn trigger the workflow again, which could cause he product to be updated, and so on. MESA has special handling for duplicate messages which works in most cases, but not all, depending on the updates you are making.

## Suggested structure

To avoid infinite loops, we always recommend adding a unique identifier to the object that was updated and then filtering by that identifier in the second step of your workflow. In the above example, you would add a Shopify add tag step to the end of the workflow that adds a "AI Update" tag:

<figure><img src="/files/1e1Xcb2Ehaw68tqja51s" alt="Screenshot of a MESA workflow with a Shopify Add Tag step at the end that adds an AI Update tag. Spotlight the Add Tag step."><figcaption><p>Now I know that MESA has updated the product!</p></figcaption></figure>

And then confirm that the product does not contain that tag in the second step of the workflow:

<figure><img src="/files/Z9zK6dcZapdFA7GgOuyL" alt="Screenshot of a MESA workflow Filter step confirming that the product does not contain the AI Update tag. Spotlight the Filter step condition."><figcaption></figcaption></figure>

The remedy for a bi-directional sync would be similar, but you would want to check that the tag does not exist in both workflows.

{% hint style="info" %}
This would result in your automation running twice every time the product is updated (once to make the update, and a second time to hit the filter), which should be accounted for when selecting a plan.
{% endhint %}

## Suggested structure using specific fields

If you're updating an object and don't need to read it, you can select **Only when specific fields change** to avoid infinite loops. For example, if you're updating tags but don't need to read them in the workflow, use the **Only when specific fields change** feature to include all the fields you're reading and exclude those you're not using, like tags. Doing so prevents the workflow from getting triggered when the only change is a tag modification.

In the example below, we have set a value for **Fields**. The workflow will only be triggered when the title, body html, or variants are updated. Because tags are not included in the Include Fields value, updates to the product tags will not trigger the workflow. This structure prevents the workflow from being executed twice.

<figure><img src="/files/XsONp3frEBfOhIE6G3Cz" alt="Screenshot of a MESA trigger with the Only when specific fields change option enabled. Spotlight the Fields value listing title, body html, and variants."><figcaption></figcaption></figure>


# Going Further


# Plans & Billing

Learn more about plans, account details, and billing.

### MESA billing basics <a href="#e0732525-3018-4562-a204-72ab9d1f7257" id="e0732525-3018-4562-a204-72ab9d1f7257"></a>

Common terms associated with MESA billing:

* **Tasks:** Each time your workflow is triggered, steps in the workflow begin to do something, like retrieving a Shopify order, adding a customer tag, or sending an email. If the step runs, that counts as a single task. Typically, every step in a workflow will count as a task if it runs, except Loops and Paths. These are not billable tasks.
* **Pro apps:** A selection of apps only available on select plans. These apps are available on the Pro, Unlimited, and Custom plans.
  * [Hubspot](https://docs.getmesa.com/apps/hubspot), [Odoo](https://docs.getmesa.com/apps/odoo), [Salesforce](https://docs.getmesa.com/apps/salesforce), [ChannelApe](https://docs.getmesa.com/apps/channelape), [Recharge](https://docs.getmesa.com/apps/recharge), and [Gorgias](https://docs.getmesa.com/apps/gorgias)
* **Premium tasks:** Actions associated with the following MESA tools: Email, SMS, AI, Image, and Weather are Premium tasks because we incur the cost of these. To protect ourselves from malicious behavior, we limit the number of Premium tasks we provide for free. Premium tasks are available on all plans.
* **Premium task credits:** The number of times you can use a Premium step for free in a monthly billing cycle. The amount of credits you receive depends on whether you’re on the Basic, Flex, Pro, or Unlimited plan.

### Selecting a MESA plan <a href="#ad0785c2-ad41-481c-b948-98d3dbf87114" id="ad0785c2-ad41-481c-b948-98d3dbf87114"></a>

There are several MESA plans to select from, depending on how you plan to use automation. To help you find a plan that is perfect for your needs, consider the following when making a selection:

* Access to Pro apps
* Premium tasks
* Number of tasks

**Can I downgrade my plan?**

You can change your plan at any time during the billing period from the "Account" section located in the top right of the MESA dashboard. You will only be charged for the days in which the plan was active. [Learn more](#da5b2d34-0d47-47bb-a7c7-907f24ae806e) about changing your plan.

### 7-Day plan trials <a href="#aaaf633b-2f74-4d8c-a602-57cee226851b" id="aaaf633b-2f74-4d8c-a602-57cee226851b"></a>

Discover the power of MESA with a free trial—experience it firsthand before you commit. The Basic, Flex, Pro, and Unlimited plans offer a free 7-day trial. Your trial begins as soon as you select one of these plans. During your trial, you’ll have access to all of the features that come with your plan. You can upgrade, downgrade, or cancel anytime during your trial. At the end of your 7-day trial, your billing will begin.

👋 If you downgrade your plan and you have workflows enabled, you may be asked to turn these off before continuing with your plan downgrade, depending on which features are and are not supported with your new plan.

Need more time with your trial? We understand. Request a trial extension by emailing our support team at <contact@getmesa.com>

### Premium tasks <a href="#premium-steps" id="premium-steps"></a>

Actions associated with Email, SMS, Image, Weather, and AI are Premium tasks because we incur the cost of these. We limit the number of Premium tasks we provide for free to protect ourselves from malicious behavior.

#### **How many Premium task credits come with my plan?**

* **Basic plan:** 50 credits
* **Flex plan:** 500 credits
* **Advanced plan:** 1500 credits
* **Unlimited plan:** 4500 credits
* **Affiliate plan:** 50 credits

#### **What happens if I use all of my Premium task credits?** <a href="#c1521e95-9344-41b5-a2ac-eeaa4bdc9665" id="c1521e95-9344-41b5-a2ac-eeaa4bdc9665"></a>

Your workflows and Premium actions will continue to run and perform as expected, but each additional Premium task will cost $0.02 until you upgrade your MESA plan or your monthly billing interval rolls over.

### Number of tasks <a href="#b14db974-2f16-4fb3-b538-42550393300d" id="b14db974-2f16-4fb3-b538-42550393300d"></a>

The Basic, Flex, and Pro plans include a set number of tasks that are included with your plan. Once you reach your plan limit, you will begin to incur charges for additional tasks. If your overages reach the base price of the next highest plan, you will automatically be upgraded to align your activity with the increase in tasks.

👋 The Unlimited plan offers unlimited non-premium tasks! Consider this plan if you want to run several workflows without worrying about the number of tasks running.

### Delays in a workflow <a href="#id-12345" id="id-12345"></a>

Using the Delay step allows you to delay or pause a workflow before it proceeds to a subsequent step. Delays can be set in minutes, hours, days, weeks, or months. Your MESA billing plan determines the minimum and maximum length of your delay.

* Basic plan: 15 minutes (minimum) - 30 days (maximum)
* Flex plan: 15 minutes (minimum) - 30 days (maximum)
* Advanced plan: 5 minutes (minimum) - 30 days (maximum)
* Unlimited plan: 1 minute (minimum) - 60 days (maximum)
* Affiliate plan: 1 minute (minimum) - 30 days (maximum)

### Account status <a href="#c7937cea-38ea-4d4b-9602-58a7a00b41b7" id="c7937cea-38ea-4d4b-9602-58a7a00b41b7"></a>

See which plan you’re on and manage your account details.

* Click on your name in the top right corner of the MESA app.
* Click on Account.
* You’ll see which plan you’re on (Basic, Flex, Pro, and Unlimited), the monthly or annual cost, when your next billing cycle renews, the number of non-premium and premium tasks included with your plan, and how many you have used.
* If there are any notifications pertaining to your plan, they will be visible at the top of the page.

### Changing your MESA plan <a href="#da5b2d34-0d47-47bb-a7c7-907f24ae806e" id="da5b2d34-0d47-47bb-a7c7-907f24ae806e"></a>

You can upgrade or downgrade your MESA plan at any time.

* Click on your name in the top right corner of the MESA app.
* Click on Plans.
* Select your new MESA plan.
  * Upgrading your MESA plan: You can upgrade your plan anytime by going to your Account page or the Pricing page and selecting your new plan. You will immediately have access to the features available with your new plan.
  * Downgrading your MESA plan: If you have enabled workflows with steps or Pro apps not supported by your new plan, you will need to disable those before you can continue with your plan downgrade. If you downgrade your plan in the middle of a billing cycle:
    * Monthly billing interval: Your billing will be retroactive, meaning you will only pay for the days you had the previous plan, and your new billing price will begin the day you select your new plan.
    * Annual billing interval: Your downgraded rate will be applicable at the annual billing renewal. View your Account page to see when your renewal is scheduled to occur.
    * Legacy Plans: By upgrading to our new plans, you’ll unlock advanced features designed to better support you. After upgrading, legacy plans will no longer be available.

### Annual vs. monthly billing

You can select a monthly or annual payment option for MESA. This choice affects both the amount and timing of your billing intervals:

* Annual plans cost less.
* Your plan renews automatically once a month or once a year.
* Monthly task and premium task limits still apply with an annual plan and will continue to reset on the same day each month.

### Usage charges

Usage charges apply to all monthly and annual plans. If you exceed your plan limits, your workflows will continue running, but additional tasks will incur a per-task charge. You have three options to address overages:

1. Upgrade your plan
2. Wait for your monthly task limit to reset
3. Reach overage costs equivalent to the next plan's base price, at which point your plan will automatically upgrade, resetting your task limits.

Usage charges are different for non-premium and premium tasks:

* Basic, Flex, and Pro non-premium task usage: $0.01 per additional task
* Basic, Flex, Pro, and Unlimited premium task usage: $0.02 per additional task

{% hint style="info" %}
Non-premium task usage charges are not applicable on the Unlimited plan.
{% endhint %}

### Changing your spending limit <a href="#da5b2d34-0d47-47bb-a7c7-907f24ae806e" id="da5b2d34-0d47-47bb-a7c7-907f24ae806e"></a>

If you've installed MESA via Shopify, you can set your spending limit within Shopify by taking the following steps:

1. In your Shopify admin, go to Settings → Apps and sales channels.
2. Find MESA, click the … menu, then select View details.
3. Under Billing and usage charges, click Usage charges.
4. In New app spending limit, enter your new amount.
5. Check the acknowledgment box and click Set limit.

This raises the maximum amount Shopify allows MESA to bill.

### Running a Time Travel <a href="#da5b2d34-0d47-47bb-a7c7-907f24ae806e" id="da5b2d34-0d47-47bb-a7c7-907f24ae806e"></a>

Time Travel tasks adhere to the same usage limits as if a workflow was actually running. If the total Time Travel exceeds your plan limit, you can accept overage charges or upgrade your plan to receive more tasks.

### MESA support <a href="#da5b2d34-0d47-47bb-a7c7-907f24ae806e" id="da5b2d34-0d47-47bb-a7c7-907f24ae806e"></a>

Our MESA support team can assist you if you have questions, need help dialing in a workflow, or would like help creating a workflow from scratch. In addition to reaching out to our MESA support team for general questions and inquiries, we offer several other support options based on the level of service you need.

**Support offerings**

* General support: Our friendly, knowledgeable MESA support team is available Monday through Friday, 9:00 am to 5:00 pm PST, via email and chat to help you with your MESA questions and inquiries. This service is available **on all MESA plans.**
* Expert Workflow Setup: Our MESA support team can help you personalize an existing workflow template or build workflows from scratch. [Learn more](https://www.getmesa.com/workflow-setup). This service is available **on all MESA plans.**

### Development stores

MESA has a free plan with 500 non-premium tasks per month for Shopify stores that are used exclusively for development or testing without any customer traffic. Afterward, you will need to select a plan to continue using MESA.


# Notifications

MESA offers **Notifications** you can turn on and off as needed.

Notifications will trigger failure notifications to be sent to designated email addresses in the event of an error occurring on newly created workflows.

Notifications are enabled by default when you create a workflow and will be enabled for all email addresses associated with your MESA account. You can remove emails associated with your workflow by clicking an email address that's listed under the Notifications section in the workflow's dashboard menu, and then clicking the trash can icon next to the email address in the Manage Workflow modal that pops up.

<figure><img src="/files/nhePrDoNjLiWfMubKeaR" alt="Screenshot of the MESA Manage Workflow modal Notifications section listing email addresses. Spotlight the trash can icon next to an email address."><figcaption></figcaption></figure>

You can also disable notifications by clicking the Manage Workflow link in the workflow's dashboard menu, clicking the toggle under the Notifications tab in that modal.

If your workflow's notifications are disabled, click the Get critical alerts link in the Notifications section of the Dashboard menu in a workflow, and the modal will appear, providing the ability to toggle notifications on or off.

<figure><img src="/files/y34arilAvpQAyXiYKMou" alt="Screenshot of the MESA Manage Workflow modal Notifications tab opened from the Get critical alerts link. Spotlight the notifications on and off toggle."><figcaption></figcaption></figure>

Furthermore, you can add email addresses to ensure that the appropriate team members receive these notifications.


# Connections

Safely and securely automate with the services you love 🔐

Connections are a secure way to store login information for the apps you use in MESA workflows. When using an [integrated app](https://www.getmesa.com/apps), your login information is saved as a connection, allowing you to seamlessly automate with the information associated with your account. Connections are secure connections. We do not and will not share your data.

## Using Connections

Aside from [the noted exceptions below](https://docs.getmesa.com/going-further/credentials#steps-that-dont-need-credentials), you always have the ability to create or select a connection from a workflow step.

If you click open a step in your workflow, you should see a submenu available that says **Authenticate** or **Authenticated**. If your step says *Authenticated*, it means you've already added and selected a connection. If it says *Authenticate*, it means you still need to create and add your connection.

Regardless, you can click open the submenu associated with Connection and make updates as needed.

To create a connection, click the "Connect with" button that's provided to follow the setup instructions related to the service you're connecting with.

<figure><img src="/files/dhG4Snoq51WyDdQYN0la" alt="Screenshot of a workflow step Authenticate submenu in the MESA workflow builder. Spotlight the Connect with button."><figcaption></figcaption></figure>

Once you've completed the setup instructions, your connection will be saved and the *Authenticate* submenu will change to *Authenticated*, confirming that a connection has been added.

You can also select a specific connection from the **Select** dropdown menu if multiple connections have been added.

<figure><img src="/files/PgOK7m1dPV5E1hIbIpYT" alt="Screenshot of a workflow step Connection submenu in the MESA workflow builder. Spotlight the Select dropdown for choosing a connection."><figcaption></figcaption></figure>

The next best step after adding a connection is ensuring that it works. To validate if a connection has been established properly, use our [Testing](https://docs.getmesa.com/workflow-builder/testing) functionality to confirm that the step works as intended.

If you're ever unsure about the connections you've added across your workflows, you can edit and delete them from your Connections menu via your MESA account. To get there, click **My account** from your profile in the upper-right corner of the app, and then select the **Connections** tab under the Account Details.

![Screenshot of the MESA app, click My account from your profile in the upper right corner. Spotlight the My account menu item.](/files/TIZWlWwGuR2et8o5z4lV)

![Here you will find your connections for all connected apps.](/files/EhVv3ZiL3lNsTDvlnyaT)

## Steps That Don't Need Connections

As mentioned, there are some steps that don't require you to setup a connection to use. Those steps are the following:

* [**ShopPad Apps**](https://apps.shopify.com/partners/shoppad)
* [**Shopify**](https://www.getmesa.com/apps/shopify/integrate) (if it's the same store you installed MESA on)
* [**Built-in Tools**](https://docs.getmesa.com/tools)

## Different Types of Connections

Not all connections are created equal. Here are the different types of connections you may encounter when setting up:

* **API Key / Text**
  * A secure string of characters used to authenticate with a service.
* **Key-Secret**
  * A pair of secure values, typically a key and a secret, used together to authenticate with a service.
* **Domain, Username & Password**
  * A set of login details used to securely access and connect your workflows with a specific domain or service.
* **OAuth**
  * **OAuth 1.0**
    * A secure method that uses tokens and signatures to authenticate with a service.
  * **OAuth 2.0**
    * A secure authorization method that uses tokens to grant specific access to your workflows.

## Tool and App-specific Connections

Some connections in MESA go beyond the setup mentioned above. Here's the current list of these alternative setups:

* [**FTP**](https://docs.getmesa.com/tools/ftp#/connect)
  * Connection setup involves securely entering your FTP server’s address, username, and password to connect and transfer files between your server and MESA workflows.
* [**Shopify Custom App**](https://help.shopify.com/en/manual/apps/app-types/custom-apps)
  * A unique application built specifically for your Shopify store, allowing you to add tailored features or integrations that meet your business needs without requiring the app to be listed on the Shopify App Store.


# Understanding the Queue

When a MESA automation is triggered, the request is placed in an individual queue for your store. It will appear in the Activity Log with the "Ready" status. Your store's queue is processed using a First In First Out (FIFO) methodology to ensure that the oldest messages are processed first and the sequencing of actions taking place as part of the automation run always matches the original message order. Typically, automations will run instantly, but depending on the number of pending runs in your store's queue you may experience a slight delay.

## Concurrency

To ensure proper message ordering and to prevent rate limit issues with third-party APIs, by default all stores process one automation run at a time. Depending on your MESA plan and your needs, we can increase the number of parallel queue workers for an individual store so that more automation runs can be processed per minute. We are able to increase the number of parallel queue workers for your store or for an individual workflow. Please reach out to support to make this request.

## Backlog

When your store's queue grows beyond 10,000 pending messages, your items will be placed in a bulk queue to avoid affecting other MESA users. If you are anticipating triggering a large number of workflows from a migration or a flash sale, let us know, and we can work with you to properly tune your store's processing capacity.

## Loops

[Loop](/tools/loop) steps create a new task in your workflow queue. For example, if you were to loop over an Order Created step with three line items, four messages would be processed: The original Order Created message, and then a message for each line item triggered by the loop. For this reason, if you are expecting a large volume of order runs and throughput is a priority, we recommend architecting you workflows to minimize the use to nested loops. Reach out to our support team if you have any questions.

## Time Travel

[Time Travels](/workflow-activity/time-travel) are processed separately from standard automation runs and will have no impact on the processing of live data.


# Managing Workflows

Workflows can be deleted to improve organization or when they are no longer needed. If removed by accident, these deleted workflows can also be restored.

Workflows can also be triggered directly from the Shopify admin! This feature is supported for Orders, Draft Orders, Products, and Customers in Shopify.

## Deleting a workflow

Navigate to the workflow you want to delete on the Workflows tab, select the three vertical dots to the right of the workflow title, then click Delete.

<figure><img src="/files/RAkFxISgOAHWFQfnPXub" alt="Screenshot of the Workflows tab in MESA with the three vertical dots menu open on a workflow. Spotlight the Delete option."><figcaption></figcaption></figure>

## Restoring a workflow

1. Click Deleted on the Workflows tab.

<figure><img src="/files/eY5Za3tKLVZvT2JNL7ML" alt="Screenshot of the Workflows tab in MESA. Spotlight the Deleted tab."><figcaption></figcaption></figure>

2. Locate the desired workflow, then click Restore on the far right.

<figure><img src="/files/MNIECTnKxZxNqPXRyvmt" alt="Screenshot of the Deleted workflows list in MESA. Spotlight the Restore button on the far right of a workflow."><figcaption></figcaption></figure>

{% hint style="info" %}
**Note:** Deleted workflows are stored for 30 days. After 30 days, they are permanently deleted and cannot be recovered.
{% endhint %}

## Triggering workflows from the Shopify admin

Workflows can be triggered from both the individual view and the list view in Shopify. However, the workflows must be turned on in MESA for them to run successfully. Follow the steps for Individual View to run a workflow on a single order (or other instance), and follow the steps for List View to run a workflow across multiple orders (or different instances).

### Individual view

The example below will run a workflow that sends Shopify Orders to Google Sheets from the Shopify interface.

1. Navigate to the Order, Draft Order, Product, or Customer that matches the workflow trigger.
2. Select More actions > Run MESA Workflow to run an individual Order, Draft Order, Product, or Customer.

<figure><img src="/files/er6rWP3Dzx1zH2QWHiBy" alt="Screenshot of a Shopify order page. Open the More actions menu and spotlight the Run MESA Workflow option."><figcaption></figcaption></figure>

3. Select the active workflow you want to run this on.

<figure><img src="/files/BWQbg3Oszk7BwGNIvuGA" alt="Screenshot of the Run MESA Workflow dialog in the Shopify admin. Spotlight the active workflow selection dropdown."><figcaption></figcaption></figure>

4. Click Run workflow.

<figure><img src="/files/wZoilOYrRIdrbbVIHFh8" alt="Screenshot of the Run MESA Workflow dialog in the Shopify admin. Spotlight the Run workflow button."><figcaption></figcaption></figure>

5. Optionally, select View my workflows to redirect to your workflows page in MESA.

When a workflow is triggered from the Shopify admin, you will see a badge indicating the source of the run in the workflow [Activity](https://docs.getmesa.com/workflow-activity).

<figure><img src="/files/dmiHHLNCiM4ubT72I9cv" alt="Screenshot of the MESA workflow Activity tab. Spotlight the badge indicating the run was triggered from the Shopify admin."><figcaption></figcaption></figure>

### List view

This example demonstrates how to run multiple orders on a workflow simultaneously.

1. From the list view, select one or more orders.

<figure><img src="/files/pvCJChtzIliSIWd739Mf" alt="Screenshot of the Shopify Orders list view. Spotlight the selection checkboxes for one or more orders."><figcaption></figcaption></figure>

2. Next, select the three horizontal dots to the right of Capture payments.

<figure><img src="/files/4hxxbvu9Az7jHXRSaf5U" alt="Screenshot of the Shopify Orders list view bulk actions bar. Spotlight the three horizontal dots to the right of Capture payments."><figcaption></figcaption></figure>

3. Select Run MESA Workflow under the Apps section.

<figure><img src="/files/rc3brqx1QbrT07paLErF" alt="Screenshot of the Shopify Orders list view bulk actions menu. Spotlight the Run MESA Workflow option under the Apps section."><figcaption></figcaption></figure>

4. Similar to Individual View, you can select which MESA workflow you'd like to run these orders on, then click Run workflow.
5. Optionally, select View my workflows to redirect to your workflows page in MESA.


# Export & Import Workflows

You can import and export workflows between multiple Shopify stores that have MESA installed.

### Export

To export a workflow, go into the **My workflows** page and find the workflow that you would like to export. There are two ways to export workflows:

1\. Click on the vertical three-dot icon on the right-hand side and click on **Export**. MESA will download a Zip folder onto your desktop.

<figure><img src="/files/TVrsM9SqHZF3aS7zlyb9" alt="Screenshot of the MESA My workflows page with the three-dot menu open on a workflow row, spotlight the Export option."><figcaption></figcaption></figure>

2\. You can click into the workflow and click on the **Dashboard** tab. Scroll all the way down until you see Actions. Then, you can click on **Export**. MESA will download a Zip folder onto your desktop.

<figure><img src="/files/DXXIDEzzbxWq7Wd0FMcy" alt="Screenshot of a workflow Dashboard tab in MESA scrolled to the Actions section, spotlight the Export button."><figcaption></figcaption></figure>

{% hint style="info" %}
[Connections](/going-further/credentials) are not exported. Since in most cases, Connections are unique to each Shopify store. You will need to select a connection on steps that require it once a workflow has been imported into a different store.
{% endhint %}

### Import

To import a workflow, you will need the Zip folder on your desktop. Then, head to the **My workflows** page. Click on the **Import** button under "Start with a template".

<figure><img src="/files/HDRbx1Ll4jOCHMZUQzn3" alt="Screenshot of the MESA My workflows page under Start with a template, spotlight the Import button."><figcaption></figcaption></figure>

Drag the Zip folder into the dotted box or select the MESA Export Zip folder.

<figure><img src="/files/wVtP1pkMAPsdyZiUFWSv" alt="Screenshot of the MESA workflow import screen, spotlight the dotted drop box for dragging in the MESA Export Zip folder."><figcaption></figcaption></figure>

Then, click to install the workflow! 🎉


# Platform Thresholds & Limits

### Platform Limits

| <p>FTP file size<br>10 MB</p>   | <p>Virtual Output items<br>10,000</p> | <p>Payload size<br>1 MB</p> | <p>Log message size<br>100 KB</p>  | <p>Storage size<br>100 KB</p> |
| ------------------------------- | ------------------------------------- | --------------------------- | ---------------------------------- | ----------------------------- |
| <p>Script file size<br>2 MB</p> | <p>Scripts<br>100</p>                 | <p>Outputs<br>100</p>       | <p>Storage & Secrets<br>10,000</p> | <p>Secret size<br>1 KB</p>    |

### Fair Use Policy

Plans with "unlimited" offerings give extensive access to our services, providing you with freedom and flexibility. However, to prevent abuse and ensure equitable usage for all our valued users, we have a fair use policy to be mindful of:

* Fair Use of Automations: You can run up to 5 million automations per billing cycle.
* Fair Use of Workflow Steps: You can create workflows with up to 100 steps.

This policy is meant to be generous and beyond the current limits of our most active customers. However, if you exceed this policy, your service may become degraded, delayed, or temporarily blocked. You may also receive a warning or be suspended from MESA if you continually exceed this policy without communicating with us. If you have any questions about our fair use policy, please [contact us](https://www.getmesa.com/contact).

Please note that this Fair Use Policy is subject to our [terms of service](https://www.getmesa.com/terms) and may be subject to adjustment in accordance with evolving service conditions.

### Miscellaneous

We aim to be transparent about our product packaging and the limits that apply, so we hope you find this document useful. Please note that the fees we provide here are subject to applicable taxes and that all purchases are subject to our [Terms of Service](https://www.theshoppad.com/terms) and [Privacy Policy](https://www.theshoppad.com/privacy).

We periodically update this document, so please check back here for current information.

If you have any questions, please [contact us](https://www.getmesa.com/contact).


# Built-in Tools


# Activity Log

The **Activity Log** tool allows you to log information about your workflow when it runs. This can be used to help debug issues with your setup.

Fields included in the Activity Log are:

* **Activity Message:** Label the data that you'd like to log so that you can easily recognize the Activity Log's logging. Example: Order Data.
* **Payload Value:** Add [Variables](/workflow-builder/fields/variables) that you'd like to view the data of. You are allowed to add multiple variables and characters.

<figure><img src="/files/ICpHAyZiJLJNP4Wt0a2P" alt="Screenshot of the MESA Activity Log tool step showing the Activity Message and Payload Value fields used to log workflow data. Spotlight the Activity Message and Payload Value fields."><figcaption></figcaption></figure>

Logs created from this step can be found in your workflow's **Logs** tab.

Here is an example of the logged information specified in a workflow and where you can see additional details in the logs.

<figure><img src="/files/4S9N1X3H0N34ZCeh5VtW" alt="Screenshot of the MESA Logs tab showing the logged Activity Log information from a workflow run with additional details. Spotlight the Activity Log entry in the Logs tab."><figcaption></figcaption></figure>


# AI

MESA's **AI** tool uses the power of Artificial Intelligence to automatically generate, classify, and analyze your data.

The AI tool is powered by ChatGPT and does not require an OpenAI account to access its AI functionality.

{% hint style="warning" %}
AI uses Premium tasks. [Learn more](https://docs.getmesa.com/going-further/plans-and-billing#premium-steps)
{% endhint %}

## Configure <a href="#action" id="action"></a>

### Skill triggered <a href="#action" id="action"></a>

The AI Skill triggered trigger lets you supercharge your AI prompts by calling MESA workflows to fetch information and take action.

Get started by creating a workflow in MESA with the AI Skill triggered trigger. Then, let your AI app know about the MESA AI Skill and start chatting. In the steps below, we use Claude Desktop, but AI Skill triggered also supports Cursor and many other AI apps.

### Actions <a href="#action" id="action"></a>

The AI tool includes several defined actions to quickly get you started with common tasks like summarizing, categorizing, and extracting details from your free-form text.

<figure><img src="/files/gECwX9xQDT0Hw86dXpkr" alt="Screenshot of the MESA AI tool step showing its defined actions for common tasks like summarizing, categorizing, and extracting details. Spotlight the AI action selector dropdown."><figcaption></figcaption></figure>

### Prompts <a href="#examples" id="examples"></a>

Provide a prompt to generate a text response within the AI actions. Use the examples below as a starting point. For additional specificity, replace the details in the prompts with MESA Variables from previous steps in your workflow.

![Screenshot of the MESA AI Prompt action configuration where you provide a prompt to generate a text response. Spotlight the prompt input field.](/files/ygVJ2YIGwk0QzBhfgs4u)

```
Write a tagline for an ice cream shop.
```

<figure><img src="/files/GvCuKr2tQyT7k1d43GJE" alt="Screenshot of the MESA AI Prompt action with the prompt Write a tagline for an ice cream shop. Spotlight the generated prompt output."><figcaption></figcaption></figure>

```
Write a thank you letter in the form of a poem for John Doe who purchased a Special Agent Widget.
```

<figure><img src="/files/yKCZijGY1luxkSUwZpu0" alt="Screenshot of the MESA AI Prompt action with a prompt to write a thank you letter as a poem for John Doe who purchased a Special Agent Widget. Spotlight the generated prompt output."><figcaption></figcaption></figure>

```
Write a product description for wooden clogs.
```

<figure><img src="/files/yC1xZafQGLYRQSJft2w7" alt="Screenshot of the MESA AI Prompt action with the prompt Write a product description for wooden clogs. Spotlight the generated prompt output."><figcaption></figcaption></figure>

```
Write a blog post to announce our new glow in the dark ice cream.
```

<figure><img src="/files/EHQhObBDPX7B7GqfaxSj" alt="Screenshot of the MESA AI Prompt action with a prompt to write a blog post announcing new glow in the dark ice cream. Spotlight the generated prompt output."><figcaption></figcaption></figure>

### Summarize

This AI action will generate a short summary from paragraph(s) of text.

```
Determine if this is a physical address. Return yes or no.

PO Box 100
1010 NE Main Street
Springfield, MA, 12352
```

<figure><img src="/files/aofCpjGBR6JtXIzOSryl" alt="Screenshot of the MESA AI Summarize action determining whether the PO Box 100 address is a physical address, returning yes or no. Spotlight the generated prompt output."><figcaption></figcaption></figure>

```
Determine if this address is in Europe. Return yes or no.

1010 NE Main Street
Springfield, MA, 12352
```

<figure><img src="/files/17UKqxINFWmTdDUdgRyQ" alt="Screenshot of the MESA AI Summarize action determining whether the Springfield address is in Europe, returning yes or no. Spotlight the generated prompt output."><figcaption></figcaption></figure>

```
Determine the gender of this name. Return male, female or unknown:

Alexis Doe
```

<figure><img src="/files/YEZRkmtsESzV3q7parm5" alt="Screenshot of the MESA AI Summarize action determining the gender of the name Alexis Doe, returning male, female or unknown. Spotlight the generated prompt output."><figcaption></figcaption></figure>

## Going Further <a href="#limitations" id="limitations"></a>

Check the Advanced > Convert JSON response checkbox on a Prompt step and add a [Loop](https://docs.getmesa.com/tools/loop) step to loop over each result in this prompt:

```
A two-column spreadsheet of top science fiction movies and the year of release. 

Title,
Year of release

Return as json
```

### Other Kinds of AI Steps

There are a multitude of AI actions that are more specific than Prompt or Summarize. [Click here ](https://www.getmesa.com/templates?cat=AI)for our existing AI templates for a few ideas.

If none of these actions match what you're trying to do, the Prompt action lets you use any GPT4o-style prompt to fully unlock the potential of artificial intelligence. [OpenAI's example page](https://platform.openai.com/examples/) is an excellent source of inspiration, and the [OpenAI Playground](https://platform.openai.com/playground?mode=chat\&model=gpt-4o) is the easiest way to test and perfect your prompts.

{% hint style="info" %}
We recommend adding an [Approval](https://docs.getmesa.com/tools/approvals) step in your workflow to verify that the prompt output meets your expectations. This is especially useful when fine-tuning your prompt to achieve the desired results.
{% endhint %}

### More Resources <a href="#limitations" id="limitations"></a>

* OpenAI's [Text completion docs](https://platform.openai.com/docs/guides/text-generation) provide examples and best practices around writing prompts.

## Technical Notes <a href="#limitations" id="limitations"></a>

**What is the AI tool powered by?**

The AI tool is powered by ChatGPT-4o.

**Why should you use ChatGPT (or another service like Claude) instead of MESA's AI-built-in tool?**

* ChatGPT reduces MESA premium task usage. Actions associated with Email, SMS, Image, Weather, and AI are Premium steps because we incur the cost of these.
* ChatGPT supports more advanced queries
* The AI tool only reads and generates up to 500 words of text. Input text will be truncated after 500 words, and responses will be limited to around 500 words. If you need to analyze or generate long amounts of text, we recommend using MESA's OpenAI app, which allows you to customize the number of tokens to use for each prompt. Most prompts can be copied over from an AI step to an OpenAI prompt step.
* ChatGPT allows you to use your own fine-tuned model

### How AI Uses Your Data <a href="#data-security" id="data-security"></a>

The AI tool makes API calls to OpenAI. Only the variables explicitly configured in the MESA builder will be shared with OpenAI. MESA does not store any of this information beyond your data retention date. OpenAI does not use data submitted to and generated by their API to train OpenAI models or improve OpenAI's service offering.

To opt out of any data sharing with AI models, simply do not use the AI step in any of your workflows.

Learn more about how and when OpenAI is used to train their models: [MESA's Data Processing Agreement](https://www.getmesa.com/dpa).


# Web Operator

The **Web Operator** action is a specialized action within the AI tool that allows you to interact with a remote browser instance by talking to [Yedric](https://mesa-chat.theshoppad.com/). With it, you can log into a system, extract data, or take actions directly in the browser, and then turn that flow into an automation.

## Configure

### Extracting Data Example

The following tutorial explains how to use the Web Operator via Gmail to automate gathering the 10 most recent emails from your inbox.

{% embed url="<https://www.youtube-nocookie.com/embed/bnpj0Q6XVg0?rel=0>" %}

#### Setup

{% stepper %}
{% step %}
Add the Web Operator step to your workflow.
{% endstep %}

{% step %}
Click the **Build Web Operator instructions** with Yedric button within the Web Operator step to launch Yedric.
{% endstep %}

{% step %}
Tell Yedric exactly what you want to do in the service you're using.

* For this example, the prompt is: "*Can you login to my Gmail account and list the 10 most recent emails in my inbox, including sender, subject, and the time received?*"
  {% endstep %}

{% step %}
Use the browser session Yedric creates to log in to the service.
{% endstep %}

{% step %}
Once logged in, tell Yedric to continue.

{% hint style="info" %}
Slow load times should be expected as Yedric processes the output. Refer to the [Technical Notes](https://docs.getmesa.com/tools/ai/web-operator#technical-notes) below for more details.
{% endhint %}
{% endstep %}

{% step %}
After Yedric provides your results, review them to ensure that all of the information is accurate.
{% endstep %}

{% step %}
Once you've confirmed Yedric has provided accurate results based on your instructions, tell Yedric to "save this as an automation."
{% endstep %}

{% step %}
After Yedric confirms the automation has been saved, you should see your Web Operator step has been updated with the instructions.

You can edit the instructions in the Web Operator step at any time.
{% endstep %}

{% step %}
Save your workflow and [begin a manual run](https://docs.getmesa.com/workflow-builder/testing) to see how the results of this process will be automated going forward!

The data from the automation will be available in your workflow as [variables](https://docs.getmesa.com/workflow-builder/fields/variables).
{% endstep %}
{% endstepper %}

### Submitting a Form Example

The following tutorial explains how to use the Web Operator to submit a form in an automation.

{% embed url="<https://www.youtube.com/embed/viZC9jHmBTA?rel=0>" %}

#### Setup

{% stepper %}
{% step %}
Add the Web Operator step to your workflow.
{% endstep %}

{% step %}
Click the **Build Web Operator instructions** with Yedric button within the Web Operator step to launch Yedric.
{% endstep %}

{% step %}
Tell Yedric exactly what you want to do.

* For this example, the prompt is: "*I want to submit my Shopify order to this form \[create a* [*Form*](https://docs.getmesa.com/tools/forms) *link]. The form only has Order Name, and Customer Name. I want you to send the order name and the customer name.*"
  {% endstep %}

{% step %}
Yedric will create a browser session, but you will not need to use it.
{% endstep %}

{% step %}
Wait for Yedric to finish analyzing the page.

{% hint style="info" %}
Slow load times should be expected as Yedric processes the output. Refer to the [Technical Notes](https://docs.getmesa.com/tools/ai/web-operator#technical-notes) below for more details.
{% endhint %}
{% endstep %}

{% step %}
After Yedric provides your results, review them to ensure that all of the information is accurate.
{% endstep %}

{% step %}
Once you've confirmed Yedric has provided accurate results based on your instructions, tell Yedric to "save this as an automation."
{% endstep %}

{% step %}
After Yedric confirms the automation has been saved, you should see your Web Operator step has been updated with the instructions.

You can edit the instructions in the Web Operator step to reference any data that's available via [variables](https://docs.getmesa.com/workflow-builder/fields/variables) from steps prior to the Web Operator in the workflow.
{% endstep %}

{% step %}
Save your workflow and [begin a manual run](https://docs.getmesa.com/workflow-builder/testing) to see how the results of this process will be automated going forward!
{% endstep %}

{% step %}
If you're using the [Form](https://docs.getmesa.com/tools/forms) in another workflow, verify that it was submitted based on your Web Operator step processing.
{% endstep %}
{% endstepper %}

### What to do with a Connection Error

{% embed url="<https://www.youtube.com/embed/-2kqEPVbzls?rel=0>" %}

{% stepper %}
{% step %}
If your Web Operator has run and did not complete the expected outcome, it's best to check the connection.
{% endstep %}

{% step %}
Navigate to My Account from your profile icon in the MESA dashboard and select the Connections tab.
{% endstep %}

{% step %}
Select the connection that your Web Operator is using (it will look like the AI step icon).
{% endstep %}

{% step %}
With the connection modal open, click the Take me to login button and log in to the service you're using with the Web Operator.
{% endstep %}

{% step %}
Save your changes to update the connection for Web Operator.
{% endstep %}
{% endstepper %}

## Going Further

### When to use the Web Operator

The Web Operator should be used when you need to take actions in a service that requires logging in, and:

* Does not have an [existing integration](https://www.getmesa.com/apps), or
* Does not provide an API (or the API is too limited for what you need).

In these cases, we use AI to automate actions *as if it were you* interacting with the tool directly in a browser. Because of this, there must be some kind of user interface involved, such as a dashboard, admin panel, or web app, where actions can be performed after logging in.

### When NOT to use the Web Operator

The Web Operator should *not* be used if you do not need to log into a service and are simply trying to extract data.

Better alternatives for these instances include:

* Using the [API](https://docs.getmesa.com/tools/api) tool when the data is available as JSON.
* Using a programming language if you’re transforming or processing data.
* Using the [Scraper](https://docs.getmesa.com/tools/scraper) tool if you’re abstracting or extracting data from public web pages or forms.

In short, the Web Operator is primarily designed for logged-in, dashboard-based workflows where you need to take actions inside a web UI that cannot be accessed through an API.

### Best Practices

There are a few key factors that will get you the best results with the Web Operator action:

* Be very explicit about what you want Yedric to do.
* You are responsible for logging into the target system during setup.
* Confirm that the output matches what you expect for your given example.
* Once everything looks correct, tell Yedric to automate the process.
  * From that point forward, the flow runs as an [automation](https://docs.getmesa.com/readme/core-concepts).

{% hint style="info" %}
If the action cannot be completed (most commonly due to login issues), we treat the automation as a failed run and surface an error.
{% endhint %}

## Technical Notes

### Performance and Timing Expectations

Because the Web Operator is using AI to visually navigate, analyze, and interact with a live browser, some steps, such as extracting data, analyzing pages, or determining next actions, can take a bit of time. It is normal for certain operations to take up to a minute or more while the AI figures out what to do next.

You should expect this and be patient during these steps. This is not a traditional API call; it’s AI reasoning through a real interface.

### Logging in to Third-Party Services

For privacy protection, **do not** prompt Yedric to automate the login process for your Web Operator by providing login details (usernames, emails, passwords, etc.). You should manually add your login credentials via the browser instance that's generated each time you use the Web Operator.


# API

The **API** tool allows you to connect MESA with internal services or any publicly-available API.

{% hint style="info" %}
If you’re looking to trigger your workflow from an API we recommend using a [Webhook](https://docs.getmesa.com/tools/webhook) if your API supports webhooks. Otherwise, you can use a [Schedule](https://docs.getmesa.com/tools/schedule) trigger and an API action in later steps.
{% endhint %}

### Authentication Methods <a href="#actions" id="actions"></a>

MESA offers [4 different built-in Actions](/workflow-builder/triggers) that you can utilize to connect to an API.

* [No Authentication](#no-auth)
* [API Key](#api-key)
* [OAuth 2.0](#oauth-2)
* [Basic Auth](#basic-auth)

<figure><img src="/files/jvXo20V5ZqFwthvYce4W" alt="Screenshot of the API tool action setup in the MESA workflow builder showing the four built-in authentication methods. Spotlight the authentication method selector listing No Authentication, API Key, OAuth 2.0, and Basic Auth."><figcaption></figcaption></figure>

#### No Authentication <a href="#no-auth" id="no-auth"></a>

Used for interacting with an API that does not require any authentication and provides public API access. To configure the **No Authentication** Action, please refer to the [Configuration information below.](#no-auth-example)

#### API Key <a href="#api-key" id="api-key"></a>

One of the most common ways to connect to an API.

<figure><img src="/files/vAF75ofvCmr6tRagVrMY" alt="Screenshot of the API Key connection setup in MESA, adding a new API Key credential. Spotlight the Key and Value fields."><figcaption></figcaption></figure>

**Key:** The name of your API key. Your service's API documentation will specify this.

**Value:** The value of your API Key that you get from the service's dashboard.

MESA will pass down the newly created connection as a key value pair in the header object. If the service expects the API key to be a query string parameter, use [API's No Authentication](#no-auth) step. Here is an example:

<figure><img src="/files/Y3Ab1AR3yPTN6wJtjpTT" alt="Screenshot of the MESA Logs showing an API Key request passed as a key value pair in the header object. Spotlight the header object containing the API key."><figcaption></figcaption></figure>

To configure the API Key Action, please refer to the [Configuration information below.](#configuring)

#### OAuth 2.0 <a href="#oauth-2" id="oauth-2"></a>

One of the most common ways to connect to an API but requires a more complex set-up. This requires creating an app in your service and entering the information into MESA to create a [connection](https://docs.getmesa.com/going-further/credentials). When creating an app in your service, you must use this URL as the callback URL: <https://app.getmesa.com/apps/mesa/oauth/redirect-token>

<figure><img src="/files/3VjqBRPmBN3iDT39pqbO" alt="Screenshot of the OAuth 2.0 connection setup in MESA where you enter the app details from your service. Spotlight the callback URL field."><figcaption></figcaption></figure>

If your service requires MESA to make a POST request to refresh a token, you can use the Use POST for token refresh setting in the [More options](https://docs.getmesa.com/workflow-builder/fields).

<figure><img src="/files/RCXalfcQy9tUeYBQ3yTE" alt="Screenshot of the API step in the MESA workflow builder with the More options section expanded. Spotlight the More options link."><figcaption></figcaption></figure>

<figure><img src="/files/HplVEWeHgZgHbQkuXLgU" alt="Screenshot of the API step More options in MESA showing the token refresh setting. Spotlight the Use POST for token refresh checkbox."><figcaption></figcaption></figure>

By default, MESA will refresh tokens by using query parameters. If you mark the checkbox, MESA will use POST content to refresh the content.

#### Basic Auth <a href="#basic-auth" id="basic-auth"></a>

Basic Authentication is a simpler method of authentication that involves a username and password. For example, a Shopify private app. You will need to create a [Connection](/going-further/credentials).

<figure><img src="/files/zYXDdJHuYkyzEW2SZzNl" alt="Screenshot of the Basic Auth connection setup for the API tool in MESA. Spotlight the username and password fields."><figcaption></figcaption></figure>

## Configure <a href="#configuring" id="configuring"></a>

In the API actions, you will find the following fields:

**Method:** GET, POST, DELETE, PUT, PATCH (for a summary, read [this article](https://www.w3schools.com/tags/ref_httpmethods.asp))

**URL:** Endpoint of a service, for example, <https://httpbin.org/anything>. If you are sending URL parameters, include these here. **Important:** Make sure to include "https\://" in the url.

### Advanced Settings (found via [More Options](https://docs.getmesa.com/workflow-builder/fields#additional-fields))

**Content Type:** Used to tell the client about the original [media type](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the resource

**Request Body:** Will contain the information that you want to send to the service - used by POST, PUT, PATCH, and DELETE requests

**Headers:** Lets the client & server pass additional information with an HTTP request or response, for example, authentication tokens or the format to return. More information can be found [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).

**Querystring parameters:** A part of a uniform resource locator (URL) that assigns values to a specified parameter(s). `Example: https://example.com/over/there?name=ferret`

**Specify a custom Request Body:** This allows you to specify text or a variable for the request body. For instance, you could specify a variable that refers to data from a previous step. The text specified here will be sent as the Request Body instead of anything specified under the **Request Body** above.

## Going Further <a href="#examples" id="examples"></a>

### Examples <a href="#no-auth-example" id="no-auth-example"></a>

#### API: No Authentication

When a product is updated, we will make a POST request to the following endpoint: <https://httpbin.org/anything>

Once a workflow runs and the request has been sent, httpbin will return the data (product title, product handle, and price) that we sent to the endpoint.

<figure><img src="/files/tMT3G3tYV7LF1va7Pi85" alt="Screenshot of the API No Authentication action in the MESA workflow builder configured to make a POST request to the httpbin endpoint. Spotlight the Method and URL fields."><figcaption></figcaption></figure>

<figure><img src="/files/Bmw5nmrMo5WsUWfOf88f" alt="Screenshot of the API No Authentication action in MESA showing the product data (title, handle, and price) configured to send to the httpbin endpoint. Spotlight the Request Body fields."><figcaption></figcaption></figure>

After updating a product and viewing the [Logs](/workflow-activity/logs), this was the Request:

![Screenshot of the MESA Logs after updating a product showing the API Request that was sent to httpbin. Spotlight the Request body.](/files/Han7QQ8o3VZXBcARLcUs)

This was the Response:

![Screenshot of the MESA Logs after updating a product showing the API Response returned by httpbin. Spotlight the Response body.](/files/7tYSVGL2M56ASDSwx781)

#### Use data obtained from an API <a href="#data" id="data"></a>

In this example, we will interact with [OpenWeatherMap's API](https://openweathermap.org/) and update a Shopify order's Notes with the current temperature of the customer's zip code once an order is created.

To utilize their API and obtain an API Key, you will need an [account](https://home.openweathermap.org/users/sign_up).

1\. You can start building your own workflows by clicking the New Workflow button on the right-hand side of the My workflows page.

<figure><img src="/files/uGtIqIEfn73R4O4XUEe9" alt="Screenshot of the My workflows page in MESA. Spotlight the New Workflow button on the right-hand side."><figcaption></figcaption></figure>

<figure><img src="/files/cSWjHZQ4QbzSL9voVeja" alt="Screenshot of the new workflow creation screen in MESA after clicking New Workflow. Spotlight the trigger selection to add the Shopify Order Created trigger."><figcaption></figcaption></figure>

2\. Select the Shopify Order Created trigger. Next, click on Add Step > Actions, search for "API", select the API tool, and then the [No Authentication](#no-auth) action.

3\. For the Method and URL, you will need to decide on your preferred endpoint. [Here is an example.](https://openweathermap.org/current)

<figure><img src="/files/q0MW9iX1prXtR6qLBKkY" alt="Screenshot of the API No Authentication action in the MESA workflow builder for the OpenWeatherMap example. Spotlight the Method and URL fields."><figcaption></figcaption></figure>

<figure><img src="/files/mv6ArakyrWZbxM0hmi2T" alt="Screenshot of the API No Authentication action in MESA showing the Querystring parameters for the OpenWeatherMap request. Spotlight the zip and appid parameter fields."><figcaption></figcaption></figure>

4\. For the Querystring parameters, you will need to add the parameters (zip and appid).

* zip (Required): You can use [MESA Variables](/workflow-builder/fields/variables) to use the Shopify Order's zipcode and country code. For this example, the variable is (comma included): {{shopify\_order.shipping\_address.zip}}, {{shopify\_order.shipping\_address.country\_code}}
* appid (Required): Your unique API key, and you can find it on your account page under the [API key tab](https://home.openweathermap.org/api_keys).
* units: Optional parameter to specify the temperature units.

5\. Click on the **+** symbol below that step and select the Shopify Update Order Notes Action. This action will only add the preferred text and will not override any existing order notes on the order.

6\. In order to view the information sent by OpenWeatherMap, you will need to enable the [Logging, debug mode logging](/workflow-activity/logs), and test your workflow. To learn how to test your workflow, [click here](/workflow-builder/testing).

7\. After a test, you can view the Variables Available to view the response from OpenWeatherMap with the debug logging enabled.

<figure><img src="/files/u7Hcl3p1j0Kh6qYBZdUl" alt="Screenshot of the API step in MESA after a test run showing the OpenWeatherMap response. Spotlight the Variables Available section."><figcaption></figcaption></figure>

8\. By viewing the Variables Available, you can figure out the variable to use for the later steps in the workflow.

9\. In the Shopify Update Order Notes Action, fill out the following:

* **Shopify Order ID**: Select the Shopify Order Created ID [variable](https://docs.getmesa.com/workflow-builder/fields/variables).
* **Notes:** If you want to pass the current temperature data down in your workflow, you can use this variable: {{api.main.temp}}

To create a custom variable, click on the plus sign icon next in Settings for that particular API step. Then, click on the Copy key.

<figure><img src="/files/T4gnwEvgYi2N4q274D7c" alt="Screenshot of the API step Settings in MESA for creating a custom variable. Spotlight the Copy key button next to the plus sign icon."><figcaption></figcaption></figure>

In one of the fields, you can type `{{` and then paste the copied value. Next, you can manually type in the data that you'd like to send. End the variable with `}}`

An example of a custom variable is: `{{api.feels_like}}`

Here is an example of updating the order notes with the current temperature.

<figure><img src="/files/Ap4jduhinoNDaJGTw13h" alt="Screenshot of the Shopify Update Order Notes action in MESA populated with the current temperature variable. Spotlight the Notes field containing the api.main.temp variable."><figcaption></figcaption></figure>

#### Send nested data to an API <a href="#nested-data" id="nested-data"></a>

To send nested data to an API, you can use dot notation. Here is an example of a nested data structure, with the data nested under **data**:

```
{
  "data": {
    "order_id": "2975040733210",
    "total_price": "403.00"
  }
}
```

Here is how you would set this up in MESA.

<figure><img src="/files/gEfuDEYbO1SHiiiywM13" alt="Screenshot of the API action in the MESA workflow builder configured to send nested data using dot notation. Spotlight the Request Body fields showing the data.order_id and data.total_price keys."><figcaption></figcaption></figure>


# Approval

The **Approval** tool allows you to pause automations for human intervention and get manual approval before data moves to the next step at any stage in your workflow.

This element of human oversight ensures your workflows process the correct information. For instance, verifying AI-generated prompts before updating product descriptions.

## Configure Required Fields <a href="#configuring" id="configuring"></a>

### Instructions

The Instructions field creates a message shown in the Approvals list to help reviewers understand what they're approving. Use [variables](https://docs.getmesa.com/workflow-builder/fields/variables) to include key details like Customer Name, Order Name, or any other relevant information.

### Data to Review

The Data to review field displays information to the approver when they review the approval task. You should include the details they need to make an informed decision.

<figure><img src="/files/mFAw2YbWJe0RddqiIUL4" alt="Screenshot of the MESA Approval tool configuration, Data to review field displaying information for the approver. Spotlight the Data to review field."><figcaption></figcaption></figure>

## Configure More Fields <a href="#configuring" id="configuring"></a>

Click the [More fields](https://docs.getmesa.com/workflow-builder/fields#additional-fields) button in your Approval step to configure settings for your Approval.

### Email Notifications <a href="#notifications" id="notifications"></a>

In the Email Notifications field, enter any email addresses that should receive a notification when a new pending approval is created. Recipients can approve or deny the task directly from the email with a single click, without needing to log in to MESA.

<figure><img src="/files/bquWsUQRoAhl3e2tyaXe" alt="Screenshot of the MESA Approval tool More fields, Email Notifications field for addresses that receive pending approval notices. Spotlight the Email Notifications field."><figcaption></figcaption></figure>

If no email is added, you will need to check the workflow's Approvals tab to view and action pending approvals.

{% hint style="info" %}
All recipients will receive an email. If you are not receiving emails, be sure to check the "Promotions" tab in your email client or add <mesa@theshoppad.net> to your contacts list.
{% endhint %}

### Continue Workflow When Approval is Denied <a href="#advanced-options" id="advanced-options"></a>

By default, a workflow stops when an approval is denied. Enable **Continue the workflow when approval is denied** to allow the workflow to proceed through the remaining steps regardless of the outcome.

<figure><img src="/files/cW9nxYF0TErUyRb05TtA" alt="Screenshot of the MESA Approval tool More fields. Spotlight the Continue the workflow when approval is denied option."><figcaption></figcaption></figure>

Use this in combination with a [Paths](https://docs.getmesa.com/tools/paths) step to create actions for approved and denied outcomes.

### Changing Labels for Approve and Deny

In cases where "Approve" and "Deny" are not the appropriate labels, they can be overwritten using the Approve button label and Reject button label fields. Click the [More fields](https://docs.getmesa.com/workflow-builder/fields#additional-fields) button to access those fields.

<figure><img src="/files/W1uRrwLyJ7fLSRhSIdaw" alt="Screenshot of the MESA Approval tool More fields. Spotlight the Approve button label and Reject button label fields."><figcaption></figcaption></figure>

### Auto-advance

The **Auto-advance** **rule** automatically approves or denies a pending approval after a specified amount of time.

This is useful when you want a default outcome if no reviewer responds within a set window.

### Approve and Deny Reasons

You can create a list of reasons for the reviewer to select from upon approving or denying an approval task.

If left blank or unchecked, reviewers will be able to approve or deny without selecting a reason.

### Approvals Tab <a href="#advanced-options" id="advanced-options"></a>

<figure><img src="/files/9PKDf9AiR6jSvq50uHaD" alt="Screenshot of a MESA workflow Approvals tab where you view, approve, or deny pending approvals. Spotlight the Approvals tab."><figcaption></figcaption></figure>

The Approvals tab in your workflow is where you can view, approve, or deny pending approvals at any time.

## Going Further

### Editing a Payload Before Approving

From the approval notification email, reviewers can open the **Edit page** — accessible outside of the MESA app — to adjust the payload before approving or denying the task. This is useful when the data needs a correction before the workflow continues.

### Other uses for an Approval step in your workflow

* Creating a draft environment for your workflow while building.
* Escalating orders to a specific person before issuing a discount or free product.
* Any stage in a workflow where human intervention is deemed necessary.

## Technical Notes

The task history and replay of approvals are influenced by your [plan limits](https://docs.getmesa.com/going-further/platform-thresholds-and-limits).


# MCP

MESA MCP lets you supercharge your AI prompts by calling MESA workflows to fetch information and even take action.

Get started by creating a workflow in MESA with an MPC trigger. Then, let your AI app know about MESA MCP and start chatting. In the steps below, we use Claude Desktop, but MESA MCP also supports Cursor and many other AI apps.

{% embed url="<https://www.youtube-nocookie.com/embed/hDl-bU7yoYs?rel=0>" %}

## Creating a MESA MCP workflow

1. Create a new workflow in MESA. Search for and select MCP to add a MCP trigger.
2. Configure the MCP step with any "parameters" your MCP workflow will need. If you want to search Shopify Orders, for instance, you might want to add parameters like `status`, `created_at_min`, `created_at_max` that will match the types of queries you will want to make. Make sure to give these parameters useful, explicit descriptions for the AI tools to interpret.
3. Add any additional steps you would like your workflow to perform. Make sure to use any parameters you created to outfit your step(s) with the information they need to perform actions for your AI tool.
4. Name the workflow something AI tools can understand, eg, "List Shopify Orders with Query". Be as explicit as possible to help AI tools determine which of your workflows to use. For instance, if you also wanted to provide your AI tool with Shopify orders by a single customer, you could create a new workflow "List Shopify Orders by Customer Email".
5. Give the workflow as descriptive of a description as possible. If you have similar "sounding" workflows, the description can provide context to the AI tool about how to decide which workflows(s) to choose.
6. Enable the workflow.
7. Copy the connection information provided by the MCP trigger step.

   > Note: you only need to configure Claude or other AI tools to connect to your MESA MCP server once.

## Using MESA MCP with Claude

### **Get Claude Desktop**

Currently, Claude can only talk to MESA's MCP workflows with [Claude Desktop](https://claude.ai/download), so make sure that application is installed on your computer. This article on [MCP for Claude Desktop](https://modelcontextprotocol.io/quickstart/user) has other potentially useful information.

### **Ensure `node` is installed on your computer**

Next, you will need to make sure that [Node](https://nodejs.org/) is installed on your computer. To check if it is installed, open your "terminal" program on your computer and run this command:

```bash
node --version
```

1. If you see `command not found: node` it means you will have to install [Node](https://nodejs.org/).
2. If you see any version less than `20.1.0` it means you will need to update your system's `node` version to at least `20.1.0`.

### **Connect Claude to your MESA MCP server**

1. Click on “Developer” in the left-hand bar of the Settings pane, and then click on “Edit Config”.
2. This will create a configuration file at:
   * macOS: \~/Library/Application Support/Claude/claude\_desktop\_config.json
   * Windows: %APPDATA%\Claude\claude\_desktop\_config.json
3. Edit the `claude_desktop_config.json` file with the connection info provided by the Skill trigger. It will look something like this, though your information will be inserted where `ID` and `KEY` are below:<br>

   ```json
   {
     "mcpServers": {
       "mesa": {
         "command": "npx",
         "args": [
           "mcp-remote",
           "https://mcp-server.getmesa.com/sse/ID/KEY"
         ],
         "env": {}
       }
     }
   }
   ```
4. Save the file and restart Claude Desktop.

   > Note: you only need to configure Claude or other AI tools to connect to your MESA MCP server once.

### **Call MESA MCP workflows in Claude**

Upon restarting, you should see a hammer icon in or near the input box. Clicking that hammer will show your Available MESA MCP workflows!

> Not seeing the hammer icon? Take a look at [Claude's MCP troubleshooting section](https://modelcontextprotocol.io/quickstart/user#server-not-showing-up-in-claude-hammer-icon-missing).

Try asking Claude something that would require information provided by your workflow eg. "Find Shopify Orders from March 2025". If Claude decides that it needs to run your workflow, you will be prompted for your approval to use the tool.

## Technical Notes

* Treat your MCP Configuration JSON like a password. It can be used to access and update your data.
* The maximum request time is limited based on the [Task compute](/going-further/platform-thresholds-and-limits#limits) limit of your plan. There is also a limit of 60 seconds per request, even if your plan allows longer requests. Requests that take more time to execute will be timed out, and no response will be returned.
* Requests are rate-limited based on the [Incoming rate limit](/going-further/platform-thresholds-and-limits#limits) of your plan.

### Common Issues

Getting Claude Desktop running can be difficult, and the error messages can be unhelpful. Here are some solutions to common issues we have encountered.

#### Claude's "response was interrupted"

<figure><img src="/files/z9HAANFatNozNmhOAGF1" alt="Screenshot of Claude Desktop showing the response was interrupted error message in a MESA MCP chat. Spotlight the response was interrupted error message." width="563"><figcaption></figcaption></figure>

Usually, this means that too much information in the chat has already been processed, and Claude is running into issues with the "[context window](https://support.anthropic.com/en/articles/7996848-how-large-is-claude-s-context-window)" size.

Some strategies:

1. Start a new chat. Sometimes this can help, but if you're requesting a lot of data on every run, it may not do the trick.
2. Upgrade your plan. Claude Pro includes a much larger context window than the free version.
3. Reduce the size of your workflow's response. Depending on the app you may be able to configure your steps to return less information. This could be in the form of "only return these fields" or simply "limit number of responses". You could also use Loops or Custom Code to reduce the size of the information you respond with.

#### Claude still can't access my MESA MCP workflows

As noted above, you need a version of [Node](https://nodejs.org) newer than `20.1.0` to access MESA's Skills.

Next a look at [Claude's MCP troubleshooting section](https://modelcontextprotocol.io/quickstart/user#server-not-showing-up-in-claude-hammer-icon-missing) for anything you might have missed or misconfigured.

If you are a more technical user and have a node "version utility" like `nvm` installed. It's possible that Claude is getting confused with node versions as `npx` runs.

The `mcp-server-mesa.log` file may have things in it like:

```
npx: installed 120 in 8.27s
Unexpected token {
}
```

If that is the case, you may need to provide Claude with more information to function properly. These steps are only valid for Mac users but something similar should be possible for Windows:

1. Open your terminal application and run:

   ```
   which npx
   ```
2. Replace `npx` in the `"command": "npx",` of the Claude configuration file with the full path, eg. `"command": "/Users/full/path/node/22.14.0/bin/npx",`.
3. In your terminal application run:

   <pre><code><strong>echo $PATH
   </strong></code></pre>
4. Add the `PATH` "env" variable to the Claude configuration file for your MESA MCP server, and paste in the response from `echo $PATH` eg.

   ```
   {
     "mcpServers": {
       "mesa": {
         "command": "/Users/full/path/node/22.14.0/bin/npx",
         "args": [
           "mcp-remote",
           "https://mcp-server.getmesa.com/sse/ID/KEY"
         ],
         "env": {
           "PATH": "/The/Path/Returned/By/Your/Terminal"
         }
       }
     }
   }
   ```
5. Restart Claude Desktop.

#### I saw my Skills, but they went away after I restarted Claude Desktop

You might need to kill the `mcp-remote` process running on your computer. In your terminal application run:

```bash
pkill -f mcp-remote
```


# Custom Code

The **Custom Code** tool allows you to add complex logic to a workflow that might otherwise be difficult with MESA's built-in tools. You can create custom integrations to third-party services, even those that MESA does not yet integrate, and code custom business logic using JavaScript.

## Configure

### To open the code editor

Click the **\</> Edit Code** button to edit your custom code.

<figure><img src="/files/Iq2UQTLkkRlQENL07WdA" alt="Screenshot of the MESA Custom Code tool. Spotlight the Edit Code button."><figcaption></figcaption></figure>

### Anatomy of a Custom Code step

```javascript
const Mesa = require('vendor/Mesa.js');

/**
 * A MESA Script exports a class with a script() method.
 */
module.exports = new class {

  /**
   * MESA Script
   *
   * @param {object} prevResponse The response from the previous step
   * @param {object} context Additional context about this task
   */
  script = (prevResponse, context) => {

    // Retrieve the Variables Available to this step
    const vars = context.steps;

    // Add your custom code here
    let response = {}

    // Call the next step in this workflow
    // response will be the Variables Available from this step
    Mesa.output.next(response);
  }

}
```

Code is executed in a V8 environment and can be written in standard JavaScript or ES6. When this step is run, the `script()` method will be called with two parameters: `prevResponse` and `context`. In order for your workflow to continue its subsequent steps, be sure to include a call to `Mesa.output.next(response);` somewhere within your `script()` method.

#### The `context` object

<table><thead><tr><th width="169">Property</th><th width="133">Type</th><th>Description</th></tr></thead><tbody><tr><td>steps</td><td><code>Object</code></td><td><p>An object containing the variables for each step that has been run so far, named with the step's unique key.</p><p>For example, to access a step with a key of "shopify" use: <code>context.steps['shopify']</code>.</p></td></tr><tr><td>trigger</td><td><a href="#the-trigger-object">Trigger</a></td><td>This object is the configuration of the current step being run.</td></tr><tr><td>task</td><td><a href="#the-task-object">Task</a></td><td>This object is information about the current task's execution.</td></tr></tbody></table>

#### The `Trigger` object

<table><thead><tr><th width="167">Property</th><th width="133">Type</th><th>Description</th></tr></thead><tbody><tr><td>metadata</td><td><code>Object</code></td><td>The values entered in configuration fields, with variable replacements.</td></tr><tr><td>raw_metadata</td><td><code>Object</code></td><td>The values entered in configuration fields, without variable replacements.</td></tr><tr><td>fields</td><td><code>Object</code></td><td>An object of the configuration fields from the UI.</td></tr></tbody></table>

#### The `Task` object

<table><thead><tr><th width="168">Property</th><th width="133">Type</th><th>Description</th></tr></thead><tbody><tr><td>context.headers</td><td><code>Object</code></td><td>A key-value object of the HTTP headers passed to this task.</td></tr><tr><td>is_test</td><td><code>Object</code></td><td>Is the current task being run as a test?</td></tr></tbody></table>

### Using Libraries

Libraries offer built-in functionality that extends the power of your code. The [MESA SDK library](/tools/custom-code/libraries/sdk) is included by default and [other libraries](/tools/custom-code/libraries) can be imported as needed.

## Going Further

### Logging information

To debug your script, it can be helpful to log data at a particular step in your code. This can be done by calling [`Mesa.log.info()`](https://docs.getmesa.com/tools/pages/OI2cEwPTTQFLMOoElwYt#mesa.log.info-message-meta). This is equivalent to `console.log()` in browser-based JavaScript. When the workflow runs, the info will be available in your workflow's [Logs tab](/workflow-activity/logs).

<figure><img src="/files/HQDAffUgCOsxBZS5ZbgR" alt="Screenshot of a MESA workflow Logs tab showing logged output from Mesa.log.info in a Custom Code step. Spotlight the logged info entries."><figcaption></figcaption></figure>

### Throwing errors

Throw a JavaScript error to halt the execution of your workflow:

```javascript
throw new Error("your error description")
```

In the User Interface, this will look like:

<figure><img src="https://docs.getmesa.com/~gitbook/image?url=https%3A%2F%2F3425906282-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F1H6u1HQc3Iew7ATmmiCi%252Fuploads%252Fgit-blob-8a5e2b2128c4b36c509295e5388274a9fc4ea252%252Ffile-m3mgczb5y3.png%3Falt%3Dmedia&#x26;width=768&#x26;dpr=4&#x26;quality=100&#x26;sign=943c5393&#x26;sv=1" alt="Screenshot of the MESA workflow builder showing a thrown JavaScript error from a Custom Code step in the user interface. Spotlight the error message."><figcaption></figcaption></figure>

### Interacting with external APIs <a href="#how-do-i-get-advanced-details-related-to-my-automation" id="how-do-i-get-advanced-details-related-to-my-automation"></a>

Use [`Mesa.request.get()`](https://docs.getmesa.com/tools/pages/OI2cEwPTTQFLMOoElwYt#mesa.request.get-path-options) to make HTTP requests to external APIs. This is the equivalent to `fetch()` in browser-based JavaScript.

## Technical Notes

### Timezones

All system timezones use your Shopify Store's timezone. You can view and update your timezone from the Shopify Dashboard: Admin > Settings > General, under "Standards and formats". If you need to get dates in a different timezone, use the [Mesa.date.setTimezone(timezone)](https://docs.getmesa.com/tools/pages/OI2cEwPTTQFLMOoElwYt#mesa.date.settimezone-timezone) method.

### Unsupported NodeJS methods

Scripts are run in a stock V8 environment. This means that some common NodeJS methods are not available:

* `request()`: Alternative: `Mesa.request.*()` [Documentation](https://docs.getmesa.com/tools/pages/OI2cEwPTTQFLMOoElwYt#mesa.request.get-path-options).
* `console.log()`: Alternative: `Mesa.log.*()` [Documentation](https://docs.getmesa.com/tools/pages/OI2cEwPTTQFLMOoElwYt#mesa.log.info-message-meta).
* `async` or `await`: All `Mesa.request.*()` methods are synchronous, so `async` and `await` are not necessary.
* DOM manipulation methods: Alternative: `Mesa.xml.decode()` [Documentation](https://docs.getmesa.com/tools/pages/OI2cEwPTTQFLMOoElwYt#mesa.xml.decode-xmlstring-namespacesep).


# Libraries


# MESA SDK

vendor/Mesa.js

## Mesa.log.info(message\[, meta])

Log info to Mesa Logs.

**Parameters**

| Name    | Type     | Description |            |
| ------- | -------- | ----------- | ---------- |
| message | `string` |             |            |
| meta    | `object` |             | *Optional* |

## Mesa.log.warn(message\[, meta])

Log a warning to Mesa Logs.

**Parameters**

| Name    | Type     | Description |            |
| ------- | -------- | ----------- | ---------- |
| message | `string` |             |            |
| meta    | `object` |             | *Optional* |

## Mesa.log.error(message\[, meta])

Log an error to Mesa Logs.

**Parameters**

| Name    | Type     | Description |            |
| ------- | -------- | ----------- | ---------- |
| message | `string` |             |            |
| meta    | `object` |             | *Optional* |

## Mesa.log.debug(message\[, meta])

Log info to Mesa Logs only if the Automation is in Debug Mode.

**Parameters**

| Name    | Type     | Description |            |
| ------- | -------- | ----------- | ---------- |
| message | `string` |             |            |
| meta    | `object` |             | *Optional* |

## Mesa.request.get(path, options)

Make a GET request to an external Rest API.

**Parameters**

| Name    | Type                                     | Description |   |
| ------- | ---------------------------------------- | ----------- | - |
| path    | `string`                                 |             |   |
| options | [RequestOptions](#object-requestoptions) |             |   |

**Returns**

* [Response](#object-or-string-response)

## Mesa.request.post(path, data, options)

Make a POST request to an external Rest API.

**Parameters**

| Name    | Type                                     | Description |   |
| ------- | ---------------------------------------- | ----------- | - |
| path    | `string`                                 |             |   |
| data    | `object`                                 |             |   |
| options | [RequestOptions](#object-requestoptions) |             |   |

**Returns**

* [Response](#object-or-string-response)

## Mesa.request.put(path, data, options)

Make a PUT request to an external Rest API.

**Parameters**

| Name    | Type                                     | Description |   |
| ------- | ---------------------------------------- | ----------- | - |
| path    | `string`                                 |             |   |
| data    | `object`                                 |             |   |
| options | [RequestOptions](#object-requestoptions) |             |   |

**Returns**

* [Response](#object-or-string-response)

## Mesa.request.patch(path, data, options)

Make a PATCH request to an external Rest API.

**Parameters**

| Name    | Type                                     | Description |   |
| ------- | ---------------------------------------- | ----------- | - |
| path    | `string`                                 |             |   |
| data    | `object`                                 |             |   |
| options | [RequestOptions](#object-requestoptions) |             |   |

**Returns**

* [Response](#object-or-string-response)

## Mesa.request.delete(path, options)

Make a DELETE request to an external Rest API.

**Parameters**

| Name    | Type                                     | Description |   |
| ------- | ---------------------------------------- | ----------- | - |
| path    | `string`                                 |             |   |
| options | [RequestOptions](#object-requestoptions) |             |   |

**Returns**

* [Response](#object-or-string-response)

## Mesa.request.send(method, path, data, options)

Make a request to an external Rest API.

**Parameters**

| Name    | Type                                     | Description                                       |   |
| ------- | ---------------------------------------- | ------------------------------------------------- | - |
| method  | `string`                                 | One of `GET`, `POST`, `PUT`, `PATCH`, or `DELETE` |   |
| path    | `string`                                 |                                                   |   |
| data    | `object`                                 |                                                   |   |
| options | [RequestOptions](#object-requestoptions) |                                                   |   |

**Returns**

* [Response](#object-or-string-response)

## Mesa.request.base64\_encode(string)

Base-64 encode a string. This is helpful when building an `Authorization` header for basic auth requests.

**Parameters**

| Name   | Type     | Description          |   |
| ------ | -------- | -------------------- | - |
| string | `string` | The string to encode |   |

**Returns**

* `string` The base-64 encoded version of the input string parameter.

## Mesa.request.base64\_decode(string\[, strict])

Base64 decode a string. Decodes data encoded with MIME base64

**Parameters**

| Name   | Type     | Description                                                                                                                                                                      |            |
| ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| string | `string` | The base-64 encoded version of the input string parameter.                                                                                                                       |            |
| strict | `bool`   | If the strict parameter is set to TRUE then the base64\_decode() function will return FALSE if the input contains character from outside the base64 alphabet. Defaults to FALSE. | *Optional* |

**Returns**

* `string` The decoded string.

## Mesa.request.hash(algorithm, string\[, base64encode])

Generate a hash of a string. This is helpful when creating signed requests.

**Parameters**

| Name         | Type     | Description                                            |            |
| ------------ | -------- | ------------------------------------------------------ | ---------- |
| algorithm    | `string` | The algorithm to use. Options: `sha1`, `sha256`, `md5` |            |
| string       | `string` | The string to create the hash from                     |            |
| base64encode | `string` | Should we base64-encode the raw value of the hash?     | *Optional* |

**Returns**

* `string` The raw binary data of the hash

## Mesa.request.hashHmac(algorithm, string, string\[, base64encode])

Generate a keyed hash value using the HMAC method. This is helpful when creating signed requests.

**Parameters**

| Name         | Type     | Description                                                                  |            |
| ------------ | -------- | ---------------------------------------------------------------------------- | ---------- |
| algorithm    | `string` | The algorithm to use. Options: `sha1`, `sha256`, `md5`                       |            |
| string       | `string` | The string to create the hash from                                           |            |
| string       | `string` | Shared secret key used for generating the HMAC variant of the message digest |            |
| base64encode | `string` | Should we base64-encode the raw value of the hash?                           | *Optional* |

**Returns**

* `string` The raw binary data of the hash

## Mesa.request.sleep($seconds)

Pauses execution

**Parameters**

| Name     | Type  | Description |   |
| -------- | ----- | ----------- | - |
| $seconds | `int` |             |   |

**Returns**

*

## Mesa.credential.get(key\[, defaultValue])

Get a secret.

**Parameters**

| Name         | Type     | Description                                                                                                                                       |            |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| key          | `string` |                                                                                                                                                   |            |
| defaultValue | `string` | A default value to use if the secret cannot be found. If `defaultValue` is empty, the script will throw a fatal error if the secret is not found. | *Optional* |

**Returns**

* `string` The secret value.

## Mesa.credential.set(key, value\[, options])

Save a secret value.

**Parameters**

| Name                    | Type     | Description                                                                                    |            |
| ----------------------- | -------- | ---------------------------------------------------------------------------------------------- | ---------- |
| key                     | `string` | The credential key or id.                                                                      |            |
| value                   | `string` | The value to save. This will be encrypted at rest, and can contained a stringified JSON array. |            |
| options                 | `object` |                                                                                                | *Optional* |
| options.oauth\_provider | `bool`   |                                                                                                | *Optional* |
| options.oauth\_scope    | `object` |                                                                                                | *Optional* |
| options.trigger\_type   | `object` |                                                                                                | *Optional* |

## Mesa.database.query(sql)

Get a storage item

**Parameters**

| Name | Type     | Description          |   |
| ---- | -------- | -------------------- | - |
| sql  | `string` | The SQL query to run |   |

**Returns**

* `array` The result of the query.

## Mesa.storage.get(key\[, defaultValue])

Get a storage item

**Parameters**

| Name         | Type     | Description                                                                                                                                                 |            |
| ------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| key          | `string` |                                                                                                                                                             |            |
| defaultValue | `string` | A default value to use if the storage key cannot be found. If `defaultValue` is empty, the script will throw a fatal error if the storage key is not found. | *Optional* |

**Returns**

* `string` The storage value.

## Mesa.storage.set(key, value)

Get a storage item

**Parameters**

| Name  | Type     | Description |   |
| ----- | -------- | ----------- | - |
| key   | `string` |             |   |
| value | `string` |             |   |

## Mesa.liquid.render(template, params)

Render a liquid template with the `params` passed.

**Parameters**

| Name     | Type     | Description                              |   |
| -------- | -------- | ---------------------------------------- | - |
| template | `string` | String representing a liquid template.   |   |
| params   | `object` | A keyed object of parameters to replace. |   |

**Returns**

* `string` The rendered template code.

## Mesa.input.getWebhookUrl(type, format, automationId, key)

Generates the URL for input webhooks

**Parameters**

| Name         | Type     | Description                                                                                                                                         |   |
| ------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| type         | `string` | Type of webhook: `json`, `shopify`                                                                                                                  |   |
| format       | `string` | Format of the returned data: `string` or `array`. If string, a full URL is returned. If `array`, URL will comprise two fields `suffix` and `prefix` |   |
| automationId | `string` | ID of the Automation                                                                                                                                |   |
| key          | `string` | The key of the trigger                                                                                                                              |   |

**Returns**

* `string` `array` The rendered template code.

## Mesa.output.next(payload, params)

Pass a payload to the service and call the next step in this Automation.

**Parameters**

| Name           | Type     | Description                                                                                     |            |
| -------------- | -------- | ----------------------------------------------------------------------------------------------- | ---------- |
| payload        | `object` |                                                                                                 |            |
| params         | `object` | Parameters to send to the output, such as tokens to construct a Shopify API url                 |            |
| params.enqueue | `bool`   | Defaults to false. Set to true if you are exploding multiple tasks that can be run in parallel. | *Optional* |

## Mesa.output.send(outputKey, payload, enqueue)

Call an arbitrary output from a Mesa Script

**Parameters**

| Name      | Type     | Description                                                                                     |   |
| --------- | -------- | ----------------------------------------------------------------------------------------------- | - |
| outputKey | `string` |                                                                                                 |   |
| payload   | `object` |                                                                                                 |   |
| enqueue   | `bool`   | Defaults to false. Set to true if you are exploding multiple tasks that can be run in parallel. |   |

## Mesa.automation.send(automationKey, payload)

Call another automation from a Mesa Script

**Parameters**

| Name          | Type     | Description                                                                                                                                                                            |   |
| ------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| automationKey | `string` | In the form `${automationKey}`, this will trigger the first input in the Automation. In the form `${automationKey}/${inputKey}`, this will trigger a specific input in the automation. |   |
| payload       | `object` |                                                                                                                                                                                        |   |

## Mesa.ftp.deleteFile(filename)

Delete the file loaded by the Input.

**Parameters**

| Name     | Type     | Description                               |   |
| -------- | -------- | ----------------------------------------- | - |
| filename | `string` | Typically passed from `context.filename`. |   |

## Mesa.ftp.moveFile(filename, destinationFilenameAndPath)

Move the file loaded by the Input to a new location.

**Parameters**

| Name                       | Type     | Description                               |   |
| -------------------------- | -------- | ----------------------------------------- | - |
| filename                   | `string` | Typically passed from `context.filename`. |   |
| destinationFilenameAndPath | `string` |                                           |   |

## Mesa.xml.decode(xmlString\[, namespaceSep='\_'])

Convert an XML file into an {object}. This function will condense XML namespaces into {namespaceSep = '\_'} separated values: <soapenv:Body> becomes { soapenv\_Body: {} }

**Parameters**

| Name              | Type     | Description                                                                     |            |
| ----------------- | -------- | ------------------------------------------------------------------------------- | ---------- |
| xmlString         | `string` | The xml file to be decoded                                                      |            |
| namespaceSep='\_' | `string` | Namespace separator for replacing <soapenv:Body> type values with soapenv\_Body | *Optional* |

**Returns**

* `object`

## Mesa.xml.encode(xmlObject\[, wrapReplace, namespaceSep='\_'])

Convert an object into an XML string.

**Parameters**

| Name              | Type     | Description                                                                    |            |
| ----------------- | -------- | ------------------------------------------------------------------------------ | ---------- |
| xmlObject         | `object` | The object to be turned into xml.                                              |            |
| wrapReplace       | `string` | Replace the default wrapping provided with another value                       | *Optional* |
| namespaceSep='\_' | `string` | Namespace separator for replacing soapenv\_Body: {} values with <soapenv:Body> | *Optional* |

**Examples**

```javascript
// returns <?xml version="1.0" encoding="UTF-8"?><doc>\n  <book>\n ...
Mesa.xml.encode({ book: { ... }});
```

```javascript
// returns <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\n  <soapenv:Body>\n ...
Mesa.xml.encode({ soapenv_Body: { ... } }, '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">');
```

**Returns**

* `string`

## Mesa.xml.valid(xmlString)

Check if xml is valid

**Parameters**

| Name      | Type     | Description |   |
| --------- | -------- | ----------- | - |
| xmlString | `string` |             |   |

**Examples**

```javascript
// returns true
Mesa.xml.valid('<?xml version="1.0" encoding="UTF-8"?><doc><book><Name>My Book</Name></book></doc>');
```

```javascript
// throws error about namespace
Mesa.xml.valid('<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope><book><Name>My Book</Name></book></soapenv:Envelope>');
```

**Returns**

* `bool`

## Mesa.csv.decode(data\[, returnObject, options])

Convert a CSV file into an object. Keys will be matched from the first header row of the CSV file.

**Parameters**

| Name                  | Type     | Description                                                                                                                   |            |
| --------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------- |
| data                  | `string` |                                                                                                                               |            |
| returnObject          | `bool`   | Defaults to `true`, which will return an object keyed by the first row in the CSV content. Set to `false` to return an array. | *Optional* |
| options               | `object` |                                                                                                                               | *Optional* |
| options.delimiter=',' | `string` | The delimiter to use when parsing the CSV file. Must be a single character.                                                   | *Optional* |

**Returns**

* `object` `array`

## Mesa.csv.encode(data\[, headerRow])

Convert an object a CSV string.

**Parameters**

| Name      | Type     | Description                                                                   |            |
| --------- | -------- | ----------------------------------------------------------------------------- | ---------- |
| data      | `object` |                                                                               |            |
| headerRow | `bool`   | Defaults to `true`. Set to `false` to skip the header row when returning CSV. | *Optional* |

**Returns**

* `string`

## Mesa.vo.push(outputKey, payload)

Push to a Virtual Output.

**Parameters**

| Name      | Type     | Description |   |
| --------- | -------- | ----------- | - |
| outputKey | `string` |             |   |
| payload   | `mixed`  |             |   |

## Mesa.vo.clear(outputKey)

Mark the matching Virtual Output records as cleared by the current Mesa Script.

**Parameters**

| Name      | Type     | Description |   |
| --------- | -------- | ----------- | - |
| outputKey | `string` |             |   |

## Mesa.vo.clearOne(outputKey, mesaId)

Mark a single Virtual Output record as cleared by the current Mesa Script.

**Parameters**

| Name      | Type     | Description                                                                 |   |
| --------- | -------- | --------------------------------------------------------------------------- | - |
| outputKey | `string` |                                                                             |   |
| mesaId    | `string` | The ID of the record to clear (returned as mesa\_id in the Virtual Output). |   |

## Mesa.date.setTimezone(timezone)

Set the timezone to use to execute all script commands.

**Parameters**

| Name     | Type     | Description                                                                                                                                                      |   |
| -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| timezone | `string` | The timezone identifier, like UTC or America/Los\_Angeles. [See a full list of TZ Database names](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). |   |

**Returns**

* `string` The timezone identifier, like UTC or Europe/Lisbon.

## {Object} RequestOptions()

Request options

**Parameters**

| Name                            | Type     | Description                                                                                                                                   |            |
| ------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| json                            | `bool`   | Automatically add JSON Content-Type headers and decode the response. Defaults to `true`.                                                      | *Optional* |
| query                           | `object` | Parameters to append to the querystring.                                                                                                      |            |
| headers                         | `object` | Headers to send to the request.                                                                                                               |            |
| debug                           | `bool`   | Log request information and response headers. Defaults to `context.automation.debug` (`false`).                                               | *Optional* |
| skipJsonWrap                    | `bool`   | Skip the named auto wrapping of outgoing data. Defaults to `false`.                                                                           | *Optional* |
| include\_headers                | `bool`   | Include headers in the response. The response format will be [ResponseRaw](#object-responseraw).                                              | *Optional* |
| options.debug\_exclude\_headers | `array`  | Exclude headers from debugging information to keep secret keys a secret. An array of header keys (example: `Content-Type`).                   | *Optional* |
| stringify\_large\_ints          | `bool`   | If JSON response, and response has ints over the JS max int, will traverse entire payload and cast long ints to strings. Defaults to `false`. | *Optional* |

## {Object|String} Response()

Request response:

* [ResponseRaw](#object-responseraw) if `options.include_headers` is `true`,
* `object` if `options.json` is `true`,
* `string` if `options.json` is `false`.

## {Object} ResponseRaw()

Request response with headers when `options.include_headers` is `true`.

**Parameters**

| Name            | Type                                   | Description                                                 |   |
| --------------- | -------------------------------------- | ----------------------------------------------------------- | - |
| body            | [Response](#object-or-string-response) | Response from the server                                    |   |
| headers         | `object`                               | Headers to from response.                                   |   |
| request\_method | `string`                               | The method used to create the response: `GET`, `POST`, etc. |   |
| request\_url    | `string`                               | The URL used to create the response.                        |   |


# Filter

vendor/Filter.js

## Filter()

Procecsses filter conditions / values

**Returns**

* `Void`

## process(a, b, comparison, additional, options)

Processes filter comparison values, and comparison

**Parameters**

| Name                  | Type      | Description                                      |   |
| --------------------- | --------- | ------------------------------------------------ | - |
| a                     | `string`  |                                                  |   |
| b                     | `string`  |                                                  |   |
| comparison            | `string`  |                                                  |   |
| additional            | `array`   | Additional operator, a, b, and comparison fields |   |
| options               | `object`  |                                                  |   |
| options.setTaskStatus | `boolean` | If the task statis should be                     |   |
| options.strLabel      | `string`  | The text to set as the task's label              |   |

**Returns**

* `boolean`

## doProcessAdditional(additional)

Prevent empty context.trigger.metadata.additional values from being processed eg. metadata.additional: \[{operator: 'and', comparison: 'equals'}]

**Parameters**

| Name       | Type    | Description |   |
| ---------- | ------- | ----------- | - |
| additional | `Array` |             |   |

**Returns**

* `boolean`

## normalizeValue(value)

Convert comparison value from a string to something more comparable

**Parameters**

| Name  | Type     | Description |   |
| ----- | -------- | ----------- | - |
| value | `string` |             |   |

**Returns**

* `string` `boolean` `number`

## runCompare(a, b, comparison)

Runs compare with two values

**Parameters**

| Name       | Type                        | Description |   |
| ---------- | --------------------------- | ----------- | - |
| a          | `string` `boolean` `number` |             |   |
| b          | `string` `boolean` `number` |             |   |
| comparison | `string`                    |             |   |

**Returns**

* `boolean`

## stringify(a, b, comparison, additional)

Processes filter comparison values, and comparison

**Parameters**

| Name       | Type                        | Description                                      |   |
| ---------- | --------------------------- | ------------------------------------------------ | - |
| a          | `string` `boolean` `number` |                                                  |   |
| b          | `string` `boolean` `number` |                                                  |   |
| comparison | `string`                    |                                                  |   |
| additional | `array`                     | Additional operator, a, b, and comparison fields |   |

**Returns**

* `string`

## printableString(str)

Replace '' NaN with the string `(empty)`, handle other non-string types

**Parameters**

| Name | Type                        | Description |   |
| ---- | --------------------------- | ----------- | - |
| str  | `string` `boolean` `number` |             |   |

**Returns**

* `string`

## isEmpty(str)

Determine if a variable is empty. Definition of empty: undefined, null, empty string "", empty array \[], empty object {}

**Parameters**

| Name | Type                        | Description |   |
| ---- | --------------------------- | ----------- | - |
| str  | `string` `boolean` `number` |             |   |

**Returns**

* `boolean`


# Loop

vendor/Loop.js

## Loop()

Procecsses loop conditions / values

**Returns**

* `Void`

## runReplace(value, regexp, context)

Helper function runs the replace and render functions for each variable

**Parameters**

| Name    | Type     | Description |   |
| ------- | -------- | ----------- | - |
| value   |          |             |   |
| regexp  | `RegExp` |             |   |
| context |          |             |   |

**Returns**

*


# Transform

vendor/Transform.js

## Transform()

The Transform utility can be used to define a relationship between objects from different sources. After defining the relationship, utility methods can be used to do things such as convert data from one source to another, allowing users to then post to API endpoints without additional data manipulation.

**Returns**

* `Void`

## map(mapping, payload)

Map a payload object to the desired output format based on a mapping array.

**Parameters**

| Name    | Type     | Description                                                                                  |   |
| ------- | -------- | -------------------------------------------------------------------------------------------- | - |
| mapping | `array`  | An array of key / value pair objects containing where key is source, value is `destination`. |   |
| payload | `object` | The payload passed into the Task.                                                            |   |

**Returns**

* `Void`

## convert(context, payload)

Convert fields defined in a Transform trigger. This method is called from the Transform trigger scaffolding script.

**Parameters**

| Name    | Type     | Description                                                                                                                      |   |
| ------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- | - |
| context | `object` | The full context object passed into the Task. We use `context.source`, `context.trigger.metadata`, and `context.trigger.fields`. |   |
| payload | `object` | The payload passed into the Task.                                                                                                |   |

**Returns**

* `Void`

## safeSet(obj, key, value)

Proxy for \_.set with handling for line\_items\[].sku not captured in the array logic

**Parameters**

| Name  | Type     | Description |   |
| ----- | -------- | ----------- | - |
| obj   |          |             |   |
| key   | `string` |             |   |
| value |          |             |   |

**Returns**

* `Void`

## handleBracketStringSyntax(value)

For some reason "{{current\_item.fields\['Option 1']}}" doesn't work but "

{{current\_item.fields\[key]}}" does... this is a quick way to try to get it kind-of working

**Parameters**

| Name  | Type     | Description |   |
| ----- | -------- | ----------- | - |
| value | `string` |             |   |

**Returns**

* `string`


# oAuth

vendor/Oauth.js

## new Oauth(grantType, tokenKey)

Class containing methods to authenticate and make authenticated requests with a third party API

**Parameters**

| Name      | Type     | Description                                                         |   |
| --------- | -------- | ------------------------------------------------------------------- | - |
| grantType | `string` | Oauth grant type. One of: `refresh_token`, `password`, or `custom`. |   |
| tokenKey  | `string` | The key of the secret containing the oAuth token information.       |   |

**Examples**

```javascript
// Refresh token flow.
const Oauth = require('vendor/Oauth.js');
const oauth = new Oauth('refresh_token', 'service.oauth');
```

```javascript
// Username password flow.
const Oauth = require('vendor/Oauth.js');
// Save username and password from external standalone secrets.
let token = JSON.decode(Mesa.secret.get('service.oauth', '{}'));
token.username = Mesa.secret.get('service-username');
token.password = Mesa.secret.get('service-password');
Mesa.secret.set('service.oauth', JSON.stringify(token));
const oauth = new Oauth('password', 'service.oauth');
```

```javascript
// Skubana flow (access_token that does not expire)
const Oauth = require('vendor/Oauth.js');
const oauth = new Oauth('custom', 'skubana.oauth');
const getResponse = oauth.get('https://dev.skubana.com/v1/orders');
Mesa.log.info('Get Response: ', getResponse);
```

```javascript
// Oauth Usage
const getResponse = oauth.get('https://example.com/products.json');
const postResponse = oauth.post('https://example.com/products.json', {});
Mesa.log.info('Get Response: ', getResponse);
Mesa.log.info('Post Response: ', postResponse);
```

**Returns**

* `Void`

## constructor(grantType, tokenKey, hasHeaders)

**Parameters**

| Name       | Type      | Description |   |
| ---------- | --------- | ----------- | - |
| grantType  | `string`  |             |   |
| tokenKey   | `string`  |             |   |
| hasHeaders | `boolean` |             |   |

**Returns**

* `Void`

## init()

Init the access token

**Returns**

* `Void`

## request(method, path, data, options)

Request method with the refresh token retry if fails.

**Parameters**

| Name    | Type                   | Description                              |   |
| ------- | ---------------------- | ---------------------------------------- | - |
| method  | `string`               | Request method.                          |   |
| path    | `string`               | Request path.                            |   |
| data    | `object`               |                                          |   |
| options | `Types.RequestOptions` | Additional configuration for Oauth calls |   |

**Returns**

* `object`

## get(path\[, options])

Make a GET request to an external Rest API

**Parameters**

| Name    | Type                   | Description                              |            |
| ------- | ---------------------- | ---------------------------------------- | ---------- |
| path    | `string`               | Request path                             |            |
| options | `Types.RequestOptions` | Additional configuration for Oauth calls | *Optional* |

**Returns**

* `object`

## post(path, data\[, options])

Make a POST request to an external Rest API.

**Parameters**

| Name    | Type                   | Description                              |            |
| ------- | ---------------------- | ---------------------------------------- | ---------- |
| path    | `string`               | Request path                             |            |
| data    | `object`               | Request payload                          |            |
| options | `Types.RequestOptions` | Additional configuration for Oauth calls | *Optional* |

**Returns**

* `object`

## put(path, data\[, options])

Make a PUT request to an external Rest API.

**Parameters**

| Name    | Type                   | Description                              |            |
| ------- | ---------------------- | ---------------------------------------- | ---------- |
| path    | `string`               | Request path                             |            |
| data    | `object`               | Request payload                          |            |
| options | `Types.RequestOptions` | Additional configuration for Oauth calls | *Optional* |

**Returns**

* `object`

## patch(path, data\[, options])

Make a PATCH request to an external Rest API.

**Parameters**

| Name    | Type                   | Description                              |            |
| ------- | ---------------------- | ---------------------------------------- | ---------- |
| path    | `string`               | Request path                             |            |
| data    | `object`               | Request payload                          |            |
| options | `Types.RequestOptions` | Additional configuration for Oauth calls | *Optional* |

**Returns**

* `object`

## delete(path\[, options])

Make a DELETE request to an external Rest API.

**Parameters**

| Name    | Type                   | Description                              |            |
| ------- | ---------------------- | ---------------------------------------- | ---------- |
| path    | `string`               | Request path                             |            |
| options | `Types.RequestOptions` | Additional configuration for Oauth calls | *Optional* |

**Returns**

* `object`


# Shopify

vendor/Shopify.js

## Shopify()

Interact with the Shopify Admin API.

**Returns**

* `Void`

## request()

Make a request to a Shopify site.

This is just a wrapper to Mesa.shopify.request.

**Returns**

* `Void`

## Shopify.get(path\[, options, connectionInfo])

Make a GET request to a Shopify site.

**Parameters**

| Name           | Type                                     | Description                                                                                                                                          |            |
| -------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| path           | `string`                                 |                                                                                                                                                      |            |
| options        | [Options](#object-options)               | Additional configuration for Shopify calls                                                                                                           | *Optional* |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | If you would like to connect to a separate Shopify website that Mesa is not installed on, create a Custom App and include a `connectionInfo` object. | *Optional* |

**Returns**

* `object`

## handleImageList(path, options, connectionInfo)

Handles listing of images with pagination.

**Parameters**

| Name           | Type     | Description                                   |   |
| -------------- | -------- | --------------------------------------------- | - |
| path           | `string` | - Shopify REST endpoint path.                 |   |
| options        | `Object` | - Query options.                              |   |
| connectionInfo | `Object` | - Connection info for external Shopify sites. |   |

**Returns**

* `Array` Array of images in REST format.

## handleImage(originalPath, options, connectionInfo)

Handles retrieval of a single image by its ID for a specific product.

**Parameters**

| Name           | Type                                     | Description                                        |   |
| -------------- | ---------------------------------------- | -------------------------------------------------- | - |
| originalPath   | `string`                                 | - Original API endpoint path.                      |   |
| options        | [Options](#object-options)               | - Query options (not used in this implementation). |   |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | - Connection information for Shopify.              |   |

**Returns**

* `Object` Processed image data in REST format.

## handleProductCount(options, connectionInfo)

Handles the product count query.

**Parameters**

| Name           | Type | Description |   |
| -------------- | ---- | ----------- | - |
| options        |      |             |   |
| connectionInfo |      |             |   |

**Returns**

*

## handlePaginatedGraphQLQuery(queryFunction, options, transformFunction, connectionInfo)

Handles paginated GraphQL queries for products or variants.

**Parameters**

| Name              | Type       | Description                                                             |   |
| ----------------- | ---------- | ----------------------------------------------------------------------- | - |
| queryFunction     | `Function` | - Function that generates a GraphQL query.                              |   |
| options           | `Object`   | - Query options, including filters and limits.                          |   |
| transformFunction | `Function` | - Function to transform the returned data into the desired REST format. |   |
| connectionInfo    | `Object`   | - Optional connection info for external Shopify sites.                  |   |

**Returns**

* `Array` Array of transformed paginated results.

## handleProductList(path, options, connectionInfo)

Handles listing of products with pagination.

**Parameters**

| Name           | Type     | Description                                   |   |
| -------------- | -------- | --------------------------------------------- | - |
| path           | `string` | - Shopify REST endpoint path.                 |   |
| options        | `Object` | - Query options.                              |   |
| connectionInfo | `Object` | - Connection info for external Shopify sites. |   |

**Returns**

* `Array` Array of products in REST format.

## Shopify.handleProduct(originalPath, options, connectionInfo)

Retrieve a single product by ID using GraphQL and convert it to REST format.

**Parameters**

| Name           | Type                                     | Description                                            |   |
| -------------- | ---------------------------------------- | ------------------------------------------------------ | - |
| originalPath   | `string`                                 | - Original API endpoint path.                          |   |
| options        | [Options](#object-options)               | - Options containing query parameters.                 |   |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | - Connection information for a separate Shopify store. |   |

**Returns**

* `object` Product data in REST format.

## Shopify.handleProductPost(data\[, connectionInfo])

Handles the creation of a product and its variants, if provided. Converts the REST payload into the appropriate GraphQL format.

**Parameters**

| Name           | Type                                     | Description                            |            |
| -------------- | ---------------------------------------- | -------------------------------------- | ---------- |
| data           | `Object`                                 | - The product data in REST API format. |            |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | - Connection information for Shopify.  | *Optional* |

**Returns**

* `Object` - The product payload in REST API format.

## handleVariantList(path, options, connectionInfo)

Handles listing of variants with pagination.

**Parameters**

| Name           | Type     | Description                                   |   |
| -------------- | -------- | --------------------------------------------- | - |
| path           | `string` | - Shopify REST endpoint path.                 |   |
| options        | `Object` | - Query options.                              |   |
| connectionInfo | `Object` | - Connection info for external Shopify sites. |   |

**Returns**

* `Array` Array of variants in REST format.

## Shopify.handleVariant(originalPath, options, connectionInfo)

Retrieve a specific variant by product ID and variant ID using GraphQL and convert it to REST format.

**Parameters**

| Name           | Type                                     | Description                                            |   |
| -------------- | ---------------------------------------- | ------------------------------------------------------ | - |
| originalPath   | `string`                                 | - Original API endpoint path.                          |   |
| options        | [Options](#object-options)               | - Options containing query parameters.                 |   |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | - Connection information for a separate Shopify store. |   |

**Returns**

* `object` Variant data in REST format.

## handleImagePost(data, connectionInfo)

Handles the creation of a product image. Converts the REST payload to GraphQL format and returns the response in REST format.

**Parameters**

| Name           | Type                                     | Description                |   |
| -------------- | ---------------------------------------- | -------------------------- | - |
| data           | `Object`                                 | - The REST image payload.  |   |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | - Shopify connection info. |   |

**Returns**

* `Object` - The image payload in REST format.

## send(query, variables, connectionInfo, endpoint)

Send a GraphQL query to Shopify.

**Parameters**

| Name           | Type | Description |   |
| -------------- | ---- | ----------- | - |
| query          |      |             |   |
| variables      |      |             |   |
| connectionInfo |      |             |   |
| endpoint       |      |             |   |

**Returns**

* `object`

## Shopify.post(path, data\[, options, connectionInfo])

Make a POST request to a Shopify site.

By default Shopify calls will auto-wrap any outgoing JSON data, eg. Shopify.post('/admin/products.json', data) will result in { "product": { data } } use options.skipJsonWrap=true to override this behavior

**Parameters**

| Name           | Type                                     | Description                                                                                                                                          |            |
| -------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| path           | `string`                                 |                                                                                                                                                      |            |
| data           | `object`                                 |                                                                                                                                                      |            |
| options        | [Options](#object-options)               | Additional configuration for Shopify calls                                                                                                           | *Optional* |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | If you would like to connect to a separate Shopify website that Mesa is not installed on, create a Custom App and include a `connectionInfo` object. | *Optional* |

**Returns**

* `object`

## handleVariantPut(productId, variantId, data, connectionInfo)

Handles updating a single variant for a specific product.

**Parameters**

| Name           | Type                                     | Description                   |   |
| -------------- | ---------------------------------------- | ----------------------------- | - |
| productId      | `string`                                 | - The ID of the product.      |   |
| variantId      | `string`                                 | - The ID of the variant.      |   |
| data           | `Object`                                 | - The variant data to update. |   |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | - Shopify connection details. |   |

**Returns**

* `Object` - The updated variant in REST format.

## handleProductPut(productId, data, connectionInfo)

Handles the updating of a product and its related entities (variants, images, etc.).

**Parameters**

| Name           | Type                                     | Description                        |   |
| -------------- | ---------------------------------------- | ---------------------------------- | - |
| productId      | `string`                                 | - The ID of the product to update. |   |
| data           | `Object`                                 | - The product data to update.      |   |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | - Shopify connection details.      |   |

**Returns**

* `Object` - The updated product in REST format.

## Shopify.put(path, data\[, options, connectionInfo])

Make a PUT request to a Shopify site.

By default Shopify calls will auto-wrap any outgoing JSON data, eg. Shopify.put('/admin/products.json', data) will result in { "product": { data } } use options.skipJsonWrap=true to override this behavior

**Parameters**

| Name           | Type                                     | Description                                                                                                                                          |            |
| -------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| path           | `string`                                 |                                                                                                                                                      |            |
| data           | `object`                                 |                                                                                                                                                      |            |
| options        | [Options](#object-options)               | Additional configuration for Shopify calls                                                                                                           | *Optional* |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | If you would like to connect to a separate Shopify website that Mesa is not installed on, create a Custom App and include a `connectionInfo` object. | *Optional* |

**Returns**

* `object`

## Shopify.patch(path, data\[, options, connectionInfo])

Make a PATCH request to a Shopify site.

By default Shopify calls will auto-wrap any outgoing JSON data, eg. Shopify.patch('/admin/products.json', data) will result in { "product": { data } } use options.skipJsonWrap=true to override this behavior

**Parameters**

| Name           | Type                                     | Description                                                                                                                                          |            |
| -------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| path           | `string`                                 |                                                                                                                                                      |            |
| data           | `object`                                 |                                                                                                                                                      |            |
| options        | [Options](#object-options)               | Additional configuration for Shopify calls                                                                                                           | *Optional* |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | If you would like to connect to a separate Shopify website that Mesa is not installed on, create a Custom App and include a `connectionInfo` object. | *Optional* |

**Returns**

* `object`

## Shopify.delete(path\[, options, connectionInfo])

Make a DELETE request to a Shopify site.

By default Shopify calls will auto-wrap any outgoing JSON data, eg. Shopify.post('/admin/products.json', data) will result in { "product": { data } } use options.skipJsonWrap=true to override this behavior

**Parameters**

| Name           | Type                                     | Description                                                                                                                                          |            |
| -------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| path           | `string`                                 |                                                                                                                                                      |            |
| options        | [Options](#object-options)               | Additional configuration for Shopify calls                                                                                                           | *Optional* |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | If you would like to connect to a separate Shopify website that Mesa is not installed on, create a Custom App and include a `connectionInfo` object. | *Optional* |

**Returns**

* `object`

## getMyshopifyDomain(context)

Returns myshopify domain from the connection.

**Parameters**

| Name    | Type | Description |   |
| ------- | ---- | ----------- | - |
| context |      |             |   |

**Returns**

* `string` The myshopify domain. Ex: mystore.myshopify.com

## getShopifyAdminUrl(context)

Returns myshopify domain from the connection.

**Parameters**

| Name    | Type | Description |   |
| ------- | ---- | ----------- | - |
| context |      |             |   |

**Returns**

* `string` The Shopify admin url, including https\://. Ex: <https://admin.shopify.com/store/mystore>

## getShopifyUuid(context)

Returns the subdomain part of the myshopify domain from the connection.

**Parameters**

| Name    | Type | Description |   |
| ------- | ---- | ----------- | - |
| context |      |             |   |

**Returns**

* `string` The subdomain part of the myshopify domain. Ex: mystore

## deleteProduct(path, options, connectionInfo)

Delete a product by ID.

**Parameters**

| Name           | Type     | Description                                   |   |
| -------------- | -------- | --------------------------------------------- | - |
| path           | `string` | - Shopify REST endpoint path.                 |   |
| options        | `Object` | - Query options.                              |   |
| connectionInfo | `Object` | - Connection info for external Shopify sites. |   |

**Returns**

* `Void`

## deleteVariant(path, options, connectionInfo)

Delete a variant by ID.

**Parameters**

| Name           | Type     | Description                                   |   |
| -------------- | -------- | --------------------------------------------- | - |
| path           | `string` | - Shopify REST endpoint path.                 |   |
| options        | `Object` | - Query options.                              |   |
| connectionInfo | `Object` | - Connection info for external Shopify sites. |   |

**Returns**

* `Void`

## deleteImage(path, options, connectionInfo)

Delete a product image by ID.

**Parameters**

| Name           | Type     | Description                                   |   |
| -------------- | -------- | --------------------------------------------- | - |
| path           | `string` | - Shopify REST endpoint path.                 |   |
| options        | `Object` | - Query options.                              |   |
| connectionInfo | `Object` | - Connection info for external Shopify sites. |   |

**Returns**

* `Void`

## getAllProducts(\[query={}, limit=250])

Make consecutive calls to Shopify in order to retrieve all products. <https://help.shopify.com/en/api/reference/products/product>

**Parameters**

| Name      | Type     | Description                                      |            |
| --------- | -------- | ------------------------------------------------ | ---------- |
| query={}  | `object` | Parameters to append to the Shopify querystring. | *Optional* |
| limit=250 | `number` | Result count for Shopify query.                  | *Optional* |

**Examples**

```javascript
// returns array of all products
const Shopify = require('vendor/Shopify.js');
Shopify.getAllProducts();
```

**Returns**

* `array`

## appendToArray(\[data], The)

Update a value if it already exists, or append it to the array if it does not exist. The example routine below should be every time we are updating `tags` or `note_attributes` to ensure that multiple Automations will work nicely with each other and not overwrite values set in other Automations.

**Parameters**

| Name | Type              | Description                                                                                                         |            |
| ---- | ----------------- | ------------------------------------------------------------------------------------------------------------------- | ---------- |
| data | `array`           | An array of values that you would like to append a value to                                                         | *Optional* |
| The  | `string` `object` | value to append to the array. For `tags`, this would be a `string`. For `note_attributes`, this would be an object. |            |

**Examples**

```javascript
Mesa.log.debug('Calling shopify to get the latest order note_attributes');
const order = Shopify.get(`admin/orders/${payload.id}.json`);
let noteAttributes = order.order.note_attributes;
noteAttributes = Shopify.appendToArray(noteAttributes, {
  name: 'dob',
  value: 'Jan 1 2000',
});
```

**Returns**

* `array`

## getVariantInventoryData(variantId)

Get inventory location information for a Shopify variant. <https://help.shopify.com/en/api/reference/inventory/inventorylevel>

**Parameters**

| Name      | Type     | Description         |   |
| --------- | -------- | ------------------- | - |
| variantId | `number` | Shopify variant id. |   |

**Examples**

```javascript
// returns { inventory_item_id: {number}, [ { inventory_levels: { inventory_item_id: {number}, location_id: {number}, available: {number}, updated_at: {string} } ] }
const Shopify = require('vendor/Shopify.js');
Shopify.getVariantInventoryData(123456);
```

**Returns**

* `&lt;a href&#x3D;&quot;#object-inventorydata&quot;&gt;InventoryData&lt;/a&gt;`

## buildVariantInventoryUpdate(variantId, inventoryCount\[, adjust=true, fulfillableAlter])

Build InventoryLevel update information for a Shopify variant. <https://help.shopify.com/en/api/reference/inventory/inventorylevel>

**Parameters**

| Name             | Type                                  | Description                                                  |            |
| ---------------- | ------------------------------------- | ------------------------------------------------------------ | ---------- |
| variantId        | `number`                              | Shopify variant id.                                          |            |
| inventoryCount   | `number`                              | Value to set as inventory.                                   |            |
| adjust=true      | `bool`                                | Switch for available\_adjustment vs available.               | *Optional* |
| fulfillableAlter | [fulfillableAlter](#fulfillablealter) | Callback function allows fulfillment location to be altered. | *Optional* |

**Examples**

```javascript
// note string for location_id, as it is required by Shopify API post
// returns { inventory_item_id: {number}, location_id: {string}, available|available_adjustment: {number} } ] }
const Shopify = require('vendor/Shopify.js');
Shopify.buildVariantInventoryUpdate(123456, 10, true | false);
```

**Returns**

* `&lt;a href&#x3D;&quot;#object-inventoryupdatedata&quot;&gt;InventoryUpdateData&lt;/a&gt;`

## {Object} Options()

options parameter for Shopify calls

By default Shopify calls will auto-wrap any outgoing JSON data, eg. Shopify.post('/admin/products.json', data) will result in { "product": { data } } use skipJsonWrap=true to override this behavior

**Properties**

**Returns**

* `Void`

## {Object} ConnectionInfo()

connectionInfo parameter for Shopify calls

**Properties**

**Returns**

* `Void`

## {Object} FulfillableLocation()

Fulfillable location shape returned by fulfillableAlter <https://help.shopify.com/en/api/reference/inventory/location>

**Parameters**

| Name         | Type     | Description                                                 |   |
| ------------ | -------- | ----------------------------------------------------------- | - |
| location\_id | `number` | The ID of the location that the inventory level belongs to. |   |

**Returns**

* `Void`

## {Function} fulfillableAlter(inventoryLevels)

Callback allows buildVariantInventoryUpdate fulfillment location to be altered. <https://help.shopify.com/en/api/reference/inventory/inventorylevel>

**Parameters**

| Name                                | Type                     | Description                                              |   |
| ----------------------------------- | ------------------------ | -------------------------------------------------------- | - |
| inventoryLevels                     | `Array.&#60;Object&#62;` | Inventory levels for the variant at different locations. |   |
| inventoryLevels.inventory\_item\_id | `number`                 | Inventory item id for variant                            |   |
| inventoryLevels.location\_id        | `number`                 | Location id                                              |   |
| inventoryLevels.available           | `number`                 | Inventory count                                          |   |
| inventoryLevels.updated\_at         | `string`                 | Last updated                                             |   |

**Returns**

* `&lt;a href&#x3D;&quot;#object-fulfillablelocation&quot;&gt;FulfillableLocation&lt;/a&gt;` fulfillableLocation

## {Object} InventoryData()

Return from getVariantInventoryData.

**Properties**

**Returns**

* `Void`

## {Object} InventoryUpdateData()

Return from buildVariantInventoryUpdate. Will either have available or available\_adjustment depending on adjust param. <https://help.shopify.com/en/api/reference/inventory/inventorylevel>

**Properties**

**Returns**

* `Void`


# ShopifyGraphql

vendor/ShopifyGraphql.js

## new ShopifyGraphql()

Graphql Library

**Returns**

* `Void`

## ShopifyGraphql.send(query, variables\[, connectionInfo, endpoint])

Grapqhl call to Shopify.

**Parameters**

| Name           | Type                                     | Description                                                                                                                                          |            |
| -------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| query          | `string`                                 | Graphql query with variables.                                                                                                                        |            |
| variables      | `object`                                 | Object with graphql query variables.                                                                                                                 |            |
| connectionInfo | [ConnectionInfo](#object-connectioninfo) | If you would like to connect to a separate Shopify website that Mesa is not installed on, create a Custom App and include a `connectionInfo` object. | *Optional* |
| endpoint       | `string`                                 | Override the Shopify GraphQL endpoint, for example to call a custom API version. Defaults to 'admin/graphql.json'.                                   | *Optional* |

**Examples**

```javascript
// Query example
const query = `query {
    shop {
      name
      primaryDomain {
        url
        host
      }
    }
   }`;
const rest =  Graphql.send(query, '');
```

**Returns**

* `object` Graphql response.

## ShopifyGraphql.addOrUpdateMetafields(id, metafields)

Adds a metafields to Shopify order. This function will add a metafield id to the payload if metafield already exits.

**Parameters**

| Name       | Type                         | Description          |   |
| ---------- | ---------------------------- | -------------------- | - |
| id         | `string`                     | Shopify Order ID.    |   |
| metafields | `Array.&#60;Metafields&#62;` | Array of metafields. |   |

**Examples**

```javascript
const shopifyOrderId = 1234;
const metafields = [{
       namespace: "example",
       key: "example_key",
       value: "example_value"
   }];
const response =  Graphql.addOrUpdateMetafields(shopifyOrderId, metafields, "order");
Mesa.log.info('Graphql response: ', response);
```

**Returns**

* `object` Graphql response

## ShopifyGraphql.addMetafields(id, metafields, entity)

Adds a metafield to a Shopify entity. This function will throw an error if metafield exists and you do not pass an id.

**Parameters**

| Name       | Type                         | Description          |         |
| ---------- | ---------------------------- | -------------------- | ------- |
| id         | `string`                     | Entity id.           |         |
| metafields | `Array.&#60;Metafields&#62;` | Array of metafields. |         |
| entity     | `string`                     | Entity: Order        | Product |

**Returns**

* `Void`

## ShopifyGraphql.groupMetafieldsByKey(data)

Takes metafield results, returns object keyed by the metafield key

**Parameters**

| Name | Type     | Description |   |
| ---- | -------- | ----------- | - |
| data | `object` |             |   |

**Returns**

* `object` metafields

## ShopifyGraphql.buildShopifyId(entity, id)

Builds Shopfiy Graphql id.

**Parameters**

| Name   | Type     | Description             |   |
| ------ | -------- | ----------------------- | - |
| entity | `string` | Shopfiy graphql entity. |   |
| id     | `string` | Shopify entity id.      |   |

**Returns**

* `string` Shopfiy graphql id

## ShopifyGraphql.extractShopifyId(gid)

Builds Shopfiy Graphql id.

**Parameters**

| Name | Type     | Description                                                         |   |
| ---- | -------- | ------------------------------------------------------------------- | - |
| gid  | `string` | Shopfiy graphql id (ex: gid://shopify/ShippingLabelV2/637424009250) |   |

**Returns**

* `string` Shopfiy id without the gid notation (ex: 637424009250)

## {Object} Metafields()

Metafields

**Properties**

**Returns**

* `Void`

## {Object} ConnectionInfo()

connectionInfo parameter for Shopify calls

**Properties**

**Returns**

* `Void`


# FAQ

## Can I use fetch in a custom code step?

No, because the custom code environment is a V8 environment, fetch is not available. However, MESA.request is our replacement for it. You can check out the [MESA SDK](https://docs.getmesa.com/tools/custom-code/sdk) for more information on available functions in the custom code step.

## How do you throw an error from within a custom code step?

You can do that by using:

```
throw new Error("your error description")
```

## How do I get advanced details related to my automation?

To check if an automation was triggered by a "test" (triggered by a [manual run](https://docs.getmesa.com/workflow-builder/testing) in a workflow) or by an actual "live" run (usually triggered with webhooks) you can check for `context.task.is_test`

* Mesa will set `context.task.is_test` to `true` if the automation was a manual run
* Mesa will set `context.task.is_test` to `false` if the automation was triggered naturally

You can also explore what `context.task` has by logging it in your code: `Mesa.log.info('context.task', context.task);`

* For example, you can access the workflow title as: `context.task.automation.automation_name`


# Data

The **Data** tool lets you save and read information in a private database built into MESA.

The Data allows you to persist information between workflow runs; saving data from one workflow and accessing it in another.

## Configure <a href="#configuring" id="configuring"></a>

You can create tables from within any Data step that allows you to create or update a row, for example, Data's "Create Record" action.

<figure><img src="/files/AQyXl5Y3ib6rKeyRu10j" alt="Screenshot of a MESA Data Create Record action. Spotlight the table name field and the Add column controls."><figcaption></figcaption></figure>

Specify a table name and begin adding columns to your table.

Give each column a name and type by choosing one of our supported column types, and select the data to store in that column by selecting [variables](https://docs.getmesa.com/workflow-builder/fields/variables) or adding static text to the column's value field.

Choose one of our supported column types:

<table data-full-width="true"><thead><tr><th>Type</th><th>SQL Type</th><th>When to use</th><th>Example</th></tr></thead><tbody><tr><td>Text</td><td>varchar(255)</td><td>Ideal for most text strings (keys, titles, names, etc). Maximum length: 255 characters.</td><td>Jannette Parks</td></tr><tr><td>Long Text</td><td>text</td><td>For free-form text and JSON blobs.</td><td>Jannette Parks likes to go to the park and play on the swings, the merry-go-round, and the super-duper play structure. She's an adventurer and she likes the thrill. She would stay at the park all day long, every day in fact, if she had the chance, and play with her yeti friend, Yedric.</td></tr><tr><td>Integer</td><td>int8</td><td>For integers and numeric IDs. Supports numbers between -9223372036854775808 and 9223372036854775807.</td><td>13</td></tr><tr><td>Number</td><td>numeric</td><td>For numbers with decimal-point precision.</td><td>13.99</td></tr><tr><td>Date</td><td>date</td><td>For dates</td><td>2024-11-30</td></tr><tr><td>Date and time</td><td>timestamptz</td><td>For date and times, with timezone information.</td><td>2024-11-30 13:24:00-07</td></tr><tr><td>Boolean</td><td>bool</td><td>Values that are either true or false</td><td>True</td></tr></tbody></table>

It is recommended that you label your columns with no spaces included.

Columns will be in the same order as they're created here.

Three additional columns will be automatically added: mesa\_id, mesa\_created\_at, mesa\_updated\_at

Click the workflow's "Save" button to save your columns to the database.

{% hint style="info" %}
Once you save your workflow, to avoid affecting workflows that may use the same table, you can no longer delete the column or adjust your column's Name or Type from the user interface.
{% endhint %}

You can run one of the queries in the Altering Tables section below if you need to adjust your columns.

### Populating a table <a href="#browsing" id="browsing"></a>

You can select the data to store in the column's value field.

One method is selecting through [variables](https://docs.getmesa.com/workflow-builder/fields/variables):

<figure><img src="/files/2PSFH7HECNCDw8rmUZ0o" alt="Screenshot of a MESA Data step column value field. Spotlight the variable selector used to store data in the column."><figcaption></figcaption></figure>

Another option is to add your own text:

<figure><img src="/files/9YXLFkigbgOZiEPGHzPE" alt="Screenshot of a MESA Data step column value field. Spotlight the value field with static text entered."><figcaption></figcaption></figure>

### Viewing a table <a href="#browsing" id="browsing"></a>

Go to My account under your account name.

![Screenshot of the MESA account menu. Spotlight the My account option under your account name.](/files/8CxMVlna9FkEDpafmRR0)

Then, click on the Data tab.

<figure><img src="/files/6Z5Lj523hjP4XUFnDT72" alt="Screenshot of the MESA My account page. Spotlight the Data tab."><figcaption></figcaption></figure>

Select View Data to browse the data in the table or Database Options to Query or Alter the table:

![Screenshot of the MESA Data tab. Spotlight the View Data button for a table.](/files/ZwccF7JFypXZQ9CkRRQQ)

![Screenshot of the MESA Data tab. Spotlight the Database Options menu with the Query and Alter options.](/files/DYtLsviyq9ny0Oo0SpBb)

### Using data stored in a table <a href="#example-queries" id="example-queries"></a>

#### Retrieve Record action

To use stored data in a table, you can use the Retrieve Record action. This retrieves a single row. For example, you can retrieve one particular order.

#### Query Action

This action retrieves multiple rows. For example, you can use this step to grab all of a user's orders.

#### Example Queries <a href="#example-queries" id="example-queries"></a>

Only show records that contain a string

```sql
SELECT * FROM "customers" WHERE "email" ILIKE '%@getmesa.com%';
```

Only show records created after a certain UTC date and time, sorted newest first:

```sql
SELECT * FROM "customers" WHERE "mesa_created_at" > '2022-01-04T17:51:00.000Z'
  ORDER BY "mesa_created_at" DESC;
```

Join two tables together:

```sql
SELECT * FROM "orders"
  LEFT JOIN "customers" ON "orders"."customer_id" = "customers"."id";
```

[More examples and information about SELECT queries](https://neon.com/postgresql/postgresql-tutorial/postgresql-select).

#### Record Created or Record Updated trigger

This step starts a workflow when a new row is added to the table or a row has one of its values changed.

## Going Further <a href="#altering" id="altering"></a>

### Alter Tables <a href="#altering" id="altering"></a>

You can remove columns or change their type by running an ALTER query. Go to the **Settings** Page and click the ⚙ cog icon next to the table. The query box will be pre-populated with some commented-out SQL queries to help you get started.

#### Remove a column <a href="#removing" id="removing"></a>

To remove a column, uncomment the first line and the DROP COLUMN line, replace `{{column_name}}` with your column, and click **Run Query**. For example:

```sql
ALTER TABLE "line_items"
  DROP COLUMN "{{column_name}}"
```

#### Change a column type <a href="#changing-column-type" id="changing-column-type"></a>

To change the column type, uncomment the first line and the ALTER COLUMN line corresponding to the column you would like to change by removing the `--` at the beginning of each line. Then change the column type to one of the options in the **Column types** listed below:

```sql
ALTER TABLE "line_items"
  ALTER COLUMN "order_id" TYPE decimal
```

Note that in some cases (especially if you have existing data), changing the column may not be as easy as running the query above. In these cases, removing the column and re-adding it from the workflow builder with the new desired column type may be easier.

[More examples and information about ALTER queries](https://neon.com/postgresql/postgresql-tutorial/postgresql-alter-table).

#### Delete a table <a href="#deleting" id="deleting"></a>

To delete a table, use the following query:

```sql
DROP TABLE "Add table name here"
```

You will need to change the **Add table name here** text to the name of your table and keep the double quotations.

### Column types <a href="#column-types" id="column-types"></a>

Data supports the following column types:

* Text `varchar(255)`: Ideal for most text strings (keys, titles, names, etc). Maximum length: 255 characters.
* Long Text `text`: For free-form text and JSON blobs.
* Integer `int8`: For integers and numeric IDs. Supports numbers between -9223372036854775808 and 9223372036854775807.
* Number `numeric`: For numbers with decimal-point precision.
* Date `date`: For dates.
* Date and time `timestamptz`: For date and times. Includes timezone information.

### Connect to your data <a href="#using-credentials" id="using-credentials"></a>

Use your connection details from the Settings page to connect directly to your Data tool's database. You can use these connections for a desktop querying client or business intelligence tool or read and write data directly from your custom application.

* Business Intelligence Clients
  * [Metabase](https://www.metabase.com/): an open-source BI tool for exploring, visualizing, and sharing data via a user-friendly interface, with support for both simple queries and advanced SQL
  * [Tableau](https://www.tableau.com): a powerful analytics platform for creating interactive visualizations and dashboards, enabling users to explore and share data insights with ease.
* SQL Clients
  * [Beekeeper Studio](https://www.beekeeperstudio.io/): an open-source SQL editor and database manager offering a clean interface for querying, editing, and managing databases efficiently.
  * [TablePlus](https://tableplus.com/): a modern database management tool with a sleek interface designed to simplify querying, editing, and managing multiple databases efficiently.

## Technical Notes

* Data is built on top of PostgresSQL and supports its features. [Learn more about connecting to PostgreSQL databases](https://www.postgresql.org/docs/current/ecpg-sql-connect.html).
* The Record Created and Record Updated triggers utilize [polling](https://docs.getmesa.com/workflow-builder/triggers#polling) to detect changes.


# Delay

The **Delay** tool allows you to delay or pause your workflow before it can proceed to the next action. Delays can be used after a [trigger](https://docs.getmesa.com/workflow-builder/triggers) has occurred.

You can insert a number and select from Minute(s), Hours(s), Day(s), Week(s), or Month(s).

<figure><img src="/files/UtDiDX9GDZtCGcu7Lwlx" alt="Screenshot of a MESA Delay step. Spotlight the number input and the time unit dropdown offering Minutes, Hours, Days, Weeks, and Months."><figcaption></figcaption></figure>

{% hint style="info" %}
The **minimum** amount of delay is determined by your billing plan:

* Flex plan: 15 minutes
* Advanced plan: 5 minutes
* Unlimited plan: 1 minute
* Enterprise plan: 1 minute
* Affiliate plan: 1 minute
  {% endhint %}

{% hint style="info" %}
The **maximum** amount of delay is determined by your billing plan:

* Flex plan: 30 days
* Advanced plan: 30 days
* Unlimited plan: 60 days
* Enterprise plan: 90 days
* Affiliate plan: 30 days
  {% endhint %}

## Advanced Settings

By selecting **More fields**, you can choose to skip the Delay step entirely so that the workflow runs for any manual runs, step replays, or Time Travels. [If you are conducting a manual run, this is recommended so you don't have to wait until the workflow continues.](/workflow-builder/testing#running-a-test)

<figure><img src="/files/2XjvyNeXzAO7l4iJVv5S" alt="Screenshot of a MESA Delay step. Spotlight the More fields button."><figcaption></figcaption></figure>

<figure><img src="/files/yvy9M1s3QY7YZyi1jqcf" alt="Screenshot of a MESA Delay step with More fields expanded. Spotlight the checkbox to skip the delay for manual runs, step replays, or Time Travel."><figcaption></figcaption></figure>

{% hint style="info" %}
**Note**: The Delay will be skipped if **Skip the delay for manual runs, step replays, or Time Travel** is checked and the Delay step is used in a manual run, replayed, or involved in a Time Travel. If an earlier step in the workflow is replayed (for example the trigger step), the Delay step will not be skipped.
{% endhint %}


# Email

The Email tool allows you to add email functionality to your workflow.\
\
The **Email trigger** allows you to trigger a workflow from an email that's received, and the **Email action** can send an email.

The Email tool is best for one-off notifications or transactional emails.

{% hint style="info" %}
Email is a premium app. There is a limit to the number of Premium actions we provide for free. [Learn more](https://docs.getmesa.com/going-further/plans-and-billing#premium-steps)
{% endhint %}

## Configure

### Email Trigger

<figure><img src="/files/xjrXMvZiwYp1WNRFmrFD" alt="Screenshot of the Email Trigger step expanded in the MESA workflow builder showing the custom MESA email address. Spotlight the custom email address clipboard icon."><figcaption></figcaption></figure>

The **Email Trigger** allows you to trigger a workflow when an email is received at a custom MESA email address. The custom email address can be found by expanding the Receive Email trigger, and you can copy it using the clipboard icon.

The information (Email Subject, Message, and Sender) sent to the custom email address can be used as [MESA variables](/workflow-builder/fields/variables) in steps later in the workflow.

### Email Action

<figure><img src="/files/tGied8xQxMi1AstTl8HY" alt="Screenshot of the Email action step in the MESA workflow builder. Spotlight the Recipient, Subject, and Message fields."><figcaption></figcaption></figure>

The **Email action** sends an email to a Recipient or Recipients of your choice and allows you to set the Subject and Message body.

The **Recipient** field can be set in two ways: it can be a fixed address (sending emails to your warehouse at a specific email address) or a variable (sending emails to different customer email addresses). You can use commas in the Recipient field to specify multiple recipients.

The **Message** field can be customized with plain text, [variables](https://docs.getmesa.com/workflow-builder/fields/variables), HTML code, or a combination of all three.

If HTML code is detected in the Message field, a formatted email will be sent. If no HTML tags are detected in your Message, a plain-text email will be sent.

Lastly, you can access additional fields, such as BCC, From, Reply To, and more, by clicking on **More options** in the step.

## Going Further

#### Using Liquid in your emails

To add an array of information to your Email body, we recommend using [Shopify Liquid](https://shopify.dev/docs/api/liquid).

#### Improving Deliverability

If you're experiencing delivery issues with your emails or they’re ending up in SPAM, especially with DKIM records configured, consider leaving the From email address blank. This will result in emails being sent from <no-reply@mail.mymesa.site>. You can set the Reply-To email address to the one where you want to receive replies; it will default to your store's contact email in Shopify.

#### **Using attachments**

You can add attachments to your email by inputting the URL of the attachment.

We currently don’t support sharing URLs from Google Drive or Dropbox, nor can you upload files directly in MESA. The attachment URL must be publicly accessible so MESA can access the file directly. We recommend using a service like [Shopify Files](https://help.shopify.com/en/manual/shopify-admin/productivity-tools/file-uploads) to upload your files and then copy the URL from there.

#### Manual Run Behavior

You can manually run the **Email trigger** by sending an email to the custom MESA email address associated with your step in the **Configure** submenu while your workflow is enabled.

When conducting manual runs with the **Email action**, it's important to avoid sending test emails to the actual recipient. To help prevent this, consider the following best practices:

1. **Change the Recipient Email**: If you're conducting a manual run, you can change the Recipient email to your own email address or an email address that's not associated with the order.
2. **Manual Run Override Email**: For manual runs, you can click the More fields button at the bottom of the step to add a test-specific email address in the "Manual run override email" field. This ensures that the intended recipient doesn't mistakenly receive test emails.<br>

   <figure><img src="/files/Su7rdJ9uuq0Tayo5l9gI" alt="Screenshot of the Email action More fields section in MESA. Spotlight the Manual run override email field."><figcaption></figcaption></figure>
3. **Heads Up**: Keep in mind that the email address linked to the selected manual run record will receive any emails sent during the run unless you've set a Manual run override email. Always double-check the email settings before proceeding with the manual run to avoid accidental notifications.

By following these best practices, you can ensure that emails sent from manual runs are sent to the right addresses and that your real recipients are not impacted.

## Technical Notes

* Sending SPAM is strictly prohibited. If you have questions about your specific use case, please contact us.
* This tool is not intended for newsletters or marketing emails.
* The Email tool does not allow you to add custom [SPF](https://en.wikipedia.org/wiki/Sender_Policy_Framework), [DKIM](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail), or [DMARC](https://en.wikipedia.org/wiki/DMARC) records to your domain name's DNS record, which helps improve email deliverability. If you would like to use these features, we recommend using MESA's [Mailgun connector](/connect/mailgun).
* Please note that the email message, including attachments, cannot exceed the per-message size limit of 25MB, or it may be permanently lost.


# Filter

The **Filter** tool is a step that lets you stop your workflow based on the conditions you set. A Filter is different than a [Path](https://docs.getmesa.com/tools/paths) because it controls whether or not your workflow continues. A Path continues the workflow for a different outcome based on the conditions set.

You should use a Filter in your workflow when there are certain reasons why you would want your workflow to stop or continue or to only act on specific items or instances.

## Configure

When using the Filter tool, you will need to select the correct [variables](/workflow-builder/fields/variables) so that MESA can apply the filtering based on the data returned by the previous steps of your workflow.

When available, recommended variables will auto-populate in a dropdown menu, but you can always click to see the full list of variables available.

<figure><img src="/files/Nw0Eo7gf4M5d1W8beIRP" alt="Screenshot of the Filter tool in the MESA workflow builder showing recommended variables. Spotlight the variable dropdown menu."><figcaption></figcaption></figure>

## Examples of Conditions <a href="#examples" id="examples"></a>

The Filter tool has nineteen conditions you can use to compare values.

<table data-full-width="true"><thead><tr><th>Condition</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>Equals</td><td>A specified field matches an exact value provided</td><td>The number of line items in an order is equal to 2</td></tr><tr><td>Does not equal</td><td>A specified field does not match an exact value provided</td><td>The number of line items in an order is not equal to 2</td></tr><tr><td>Contains</td><td>A specified field includes a certain value within its content, regardless of its position in the text</td><td>An order's tags contains a "VIP" tag</td></tr><tr><td>Does not contain</td><td>A specified field does not include a certain value within its content, regardless of its position in the text</td><td>An order's tags does not contain a "VIP" tag</td></tr><tr><td>Is empty</td><td>A specified field has no data, meaning it is blank or null</td><td>An order's tags are empty</td></tr><tr><td>Is not empty</td><td>A specified field has data, meaning it is not blank or null</td><td>An order's tags are not empty</td></tr><tr><td>Is greater than</td><td>A specified field is numerically higher than a given value</td><td>A customer's order count is more than 2</td></tr><tr><td>Is less than</td><td>A specified field is numerically lower than a given value</td><td>A customer's order count is less than 2</td></tr><tr><td>Is less than or equal to</td><td>A specified field is numerically lower than or exactly equal to a given value</td><td>A customer's order count is less than or equal to 2</td></tr><tr><td>Is greater than or equal to</td><td>A specified field is numerically higher than or exactly equal to a given value</td><td>A customer's order count is greater than or equal to 2</td></tr><tr><td>Is in</td><td>A specified field matches any one of the values within a defined list or content</td><td>US is in a customer's country code address</td></tr><tr><td>Is not in</td><td>A specified field does not match any one of the values within a defined list or content</td><td>US is not in a customer's country code address</td></tr><tr><td>Starts with</td><td>A specified field value starts with a specific, or sequential, numbers or characters</td><td>A product's SKU starts with 123</td></tr><tr><td>Does not start with</td><td>A specified field value does not start with a specific, or sequential, numbers or characters</td><td>A product's SKU does not start with 123</td></tr><tr><td>Ends with</td><td>A specified field value ends with a specific, or sequential, numbers or characters</td><td>A product's SKU ends with XYZ</td></tr><tr><td>Does not end with</td><td>A specified field value does not end with a specific, or sequential, numbers or characters</td><td>A product's SKU does not end with XYZ</td></tr><tr><td>Is after [date/time]</td><td>A specified date/time value falls later than a given date or time</td><td>An order was created after 10/24/24 12:00AM</td></tr><tr><td>Is before [date/time]</td><td>A specified date/time value is earlier than a given date or time</td><td>An order was created before 10/24/24 12:00AM</td></tr><tr><td>Is on [date]</td><td>A specified date value matches exactly with a given date</td><td>An order was created on 10/24/24</td></tr></tbody></table>

When using dates or time frames as a condition or rule within the Filter step, you have the ability to use [specific date formats](https://docs.getmesa.com/workflow-builder/fields/liquid-templating#date).

{% hint style="info" %}
Please note that values will be case-sensitive
{% endhint %}

## Going Further <a href="#multiple" id="multiple"></a>

### Multiple rule sets <a href="#multiple" id="multiple"></a>

You can apply additional rules by clicking the **More fields** button, then selecting the Additional Rules checkbox.

<figure><img src="/files/nOHR8uUwsakJv0PlFF5R" alt="Screenshot of the Filter tool in the MESA workflow builder. Spotlight the More fields button and Additional Rules checkbox."><figcaption></figcaption></figure>

Define if all rules need to match (`AND`), or if only one of your rules needs to match (`OR`). You can add an unlimited number of rule sets by clicking the Add Rule button to build complex comparison logic.

<figure><img src="/files/48tomLtTvC8bgmbfaV8d" alt="Screenshot of the Filter tool with multiple rule sets in the MESA workflow builder. Spotlight the AND / OR selector and the Add Rule button."><figcaption></figcaption></figure>

## Technical Notes

### Advanced rule sets <a href="#advanced" id="advanced"></a>

If you use a combination of **AND** or **OR** operators, the logic will read from top to bottom. For example, `a AND b OR c AND d` will be executed as `((a && b) || c) && d`.

#### **AND Filter will only** proceed if *both* conditions are true.

* **Example**: Order created is more than $5 **AND** it is the customer's first order.
* **Action**: If both conditions are met, the task continues. Otherwise, it stops.

**OR Filter will proceed if at least&#x20;*****one*****&#x20;of the listed conditions is true**

* **Example**: Order created is more than $5 **OR** it is the customer's first order.
* **Action**: If one condition is met, the task continues. Otherwise, it stops.

For more fine-grained control, separate your **AND** comparisons and **OR** comparisons into separate Filter steps.

<figure><img src="/files/5y4FI0XWAzd3ZoH1UnZz" alt="Screenshot of a MESA workflow with a separate Filter step for AND comparisons. Spotlight the AND Filter step."><figcaption></figcaption></figure>

<figure><img src="/files/jYk6GNUxcYhBbnUBtHDy" alt="Screenshot of a MESA workflow with a separate Filter step for OR comparisons. Spotlight the OR Filter step."><figcaption></figcaption></figure>

### Special values

The following values will be automatically cast from strings to their respective types:

* `true`
* `false`
* `null`

### Creating a custom comparison

You can further adjust the functionality of a Filter step by opening the step options (three vertical-dot icon) and clicking Edit code.

<figure><img src="/files/JSWJJl2aJb0YPhW1FkGf" alt="Screenshot of the Filter step options menu in the MESA workflow builder, opened from the three vertical-dot icon. Spotlight the Edit code option."><figcaption></figcaption></figure>

<figure><img src="/files/hI6jsaDohumbr63Wl9N2" alt="Screenshot of the Filter step Edit code view in the MESA workflow builder. Spotlight the custom comparison code editor."><figcaption></figcaption></figure>


# Form

The **Form** tool allows you to create any kind of submission form. This makes it possible for customers to answer questions related to their order, sign up for promotions or mailing lists, or contact store departments directly such as Returns & Exchanges.

<figure><img src="/files/RHFKIsE6FMkUdjoHGyRs" alt="Screenshot of the MESA Form tool showing a Returns and Exchanges submission form customers use to answer questions about their order. Spotlight the form fields."><figcaption></figcaption></figure>

## Configure

### Building

Use the Form Builder to create your form from scratch. To gather the information you need, you can include headings, plain text, and various input types like text fields, dropdowns, and checkboxes.

![Screenshot of the MESA Form Builder used to create a form from scratch with headings, plain text, and input types like text fields, dropdowns, and checkboxes. Spotlight the field type options.](/files/91ndCw5GFnvkCHrutcWB)

<figure><img src="/files/cjxoY4BbowV5KgxQe2K0" alt="Screenshot of creating a custom form in MESA automations, Form Builder step 1. Spotlight the form building canvas."><figcaption></figcaption></figure>

### Manual Run

To preview the form, turn your workflow on and select the **Form URL** link-out icon highlighted below.

![Be sure to enable your workflow before opening the Form URL](/files/Jthj43HaxVjLrQweZJYC)

Once the workflow is enabled, complete a form and click submit to see your submission in your workflow's [Activity](https://docs.getmesa.com/workflow-activity) tab.

### Using Form variables

In later steps, use the [variable](https://docs.getmesa.com/workflow-builder/fields/variables) selector to insert a variable from your form's submission fields.

<figure><img src="/files/1ZIXnMgAfx3OfTJLJVyZ" alt="Screenshot of the variable selector in a later workflow step used to insert a variable from the Form submission fields. Spotlight the variable selector."><figcaption></figcaption></figure>

For example, if you want to send these form values to [Google Sheets](/connect/google-sheets), you can select the variables on the right that match the correct column in MESA.

<figure><img src="/files/9JxCTszDLH4SuVEkJPMP" alt="Screenshot of a Google Sheets step in MESA mapping Form field values to matching spreadsheet columns. Spotlight the variable selector on the right."><figcaption></figcaption></figure>

### Using your form

#### Linking to your form

Use the Form URL to link people to your form.

<figure><img src="/files/iMwtqjBQUIzEMazxfYFw" alt="Screenshot of the MESA Form trigger settings showing the Form URL used to link people to your form. Spotlight the Form URL field."><figcaption></figcaption></figure>

#### Javascript embed code

You can use the embed code to embed your form anywhere you need it to appear.

<figure><img src="/files/hdSgW3X0zptLnic8vmaM" alt="Screenshot of the MESA Form trigger settings showing the JavaScript embed code used to embed your form anywhere. Spotlight the Form Embed Code field."><figcaption></figcaption></figure>

### Coding your form

You can code your form from scratch using the Advanced Code snippet provided in the Form Builder if you prefer a direct coding approach.

With the Form Builder open, click the Get Code tab and copy the code from the Advanced section.

### Customizing appearance

By default, MESA adds [Bootstrap](https://getbootstrap.com/) wrappers and classes and uses its default styling. When setting up a form, MESA gives you the option to add class names to the form fields should you wish to attach custom styles.

## Going Further

### **Add to Shopify's order status page**

1\. Open the **Form** trigger and click on the copy icon on the right of the **Form Embed Code** field.

<figure><img src="/files/hdSgW3X0zptLnic8vmaM" alt="Screenshot of the MESA Form trigger settings, open the Form trigger to add the form to Shopify&#x27;s order status page. Spotlight the copy icon on the Form Embed Code field."><figcaption></figcaption></figure>

2\. From your Shopify Admin, click on **Settings** and then locate the **Checkout** settings.

3\. Scroll down until you locate the **Order status page additional scripts** section. Paste the copied Form embed code.

4\. **Save** your changes.

After saving, your form will appear on the order status page after customers place an order.

You can preview the look of the form by going to any order in your store. Click the **More Actions** dropdown and then select the **View order status page** from the drop-down menu.

### **Add a form via the Shopify theme editor**

{% hint style="info" %}
Your theme must be an [Online Store 2.0 theme](https://themes.shopify.com/themes?sort_by=most_recent\&architecture%5B%5D=os2) in order to add a MESA Form through the Shopify theme editor.
{% endhint %}

1\. Open the Form trigger and copy the entire URL to the right of the **Form URL** field.

<figure><img src="/files/iMwtqjBQUIzEMazxfYFw" alt="Screenshot of the MESA Form trigger settings, open the Form trigger to add a form via the Shopify theme editor. Spotlight the copy action on the Form URL field."><figcaption></figcaption></figure>

2\. From your Shopify Admin, click on **Online Store** under **Sales Channels**. Locate your preferred theme and click on **Customize**.

3\. In the theme editor, select a page to which you'd like to add the Form using the dropdown menu at the top.

4\. Once a page is selected, click **Add section** in the left sidebar menu. Then, scroll down to the **App** blocks and select the **MESA Form** block.

5\. Locate the **Form URL** field and paste the copied **Form embed code**. You will be able to see the Form in the theme editor as a preview after pasting the URL.

6\. **Save** your changes.

{% hint style="info" %}
After saving, you can exit the theme editor and view the form on your selected page.
{% endhint %}

### **Add to the customer account order page**

1\. Open the **Form** trigger and click on the copy icon to the right of the **Form Embed Code** field.

<figure><img src="/files/hdSgW3X0zptLnic8vmaM" alt="Screenshot of the MESA Form trigger settings, open the Form trigger to add the form to the customer account order page. Spotlight the copy icon on the Form Embed Code field."><figcaption></figcaption></figure>

2\. From your Shopify Admin, click on **Online Store** under **Sales Channels**. Locate your preferred theme and click on **Actions** and then **Edit code**.

3\. Locate your theme's customer order file. Each theme varies, but a common location is under the **Templates** folder: **customers/order.liquid** file.

4\. Paste your copied **Form Embed Code** anywhere you’d like it to appear on the page.

5\. **Save** your changes. After saving, you can exit out of the theme editor and view the customer account page.

### Hosted Forms <a href="#hosted" id="hosted"></a>

Your form is also available on your Shopify site out of the box. To view your hosted form, click on the export icon under the Form URL.

{% hint style="info" %}
If your workflow is disabled, you will not be able to see your form.
{% endhint %}

<figure><img src="/files/iMwtqjBQUIzEMazxfYFw" alt="Screenshot of the MESA Form trigger settings for viewing your hosted form on your Shopify site. Spotlight the export icon under the Form URL."><figcaption></figcaption></figure>

If the customer is logged in, the payload submitted by the form will also include `customer_id`.

### Styling your form

When setting up a form, MESA gives you the option to add class names to the form fields.

This HTML snippet adds a border around the form and ensures that the input fields and buttons have a border outline.

```html
<style>
 #mesa-form {
     margin-top: 25px;
     padding: 1.1428571429em;
     border: 1px solid #D9D9D9;
     border-radius: 4px;
     margin-bottom: -20px;
 }

 #mesa-form button#submit {
    border-color: #D9D9D9; 
 }
</style>
```

{% hint style="info" %}
Scripts do not apply the same styling universally and may require adjustments based on the location of the Form.
{% endhint %}

### JavaScript API

If you would like to build something more interactive, Form has a powerful JavaScript API:

* `GET {{form_url}}.json`: (optional) retrieve your Form Builder configuration in a format that can be rendered with the [Form Renderer](https://formbuilder.online/docs/formRender/options/) JavaScript library.
* `POST {{form_url}}.json`: Post a JSON object representing your form. Example:\\

```bash
curl 'https://mymesa.site/mesa-example/forms/form_shopify_order_return.json' \
 -H 'Content-Type: application/json' \
 --data-raw 'name=Bob+Biller&email=bob&message='
```

Here is an example of a form that is built with the Form Renderer library and submitted via jQuery. To use it, simply change `{{form_url}}` in the `<form>` tag to be your MESA Form URL.

```html
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

<form id="mesa-form" class="container" style="display: none;" action="{{form_url}}" method="POST" name="mesa-form">
 <div id="form-content"></div>
   <div class="form-group">
     <div class="hcaptcha"></div> <!-- Remove this line to hide the captcha -->
   </div>
   <div id="error"></div>
   <div class="formbuilder-button form-group field-submit">
     <button type="submit" class="btn-primary btn" name="submit" id="submit">Submit</button>
   </div>
 </div>
</form>

<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://cdn.jsdelivr.net/npm/formBuilder@3.4.0/dist/form-render.min.js'></script>

<script src="https://mymesa.site/forms/hcaptcha.js" async defer></script>
<script>
jQuery(document).ready(function($) {
 var $form = $('#mesa-form');
 var mesaFormUrl = $('#mesa-form').prop('action') + '.json';
 
 // Render the form from the fields configured in the MESA Dashboard Form Builder with FormRender:
 // https://formbuilder.online/docs/formRender/options/
 $.getJSON(mesaFormUrl, function(data) {
   jQuery('#form-content', $form).formRender({
     formData: data
   });

   // If this is a Shopify Checkout page, support auto-populating the customer-id field
   if (typeof Shopify !== 'undefined' && typeof Shopify.checkout !== 'undefined') {
     jQuery('#form-content input[name=customer-id]').val(Shopify.checkout.customer_id);
   }
   $form.fadeIn();
 });

 // Bind an AJAX POST call to the #submit button
 $('#submit', $form).bind('click', function(event) {
   // Validate form first, return early if fails
   if (!$form[0].checkValidity()) {
      return;
   }

   event.preventDefault();
   $(this).prop("disabled", true);

   // Post to the MESA Forms JavaScript API url, which is: "{{form_url}}.json"
   // MESA Forms will accept these Content-Types: `application/json`, `application/x-www-form-urlencoded`
   $.ajax({
     type: "POST",
     url: mesaFormUrl,
     data: $form.serializeArray(),
     success: function() {
       $('#mesa-form').html('<div class="alert alert-success" role="alert">Thank you for your submission.</div>');
     },
     error: function(jqXHR) {
       console.log(jqXHR, status, error);
       $('#error').html('<div class="alert alert-danger" role="alert">Sorry, there was an error submitting your form: ' + jqXHR.responseJSON.error.message + '. Please try again.</div>');
       $('#submit', $form).prop("disabled", false);
     }      
   }).done

 });
});
</script>
```

## Technical Notes

### **Pre-populate Field Values** <a href="#pre-populate-field-values" id="pre-populate-field-values"></a>

You can pre-populate the value of any field by setting the **Value** field in the Form Builder field settings.

Default values can also be passed via query string parameters as long as the field's **Value** has curly brackets around the same values as the field's **Name**: `{{}}`

For example:

* **Field's Name**: Email
* **Field's Value**: {{email}}

<figure><img src="/files/4UUIfGeXcJKXnHJ3e4ed" alt="Screenshot of the MESA Form Builder field settings showing a pre-populated Email field whose Value uses curly brackets around the field Name. Spotlight the Value field."><figcaption></figcaption></figure>

Then, linking to the url `{{form_url}}?email=bob@example.com` would pre-populate the Email field with the value `bob@example.com`.

The success message can also be overwritten by passing the `success_message` query string parameter. For example: `{{form_url}}?success_message=Your+return+is+in+process.`

Hosted MESA Forms on Shopify support these same query string parameters.

Here is an example of a field's **Value**: `{{customer.id}}`

### **Success Redirect URL** <a href="#success-redirect-url" id="success-redirect-url"></a>

The **Success Redirect URL** field allows you to add your own redirect that displays a success message after a form is submitted.​

<figure><img src="/files/FAyupzKmJlcO0sZoiDjh" alt="Screenshot of the MESA Form trigger settings showing where to add a redirect after submission. Spotlight the Success Redirect URL field."><figcaption></figcaption></figure>

### Captcha

The **Captcha** field can add a **Captcha Checkbox** to prevent unwanted spam from bots and solicitors.​

<figure><img src="/files/FAyupzKmJlcO0sZoiDjh" alt="Screenshot of the MESA Form trigger settings showing the option to add a Captcha Checkbox to prevent spam. Spotlight the Captcha field."><figcaption></figcaption></figure>

Here's what it looks like when visiting the Form URL.

<figure><img src="/files/ZWYL9umSg7Yjao2VGYUI" alt="Screenshot of the published Form URL page showing the Captcha checkbox a visitor sees before submitting. Spotlight the Captcha checkbox."><figcaption></figcaption></figure>

<br>


# FTP

The **FTP (File Transfer Protocol)** tool allows you to download and upload files to a specified FTP server. With MESA, you can map the data to a format that Shopify or another system expects and pass it along to the next step. Sharing CSV and other files via FTP servers is a great choice to connect your fulfillment service, product manager, or another third-party system to Shopify. MESA supports both FTP and SFTP (secure FTP) protocols.

{% hint style="info" %}
**Please note**: At this time, MESA does not support SSH keys for FTP.
{% endhint %}

## Connection <a href="#connect" id="connect"></a>

Your hosting service should have details for all fields required to [connect your FTP with MESA](/going-further/credentials).

<figure><img src="/files/RmtZGzowQ7TWaZT8MwNj" alt="Screenshot of the MESA FTP connection form, filled with the FTP server host, username, and password credential fields. Spotlight the Add Connection button."><figcaption></figcaption></figure>

Once all the details have been filled in, click **Add Connection** to connect your FTP with MESA.

## Configuration <a href="#configuring" id="configuring"></a>

### Fetch File triggers <a href="#triggers" id="triggers"></a>

You can begin a workflow by fetching a FTP, XML, or CSV file on a scheduled basis.

<figure><img src="/files/XKzERVAeRIUJfH19E5U9" alt="Screenshot of the MESA workflow builder trigger picker for the FTP tool, showing the Fetch FTP, XML, and CSV file triggers that run on a schedule. Spotlight the Fetch File trigger options."><figcaption></figcaption></figure>

Once you have selected your preferred FTP trigger, there are fields available to complete:

* [File Name](#file-name)
* [Move File After Successful Read](#move-file)
* [Scheduled Time](#scheduled-time)

### **File Name**

Enter the path to the file on your FTP server.

<figure><img src="/files/pxKPsPwPBYPaYyYO2USw" alt="Screenshot of the MESA FTP Fetch File trigger configuration with the path to the file on the FTP server entered. Spotlight the File Name field."><figcaption></figcaption></figure>

To check if you have correctly entered your path, you can click on the Retrieve File button to test.

<figure><img src="/files/f15RLUIHYricmMY4Syxz" alt="Screenshot of the MESA FTP Fetch File trigger configuration used to test the entered file path. Spotlight the Retrieve File button."><figcaption></figcaption></figure>

If MESA cannot locate your file, an error will display, stating that the file is not found or could not be read. To fix this, please adjust the text entered into the File Name field.

<figure><img src="/files/JwYyp043x5ew46hD7o2A" alt="Screenshot of the MESA FTP Fetch File trigger after clicking Retrieve File with an invalid path, showing the file not found error. Spotlight the file not found or could not be read error message."><figcaption></figcaption></figure>

Optionally, you can use wildcards (\*) to match portions of the path if the path is dynamic. If you are familiar with regular expressions, you can test the wildcard placement on a third-party website (e.g. [regex101](https://regex101.com/)) to ensure that the pattern matches the file path.

<figure><img src="/files/szSZsp4FWnePrQrrdaq6" alt="Screenshot of the MESA FTP Fetch File trigger with a wildcard character used in the file path to match a dynamic portion of the path. Spotlight the File Name field wildcard."><figcaption></figcaption></figure>

<figure><img src="/files/emomEDMDYsldxFQcYmb3" alt="Screenshot of the regex101 website used to test a wildcard pattern against an FTP file path. Spotlight the regular expression and test string match."><figcaption></figcaption></figure>

### **Move File After Successful Read**

If selected, the file will be moved after MESA successfully reads it. This is useful if you have a dedicated directory/folder to store read files so your FTP server is organized. This can be found by selecting the [More fields](https://docs.getmesa.com/workflow-builder/fields#additional-fields) button.

<figure><img src="/files/ykQLhM6OFbetG5sCH9Ih" alt="Screenshot of the MESA FTP Fetch File trigger with the More fields section expanded to reveal the Move File After Successful Read option. Spotlight the Move File After Successful Read setting."><figcaption></figcaption></figure>

In the below screenshot, the "processed" folder stores all files that have been read.

![Screenshot of the FTP server file directory showing a processed folder that stores all files MESA has read. Spotlight the processed folder.](/files/CeQPOEtDGrQwrerVcsAU)

For the Moved File Name field, you can use the [Variable](/workflow-builder/fields/variables) {{file}} which is from the file name. For example, if the file name value is **orders/Order\*.csv**, and the found file was **orders/Order-1234.csv**, {{file}} would resolve to **Order-1234.csv**.

For our example, we have inputted: processed/orders/{{file}}

<figure><img src="/files/tDV1SPj0g2s7I2D9FZeh" alt="Screenshot of the MESA FTP Fetch File trigger Move File After Successful Read option with processed/orders/{{file}} entered. Spotlight the Moved File Name field."><figcaption></figcaption></figure>

### **Scheduled Time**

Towards the bottom of the configuration, you can configure how often you'd like your workflow to run. Make sure to click the Save button to save your changes.

<figure><img src="/files/Y0qOVt4JBmvmqVQtIBiT" alt="Screenshot of the MESA FTP Fetch File trigger scheduling section at the bottom of the configuration, used to set how often the workflow runs. Spotlight the Scheduled Time and Save button."><figcaption></figcaption></figure>

## Going Further <a href="#save-ftp-action" id="save-ftp-action"></a>

### Save FTP File action <a href="#save-ftp-action" id="save-ftp-action"></a>

* [Advanced Data Mapping](#advanced-data-mapping)

In the File Name field, you can input your preferred name of the file that will be sent to your FTP server.

<figure><img src="/files/qLajBzvHtcHIfXGObYoh" alt="Screenshot of the MESA Save FTP File action configuration with the preferred output file name entered. Spotlight the File Name field."><figcaption></figcaption></figure>

Example: **products/all-products-{{ "now" | date: "\_%m\_%d\_%Y\_%I\_%M\_%S\_%p" }}.csv** will create a file in the products folder, with the name **all-products-\_07\_12\_2024\_09\_48\_54\_AM.csv**

[Learn more about formatting dates with Liquid](/workflow-builder/fields/liquid-templating#date).

In the **Data Mapping** section, you can map out the data sent to your FTP server by utilizing [MESA's Variables feature](/workflow-builder/fields/variables).

<figure><img src="/files/8zXzomSezeGdsHDIPLgq" alt="Screenshot of the MESA Save FTP File action showing the Data Mapping section where the data sent to the FTP server is mapped using Variables. Spotlight the Data Mapping section."><figcaption></figcaption></figure>

**Advanced Data Mapping**

For more advanced mapping, you can also use the **Edit Code** button on the FTP action, then add in your own data mapping.

<figure><img src="/files/27ukRWR4RexR3ae4wCBc" alt="Screenshot of the MESA Save FTP File action with the code editor open for advanced data mapping. Spotlight the Edit Code button."><figcaption></figcaption></figure>

The following code will take a list of Shopify products, and create CSV file content from them. The **Mesa.csv.encode()** method is used to convert the data into CSV format. See the MESA Script SDK [documentation](https://docs.getmesa.com/tools/custom-code/sdk#vendor-mesa.js-mesa.csv.encode) for more details.

```javascript
script = (payload, context) => {
  // Adjust `payload` here to alter data before we transform it.

  // Alter the payload data based on our transform rules
  let csvRows = [];

  payload.forEach((product) => {
    csvRows.push({
      id: product.id,
      title: product.title,
      handle: product.handle,
      status: product.status,
    });
  });

  // Adjust `output` here to alter data after we transform it.
  const csvOutput = Mesa.csv.encode(csvRows, true);

  // We're done, call the next step!
  Mesa.output.next(csvOutput);
};
```

## Technical Notes

#### Fetch CSV File Row Created Trigger

* This trigger can support a CSV file with over 10,000 rows.
* Our queue will batch 50 rows at a time. After those 50 rows are processed, the next 50 will be enqueued. This continues until all rows have been processed.
* We do not recommend parallel processing for this trigger as it can disrupt the enqueuing logic.
* For CSV files with more than 1,000 rows, avoid using short schedule intervals as this may conflict with existing runs. For files over 1,000 rows, set the schedule to approximately 1 hour. For files with 10,000+ rows, keep schedule times several hours apart to prevent double booking
* Unlike other triggers that support enqueueing multiple files, this trigger only enqueues one file at a time.

#### Query Rows Action

* You can query rows based on specific rulesets.

#### Add or Update Rows in CSV Action

* Row ID is used as a primary key for querying and updating. While it should be an ID, it can be any value. If a match is found with the Row ID, the existing row will be updated. If no match is found, a new row will be added. If there are multiple rows that match the same ID all matching rows will be updated.


# Image

The **Image** tool allows you to manipulate and process images. By passing in an image URL, you can add image effects, overlays, identify colors, and remove backgrounds.

{% hint style="info" %}
Image is a Premium app. There is a limit to the number of Premium actions we provide for free. [Learn more](https://docs.getmesa.com/going-further/plans-and-billing#premium-steps)
{% endhint %}

## Add Effects / Transform your image

This action adds image effects to the supplied image. Pass in an image URL and then the action will return a new image URL that can be accessed using the `{{ image }}` [variable](/workflow-builder/fields/variables).

<figure><img src="/files/wtJxTTB2tYsDXt643H0t" alt="Screenshot of MESA Image tool Add Effects / Transform action configuration. Spotlight the Image URL field and the image effect options."><figcaption></figcaption></figure>

## Add an Overlay

This action adds a text overlay or a watermark to the supplied image. You can either pass an image URL for the watermark or configure the text overlay. The Trigger will return a new image URL that can be accessed using the `{{ image }}` [variable](/workflow-builder/fields/variables).

<figure><img src="/files/5TSuQMm4deZx2vGcRvA2" alt="Screenshot of MESA Image tool Add an Overlay action configuration. Spotlight the text overlay and watermark fields."><figcaption></figcaption></figure>

## Identify Colors

This action identifies the most predominant colors used in an image. Simply pass an image URL to the trigger, and it will return a list of the colors in the form of the `{{ colors }}` [variable](/workflow-builder/fields/variables).

<figure><img src="/files/g1NV5Dy4Isi6FvHkEBUU" alt="Screenshot of MESA Image tool Identify Colors action configuration. Spotlight the Image URL field used to return the colors variable."><figcaption></figcaption></figure>

## Technical Notes

The Image tool is a premium app and has a boundary to the number of times it can be executed each billing period.


# Logic

The **Logic** tool lets you contain all of the inner workings of your workflow--filtering, restructuring and looping data--in a single, reliable step. Our AI assistant Yedric can help you build and adjust the logic.

## Configure <a href="#overview" id="overview"></a>

### Building a Logic workflow

Start by opening Yedric and asking him to `Build a workflow`. For example:

{% code overflow="wrap" %}

```
Build a workflow that sends Shopify orders over $100 with an "uploadery_1" line item to Google Sheets
```

{% endcode %}

Yedric will look for similar templates. If you decline the template install, he will ask a few clarifying questions, outline your workflow, and get to work adding your trigger, Logic step and action(s). As part of the workflow building, Yedric will write the logic script and build a diagram outlining your workflow's logic:

<figure><img src="/files/V4zCjGaUhp4DGoCMYxX1" alt="Screenshot of a Logic step built by Yedric in the MESA workflow builder showing the generated logic script and workflow diagram, spotlight the Logic step diagram."><figcaption></figcaption></figure>

Once your workflow is built, Yedric will let you know what needs to be done to complete the workflow setup, then walk you through manually running it to confirm it is working as expected. Describe any changes you need to make to Yedric. If everything looks good, turn on your new workflow.

### Editing a Logic step

The easiest way to edit a logic step is by clicking the Edit with Yedric at the bottom of the Logic step. Yedric will read your workflow and walk you through making the updates.

<figure><img src="/files/PSPffWx1br1RCy8oaoom" alt="Screenshot of a Logic step opened in the MESA workflow builder, spotlight the Edit with Yedric button at the bottom of the step."><figcaption></figcaption></figure>

If you are technical and would like to get under the hood, you can edit the Logic code. Click on `...` > `Edit Code`, and you can edit the JavaScript code powering the Logic step with the [MESA SDK](/tools/custom-code/libraries/sdk).


# Loop

The **Loop** tool allows you to iterate over a list of items one-by-one.

A Loop is useful when you want to take a list of things, for example, all of the line items in an order, and perform an action on each individual item.

## Configure <a href="#overview" id="overview"></a>

### Loop

To iterate over specific items from a list (typically from the [Trigger](https://docs.getmesa.com/workflow-builder/triggers) or [Actions](https://docs.getmesa.com/apps/shopify/actions)), use the [variables](https://docs.getmesa.com/workflow-builder/fields/variables) menu to select the list of items after adding your Loop step.

<figure><img src="/files/zgBfaCcjWfGmsCz81S9O" alt="Screenshot of MESA workflow builder, added Loop step, open the variables menu to select the list of items to iterate over. Spotlight the list variable selection."><figcaption></figcaption></figure>

After your Loop has been added and configured, you'll see your Loop steps within a confined container with a grey border.

To perform one or more tasks on each item in the list, add [actions](https://docs.getmesa.com/apps/shopify/actions) after the Loop within the container with a grey border.

You can reference the individual items or their information by using the Loop variables that will populate for actions added in the Loop container.

You will have variables available from steps that occur prior to the Loop in your workflow, as well as the Loop variables. Typically, you'll want to use Loop variables when configuring actions within the Loop container.

<figure><img src="/files/hkwg4CKuPBEwQvN3rlN3" alt="Screenshot of MESA workflow builder, action added inside the Loop container with the grey border, using Loop variables. Spotlight the Loop container and its variables."><figcaption></figcaption></figure>

{% hint style="info" %}
Be sure to **Save** your workflow after adding and configuring your Loop to see your available Loop variables.
{% endhint %}

In each Loop action, there are conditions you can add to filter the list.

You can populate the [Filter by conditions](https://docs.getmesa.com/tools/filter#examples) via the More fields button so that specific values or results that meet the conditions are passed to the following steps.

<figure><img src="/files/VYvhpIIGAJQaPesYm3tU" alt="Screenshot of MESA workflow builder, Loop action with the More fields button opened to add Filter by conditions. Spotlight the Filter by conditions fields."><figcaption></figcaption></figure>

## Going Further

### Loop End

The default configuration of the Loop tool will continue the workflow without passing variables after the Loop. However, you can optionally configure a Loop End step to build a list from matching items to use in later steps.

In the Loop step, click the More options button to add the Loop End via the Build a list from matching items checkbox.

<figure><img src="/files/DYOjCpoXhpGXYHZSteMv" alt="Screenshot of MESA workflow builder, Loop step with the More options button opened. Spotlight the Build a list from matching items checkbox that adds the Loop End."><figcaption></figcaption></figure>

After saving your workflow, use the [variable](https://docs.getmesa.com/workflow-builder/fields/variables) selector to append data from the Loop container to use in future steps after the Loop.

The value can be a single variable from an action within the Loop, or you can add a [Transform Mapping](https://docs.getmesa.com/tools/transform#transform-mapping) action within the Loop and map a new object.

<figure><img src="/files/qE33U0gsycHK0lruQK37" alt="Screenshot of MESA workflow builder, Loop End step using the variable selector to append data from the Loop container. Spotlight the variable selector."><figcaption></figcaption></figure>

The variable that's created from the Loop End step will be Loop End > Items, and it can be used in steps after the Loop.

<figure><img src="/files/BBczfTnXn9BfHR9slrDZ" alt="Screenshot of MESA workflow builder, step after the Loop using the Loop End > Items variable. Spotlight the Loop End > Items variable."><figcaption></figcaption></figure>

### Other kinds of Loop steps

Beyond the regular Loop action, you can add different variations of Loop actions to your workflow. These are single-output steps with a different behavior than the Loop & Loop End functionality.

#### Sum

The Loop Sum action will calculate the sum of all items that match a specific criteria.

For example, the Loop Sum action can add up the price of line items (products) in an order and pass that value as a variable to reference in the following steps. The value will be an integer.

<figure><img src="/files/mPW5tMJyhzCpfF2HVJu6" alt="Screenshot of MESA workflow builder, Loop Sum action configured to add up the price of line items in an order. Spotlight the Loop Sum action configuration."><figcaption></figcaption></figure>

#### Map

The Loop Map action will create a list of values that are identified based on the item you're referencing from a previous step.

For example, the Loop Map action can pass all line item (product) titles in an order for tagging purposes.

<figure><img src="/files/lHn6vsnRwbv9DHrMLsOu" alt="Screenshot of MESA workflow builder, Loop Map action configured to create a list of line item titles. Spotlight the Loop Map action configuration."><figcaption></figcaption></figure>

#### Number of Matches

The Loop Number of Matches action will return the number of items that match a specific criteria.

For example, the Loop Number of Matches action can provide an integer as a variable that can be referenced in future steps representing the number of line items (products) in an order with a specific SKU.

<figure><img src="/files/oS9xmlcoqkAo11gThbjh" alt="Screenshot of MESA workflow builder, Loop Number of Matches action configured to return the count of items matching a criteria. Spotlight the Loop Number of Matches action configuration."><figcaption></figcaption></figure>

## Technical Notes

* The Loop queue is synchronous.
* There is a legacy version of the Loop step that can be found on stores with previous versions of MESA, or when using templates that have not been updated to the latest Loop and Loop End functionality.
  * Everything gets enqueued all at once with legacy Loop actions, which makes this action more susceptible to timeouts.


# Package Tracking

The **Package Tracking** tool allows you to account for shipping information via tracking numbers in your workflow.

This helps you structure workflows based on up-to-date tracking information.

## Configuration

### Shipment triggers

<figure><img src="/files/FzZW1ZGV9MHk51ChHUns" alt="Screenshot of the Package Tracking shipment triggers in the MESA workflow builder. Spotlight the shipment status trigger options such as In Transit, Out for Delivery, and Delivered."><figcaption></figcaption></figure>

You can run workflows based on certain shipping updates such as: Information Received, In Transit, Out for Delivery, Failed Attempt, Delivered, Exception, Expired, and Pending.

### Track Package action

You can retrieve information relating to a shipment's current status by using the Track Package action.

When Shopify (or another e-commerce platform like Square) receives a new order with a tracking number, the Track Package action can track the shipment and allow you to filter based on different tracking states.

## Technical Notes

If you track a tracking number and attempt to track it again it’s going to throw you an error. Any subsequent update needs to come from the trigger.


# Paths

The **Paths** tool allows your workflow to complete different tasks based on conditions set. It lets you handle different scenarios within an automated process, allowing for more complex and dynamic workflows.

<figure><img src="/files/WuIh6IhiK0gGtYXBNztw" alt="Screenshot of a MESA workflow using the Paths tool to complete different tasks based on conditions. Spotlight the Paths step."><figcaption></figcaption></figure>

<figure><img src="/files/Nc1Jdkr7T6zs1JOUdkFd" alt="Screenshot of a MESA workflow where the Paths tool splits the workflow into separate segments. Spotlight the gray bordered path segments."><figcaption></figcaption></figure>

While Paths allow you to split your workflow into separate segments, [Filter](/tools/filter) will only display a single step with conditional rules to be met before proceeding to the next step.

## Configure

Once added, the Paths tool will create multiple "paths" (also known as path rules). Each path [will process an automation based on the specified conditions](https://docs.getmesa.com/tools/filter) saved in the Rule fields and will be outlined with a gray border.

Create [multiple rule sets](/tools/filter#multiple-1) by clicking More options > Additional Rules.

<figure><img src="/files/MJS5rADbygw2JzsJyvar" alt="Screenshot of a MESA Paths rule configuration with More options open. Spotlight the Additional Rules option."><figcaption></figcaption></figure>

All steps added within a path will be included in the gray border to visually demonstrate where the path begins and ends in a workflow.

Here is a quick demonstration:

{% embed url="<https://www.youtube-nocookie.com/embed/nL17gYSSw8Q?rel=0>" %}

Here is a scenario where it would be helpful to use the **Paths** tool.

1. [**Trigger**:](https://docs.getmesa.com/workflow-builder/triggers) An event starts or triggers your workflow. For example, a customer places an order on your Shopify store.
2. [**Condition or Decision Point**](/tools/filter#examples): At some point in the workflow, a condition is evaluated. This could be something like "Is the order's total value greater than $100?".
3. **Paths**: Based on the outcome of the condition, the workflow splits into different paths:
   * **Path 1 Rule**: If the condition is true (e.g., the order's total value is greater than $100), the workflow follows this path.
   * **Path 2 Rule**: If the condition is false (e.g., the order's total value is $100 or less), the workflow follows a different path.
   * **Multiple Paths that evaluate to true**: If multiple Path conditions are true, the workflow follows each path.
4. **Actions within paths**: Each path can have its own set of actions, such as sending a specific email, sending a Slack message, notifying a team member, etc.

## Going Further

* We recommend re-labeling your paths (Path Rules) so that you can easily identify what each will do when your workflow runs. Click the 3 vertical-dot icon then Settings to update the path rule's name.
* If you need similar functionality in all paths, simply duplicate the path by clicking the 3 vertical-dot icon in the top right of the Path step and make adjustments as needed.
* Drag and drop any actions that exist outside of a path into a path when needed.

## Technical Notes

* If you delete a Paths step, all of the actions that follow it will be deleted as well.


# Relay

Relay lets you trigger another workflow directly from your workflow, so you can break complex automations into smaller, reusable pieces or kick off a separate process based on conditions in your current workflow.

## Configure

Relay has a single action, Trigger Workflow. Add it as a step in your workflow, then select the workflow you want to trigger from the dropdown. This is the workflow that will run when this step executes.

<figure><img src="/files/ELEDL4Xfk61L6GpeQ5Hg" alt="Screenshot of the Relay Trigger Workflow step in the MESA workflow builder. Spotlight the workflow selection dropdown."><figcaption></figcaption></figure>

### Wait for completion

Enable the Wait for completion setting from the More fields menu to pause the original workflow until the triggered workflow finishes and returns its last output.

### Data

Use Data fields to pass information into the triggered workflow. Add a key (like `message` in the example above) and set its value using plain text, variables from previous steps in the current workflow, or a combination of both.

The triggered workflow can then reference this data in its own steps.

## Technical Notes

* Each time Relay runs, its record in the [Activity](https://docs.getmesa.com/workflow-activity) includes a link (e.g. "Triggered: workflow\_name") that takes you directly to the run details for the triggered (child) workflow.


# RSS

## Configure

To configure a RSS trigger or action, you simply need to copy and paste the URL of the RSS feed that you would like to extract the content from into the Feed URL field of the step.

<figure><img src="/files/LD9SOpT8ynfd8pO0SiNF" alt="Screenshot of the MESA RSS trigger or action configuration where you paste the RSS feed URL. Spotlight the Feed URL field."><figcaption></figcaption></figure>

The content of the feed will be available as [variables](https://docs.getmesa.com/workflow-builder/fields/variables) via the variable selector in future steps.

<figure><img src="/files/iaufrEihjnINTaxMukNG" alt="Screenshot of the MESA variable selector in a later step showing the RSS feed content available as variables. Spotlight the variable selector."><figcaption></figcaption></figure>

## Technical Notes

* The RSS trigger is a [polling](https://docs.getmesa.com/workflow-builder/triggers#polling) trigger and will need to be configured according to a schedule that fits within your plan.


# Schedule

The **Schedule** tool allows you to schedule workflows on a specific date and time.

You are offered two options: **Recurring** and **One time**. Recurring means that the workflow will trigger at a frequency (i.e. hourly, daily, etc...). One time means that the workflow will trigger once on the date and time of your choosing.

You can click on the hyperlink **Timezone:** to be redirected to your Shopify store's timezone settings.

With MESA and the Schedule tool together, you can schedule important workflows without worrying if they will run when you need them to.

<figure><img src="/files/ggbf6GTD3cA61o7cKmmZ" alt="Screenshot of the Schedule trigger configuration in the MESA workflow builder. Spotlight the Recurring option and its frequency setting."><figcaption></figcaption></figure>

<figure><img src="/files/ezyfwDcfsJUHLfNra7Yb" alt="Screenshot of the Schedule trigger configuration in the MESA workflow builder with the One time option selected. Spotlight the date and time picker and the Timezone link."><figcaption></figcaption></figure>

In future steps of your workflow, you can [filter by](https://docs.getmesa.com/tools/filter) the Executed at and Scheduled at times relating to the Schedule trigger.

<figure><img src="/files/2za8AvvLoZ1QYDsHj9a5" alt="Screenshot of a Filter step in the MESA workflow builder using the Schedule trigger data. Spotlight the Executed at and Scheduled at variable options."><figcaption></figcaption></figure>


# Scraper

The **Scraper** tool allows you to extract and convert the contents of a web page into markdown format.

Scraper is great for gathering content from web resources to gain insights for your business.

## Configure

To configure the Scraper tool, you simply need to copy and paste the webpage URL that you would like to extract the content from into the URL field of the step.

<figure><img src="/files/CwrG0fUhEf2SECRz3rSZ" alt="Screenshot of the MESA Scraper tool, paste the webpage URL you want to extract content from. Spotlight the URL field."><figcaption></figcaption></figure>

The markdown content of the webpage will be available as a [variable](https://docs.getmesa.com/workflow-builder/fields/variables) via the variable selector in future steps.

<figure><img src="/files/CYFx9qMduQam7kzgTvfe" alt="Screenshot of a MESA workflow step showing the scraped markdown content available through the variable selector. Spotlight the markdown content variable."><figcaption></figcaption></figure>

## Technical Notes

The Scraper tool is currently meant for extracting webpage content only. It does not support scraping for search engines like Google.


# SMS

The **SMS** tool allows you to build a workflow that sends an SMS message in seconds. You can customize the phone number and edit the message by using [Variables](/workflow-builder/fields/variables). All messages will be sent from this phone number +1 510 567 7078.

{% hint style="info" %}
**SMS** is a Premium app. There is a limit to the number of Premium actions we provide for free. [Learn more](https://docs.getmesa.com/going-further/plans-and-billing#premium-steps)
{% endhint %}

<figure><img src="/files/G3D8PPxSR9L77BABD1bR" alt="Screenshot of the MESA SMS tool step configuration for sending an SMS message. Spotlight the phone number and message body fields."><figcaption></figcaption></figure>

## Prohibited messages

All messages must adhere to the [codes of conduct published by mobile network operators](https://www.10dlc.org/en/verizon-tmobile-att-sprint-carrier-code-of-conduct) (AT\&T, T-Mobile, Verizon). If a message sender is observed sending any disallowed content, including sending unsolicited messages, phishing, or filter evasion, we will suspend your MESA account immediately.

All messages must comply with the opt-in requirements outlined in the [CTIA guidelines](https://api.ctia.org/wp-content/uploads/2019/07/190719-CTIA-Messaging-Principles-and-Best-Practices-FINAL.pdf). In short, businesses should send messages to customers only after receiving opt-in permission. Also, message senders should not use opt-in lists that have been rented, sold, or shared.

## Technical Notes

* The SMS tool only supports sending messages to the United States and Canada.
* The message body has a maximum length of 160 characters (after variable replacements have been made). If your message is longer than 160 characters, the task will be marked as Fail and no message will be sent.
* To avoid these obstacles, consider using the Twilio app, which has fees per message sent and requires additional configuration.


# Transform

The **Transform** tool converts the payload sent from the previous step into a form that the next step expects. Of the three different types of Transforms, the Transform Mapping is the most common. If you need fine-tuned logic, you can customize the script for every Transform.

## Transform Mapping

The Transform Mapping is by far the most common type of transform. The **Key** column represents the payload key that the next step will receive. The **Value** column represents the the value that the key will have. The value can be text (like `VIP` or `20.99`), or a [variable](/workflow-builder/fields/variables) that will be replaced by the corresponding value from the payload during execution.

When you click on the [Variables](/workflow-builder/fields/variables) icon \[<>] next to the value, a menu will appear with suggested variables (e.g. [Loop variables](https://github.com/shoppad/mesa-docs-gitbook/blob/master/tools/broken-reference/README.md)) based on the previous and next steps in the workflow. [It supports liquid-style variables](/workflow-builder/fields/liquid-templating) like `{{source.order_name}}`

In the example below, the Transform Mapping maps order data to the columns expected by the Google Sheets Write Sheet step.

<figure><img src="/files/1kSowhCfrc300hpCWcLb" alt="Screenshot of a MESA Transform Mapping mapping order data to the columns expected by the Google Sheets Write Sheet step, showing the Key and Value columns. Spotlight the Key and Value mapping columns."><figcaption></figcaption></figure>

## Transform Editor

The Editor Transform lets you create a JSON, HTML, or text payload. It supports liquid-style variables like `{{source.order_name}}`

<figure><img src="/files/ZwfRMEssI9wnt9q7c5gG" alt="Screenshot of the MESA Transform Editor creating a JSON, HTML, or text payload with liquid-style variables. Spotlight the Editor payload input area."><figcaption></figcaption></figure>

## Transform Script

The Script Transform allows fine-tuned logic in a JavaScript script. Enter a human-readable description of what the script is doing, and then click **Edit Code** to start writing your JavaScript.

Read our technical documentation for more details about writing scripts: [Scripts](https://docs.getmesa.com/for-developers/admin-api#scripts) and [Script Specification](https://docs.getmesa.com/tools/custom-code/script-specification).

<figure><img src="/files/JPoRL7zZTjLsDhNVH7NM" alt="Screenshot of the MESA Transform Script with a human-readable description of what the script does. Spotlight the Edit Code button."><figcaption></figcaption></figure>


# Queue

The **Queue** tool acts like a queue, which allows you to process [Triggers](/workflow-builder/triggers) and workflows into it and then resume based on a time interval at the end of a workflow. Depending on the repeat schedule, the Queue will run again since its previous session.

You can think of the Queue as a fishing net with a timer. The fishing net is left alone to catch fish (in this case, triggers and workflows), and every time the timer goes off, you collect all of the fish in the fishing net since the last time you put it out (in this case, MESA runs all the collected Triggers and workflows). Then, repeat!

<figure><img src="/files/qWavD6Z7pKg4XJBrEoFf" alt="Screenshot of the MESA Queue tool added as a step in a workflow in the builder. Spotlight the Queue step."><figcaption></figcaption></figure>

The Queue has 8 time options.

<figure><img src="/files/Vf1MNViDBbovyhL0AGVM" alt="Screenshot of the MESA Queue tool Configure showing the 8 time interval options. Spotlight the time interval dropdown."><figcaption></figcaption></figure>

In the example below, after an order is created, MESA will map the data values accordingly and collect all the orders into the Queue. Once the Queue runs, MESA will create a Google Sheets spreadsheet with all of the orders from the day.

<figure><img src="/files/Xi9JZIjKIFnHpVtMKhnm" alt="Screenshot of an example MESA workflow where created orders are collected into the Queue and then a Google Sheets spreadsheet is created. Spotlight the Queue step in the workflow."><figcaption></figcaption></figure>


# Weather

The **Weather** tool provides current, historical weather data, and future weather.

{% hint style="info" %}
Weather is a Premium app. There is a limit to the number of Premium actions we provide for free. [Learn more](https://docs.getmesa.com/going-further/plans-and-billing#premium-steps)
{% endhint %}

### Actions <a href="#action" id="action"></a>

The **Weather** tool includes a number of defined actions to quickly get you started with common weather requests like:

<figure><img src="/files/NITmPIYIPOtyO6TDSDGg" alt="Screenshot of the MESA Weather tool action picker showing the defined actions for common weather requests. Spotlight the list of Weather actions."><figcaption></figcaption></figure>

After the **Weather** step in your workflow, you can use [Variables](/workflow-builder/fields/variables) to reference the data retrieved from these steps.

### Technical Notes <a href="#limitations" id="limitations"></a>

Please read the descriptions under each **Weather** action. Certain actions provide information for a X number of day(s).

* **Retrieve Weather Forecast:** Grab weather details of the next 3 days
* **Retrieve History Forecast:** Grab weather details of the past 7 days
* **Retrieve Marine Weather:** Grab marine weather for 1 day


# Web Request

The **Web Request** [trigger](/workflow-builder/triggers) creates a unique URL that you can call to execute a MESA workflow. Unlike the [Webhook](/tools/webhook) trigger, the entire workflow will execute, and the result of the last step in the workflow will be returned as the response. Using the **Web Request** trigger, you can retrieve Shopify Customer Metadata values to use in your single page app, proxy an API call to a third party app, or even display an HTML table of data stored in a [Data](/tools/data) table. If you would like to combine data retrieved from multiple steps in your response, we recommend making the last step of your workflow a Mapping or Editor [Transform](/tools/transform) action.

## Configuration <a href="#configuring" id="configuring"></a>

### Passing Data <a href="#passing-data" id="passing-data"></a>

Querystring parameters appended to your URL will be available as [Variables](/workflow-builder/fields/variables) in your workflow. For example, if you append `&limit=1` to the **Web Request URL**, it will be available as the `{{webrequest.querystring.limit}}` variable. To easily select the variable from the Variable selector modal, make a test request and refresh the builder. The querystring parameters sent in your previous workflow run will appear in the variable selector:

<figure><img src="/files/uJbq0Aa3IM6U8JKU3WKM" alt="Screenshot of the MESA variable selector modal after a Web Request test run showing the querystring parameters from the previous run. Spotlight the webrequest querystring variables."><figcaption></figcaption></figure>

If you make a POST request to the **Web Request** trigger, all data passed will be available in the body variable. For example: `{{webrequest.querystring.id}}`. Similar to querystring parameters, to see these variables in the variable selector model, make a test request and refresh the builder.

All headers passed in the request are also available as variables. For example, you could use the `Authorization` header to authenticate requests in a [Custom Code](/tools/custom-code) step

### Custom Response Headers <a href="#custom-headers" id="custom-headers"></a>

The Response Headers returned by the completed automation can be customized under the **More options** section. Change the `Content-Type` value to `text/xml` and end your workflow with a Transform Editor step to return an XML document. Change the `Content-Type` to `text/html` and end your workflow with a Transform Editor step to return an HTML document that will render in the browser:

<figure><img src="/files/qSfKkAkqyNwLvSFaXCjX" alt="Screenshot of the Web Request trigger More options section for customizing Response Headers. Spotlight the Content-Type header value."><figcaption></figcaption></figure>

You can make the response a redirect by including a `code` of either 301 or 302 and `location` in the response in the last step of your workflow:

<figure><img src="/files/i7MZrDll9xVvzvnTu8VX" alt="Screenshot of the last step of a workflow returning a redirect response with a code of 301 or 302 and a location. Spotlight the code and location response values."><figcaption></figcaption></figure>

You can remove the `.json` in the URL or replace it with `.html` or `.xml` to improve the clarity of your endpoints as well, but simply changing the URL suffix will do nothing if the `Content-Type` header is not changed as well.

<figure><img src="/files/NAHWCE3KhJ1bemW9R0a5" alt="Screenshot of the Web Request trigger URL where the .json suffix can be changed to .html or .xml. Spotlight the Web Request URL suffix."><figcaption></figcaption></figure>

The `Access-Control-Allow-Origin` and `Access-Control-Allow-Headers` headers can be customized to fine-tune your [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) security settings, and additional custom headers can be added with static values or values from variables passed from other steps.

### Technical Notes <a href="#technical-details" id="technical-details"></a>

* Each request executes a workflow and counts as an automation run. You can see a history of all automation runs within the[ Activity](/workflow-activity) tab.
* Requests are rate-limited based on the [Incoming rate limit](/going-further/platform-thresholds-and-limits#limits) of your plan.
* The maximum request time is limited based on the [Task compute](/going-further/platform-thresholds-and-limits#limits) limit of your plan. There is also a limit of 60 seconds per request, even if your plan allows longer requests. Requests that take more time to execute will be timed out, and no response will be returned.
* Certain actions, including Loop and Delay, are not supported by the Web Request tool. If you need to delay a couple of seconds, you might be able to use [Mesa.request.sleep](https://docs.getmesa.com/tools/custom-code/sdk?q=sle#vendor-mesa.js-mesa.request.sleep) in a Custom Code step.
* The URL of your Web Request trigger is static and includes a mandatory `apikey` querystring parameter. If you want a shorter URL, we recommend using a URL shortener service like [bit.ly](http://bit.ly/).


# Webhook

The **Webhook** tool allows you to trigger a MESA workflow from a third-party service. It can similarly be thought of like a notification. It lets a third-party service start a workflow in MESA when something happens in your third-party service.

With Webhook, you can create a chain reaction of events that allows you to focus more on your store than work on repetitive tasks.

<figure><img src="/files/0AK3knQinlLVbAmnaFxB" alt="Screenshot of a MESA workflow using the Webhook tool to trigger the workflow from a third-party service. Spotlight the Webhook trigger step."><figcaption></figcaption></figure>

## Set up a Webhook trigger <a href="#setup" id="setup"></a>

When creating a new workflow, you can select the **Webhook** tool as the trigger.

<figure><img src="/files/Uyce3vffM5o8k8Nr0PrV" alt="Screenshot of creating a new MESA workflow and choosing a trigger. Spotlight the Webhook tool in the trigger list."><figcaption></figcaption></figure>

## Add a Webhook URL to your app that you want to connect with <a href="#webhook-url" id="webhook-url"></a>

Hit the Copy button to copy the link from the Webhook URL field and add it to your app in order for MESA to receive notifications from your third-party application.

<figure><img src="/files/eeluYcwhDyUO2w8hAO1M" alt="Screenshot of the MESA Webhook trigger configuration showing the Webhook URL field. Spotlight the Copy button next to the Webhook URL."><figcaption></figcaption></figure>

## Send data to a webhook <a href="#sending-data" id="sending-data"></a>

After adding the Webhook URL to your app, data coming from your third-party application is sent to MESA's Webhook trigger in the form of a JSON payload.

## Manually run your webhook <a href="#testing" id="testing"></a>

You will want to manually run your Webhook trigger by sending a notification from your third-party application.

To check the payload coming from your third-party application, click on the **Activity** tab of your workflow in the MESA dashboard. Then expand the recent run of your workflow, click the 3 vertical dots on the right side of the **Webhook** text, and then click **Request Details**.

![Screenshot of the MESA workflow Activity tab with a recent Webhook run expanded and the three vertical dots menu open on the Webhook step. Spotlight the Request Details option.](/files/VdehOe9EQ2meGwYFNU99)

On subsequent steps, you can create variables that reference the data that is received in the Webhook trigger. For example, you can use the variable: `{{webhook.team_domain}}`

## Limitations <a href="#limitations" id="limitations"></a>

You are unable to send data back to the request. MESA can only receive data coming from the third-party application.

Variables will not be selectable from the Webhook trigger from the Variables menu on subsequent steps. You will need to manually create the variables following the format: `{{webhook.team_domain}}`

## Examples and use cases <a href="#examples" id="examples"></a>

**Webhook** provides the ability to integrate or provide additional capabilities with third-party applications that are currently not supported in MESA. For example, you can trigger a workflow using a Slack command.

![Screenshot of a MESA workflow triggered by a Webhook from a Slack command. Spotlight the Webhook trigger step.](/files/JTcOmv1OJegrfo2zpLg6)

![Screenshot of the Slack app command settings where the MESA workflow Webhook URL is added. Spotlight the Request URL field for the Slack command.](/files/dqDmqvgnDuwBY2EKLtk7)

After creating an app in Slack and adding a command, you can add the Webhook URL from your MESA workflow to the settings of your Slack command.

When messaging on Slack, you can type in the command and hit Enter to trigger the workflow in MESA.


# Apps


# Airtable

## Connection <a href="#connect" id="connect"></a>

When you are setting up your first workflow with Airtable, you'll need to connect your Airtable account with MESA.

Click on the Connect with Airtable button to begin the process.

<figure><img src="/files/OlqKSaVMpAzR2L3StBne" alt="Screenshot of the Airtable connection setup in MESA when creating your first Airtable workflow, spotlight the Connect with Airtable button."><figcaption></figcaption></figure>

On the prompted modal, click on Add a base and select All current and future bases in all current and future workspaces.

This base access is recommended because it will allow you to easily link any base from any workspace you create in your Airtable to your MESA workflow. If you choose another selection for this access, you may need to create a new connection for workflows going forward.

<figure><img src="/files/VXwfhrQToRpOi5Kn43qf" alt="Screenshot of the Airtable authorization modal, spotlight the Add a base option set to All current and future bases in all current and future workspaces."><figcaption></figcaption></figure>

Click on Grant access once you are done.

<figure><img src="/files/MElDMLweUzvgnitsszH9" alt="Screenshot of the Airtable authorization modal after selecting base access, spotlight the Grant access button."><figcaption></figcaption></figure>

Afterwards, you can re-use the newly created connection and select it for your future workflows.

## Configure <a href="#configuration" id="configuration"></a>

### Retrieve fields from your Airtable Table <a href="#retrieve" id="retrieve"></a>

In certain Airtable actions, we can automatically detect the fields in your Airtable Base and add them to MESA using the Retrieve Fields button.

<figure><img src="/files/00ndHpic3vcNCWK3DVV8" alt="Screenshot of an Airtable action step in the MESA workflow builder that detects the fields in your Airtable Base, spotlight the Retrieve Fields button."><figcaption></figcaption></figure>

{% hint style="info" %}
Your fields will display in the order that they were defined when you set up your Airtable Table. If you are viewing your table's data in an Airtable View, the order of the columns may be different.
{% endhint %}

### Send data with different field types <a href="#types" id="types"></a>

Airtable provides a variety of field types that lets you store data in each record. [Learn more about field types](https://support.airtable.com/hc/en-us/articles/203229705-Guide-to-the-basic-field-types).

<figure><img src="/files/IlqWlwZvKenpQZDCeGHy" alt="Screenshot of an Airtable action step in the MESA workflow builder showing the different Airtable field types available for each record, spotlight the field type inputs."><figcaption></figcaption></figure>

When using [MESA's Variables feature](/workflow-builder/fields/variables), you will want to make sure that the data (that represents each variable) matches Airtable's expected format. When the data does not match Airtable's expectations, your workflow will fail.

## Technical Notes <a href="#triggers" id="triggers"></a>

### I don't see my Airtable workflow activating when I update something in Airtable? <a href="#triggers" id="triggers"></a>

MESA workflows that contain Airtable [triggers](/workflow-builder/triggers) (such as Record Updated and Record Created) will run on a polling system. This means on every hour or whatever the selected frequency is selected, MESA will look for any recent activity in Airtable. As a result, you may not see immediate activity in your MESA workflow until the frequency hits.

<figure><img src="/files/Tw0KAJQX78zBLnqnMEB4" alt="Screenshot of an Airtable trigger step in the MESA workflow builder that runs on a polling system, spotlight the Schedule frequency setting."><figcaption></figcaption></figure>

Once the frequency hits, MESA will process every single task that has accrued within the previous timeframe. To change the default frequency, you can click the More options button from the Configure menu of the Airtable trigger and select the Schedule.

{% hint style="info" %}
Please note that available frequencies will differ depending on your MESA billing plan.
{% endhint %}

### Why did my workflow run so many times when I updated my field type? <a href="#runs" id="runs"></a>

When you update the field type of a column in your linked table from your Airtable base, Airtable will run an update on all records associated with that column based on the change. Unless you decline to be notified, Airtable will prompt you with messaging alluding to this update before converting:

<figure><img src="/files/pbdmw6CmUjjMyGbrL5Rm" alt="Screenshot of the Airtable prompt warning that changing a column field type will update all associated records, spotlight the conversion warning message."><figcaption></figcaption></figure>

Even if the records are not altered, Airtable will consider this an update to all records when this action is performed. As a result, if you are using an Airtable Record Updated trigger in your workflow, this will create an automation run for each of the records and will count towards your usage.

### Potential Use Cases <a href="#potential" id="potential"></a>

Jumpstart your automation journey with one of our pre-made templates that you can install directly to the MESA dashboard.

* [Send orders to Airtable](https://www.getmesa.com/connect/shopify/integrate/airtable/send-orders-to-airtable)
* [Add product options to Airtable](https://www.getmesa.com/connect/infiniteoptions/integrate/airtable/add-infinite-options-line-items-to-airtable)
* [Add Uploadery images and line items to Airtable](https://www.getmesa.com/connect/uploadery/integrate/airtable/add-uploadery-images-and-line-items-to-airtable)


# Algolia

## Connection

When you're setting up your first workflow with Algolia, you will need to create a [Connection](https://docs.getmesa.com/going-further/credentials) in order to connect MESA with Algolia.

<figure><img src="/files/O3k8a5ikzDseCdxD5E69" alt="Screenshot of the MESA Algolia step connection setup, creating a Connection to link MESA with Algolia. Spotlight the connection credential fields."><figcaption></figcaption></figure>

To create your connection, login to your Algolia account and navigate to Settings.

<figure><img src="/files/gOqhemr6vFQuc9fi6Iw5" alt="Screenshot of the Algolia dashboard after logging in. Spotlight the Settings navigation item."><figcaption></figcaption></figure>

Then, select API Keys in the Team and Access section and copy your Application ID. Paste the Application ID in the Application ID field of your MESA Algolia step.

<figure><img src="/files/FZKPI9TOqV7WfR546zor" alt="Screenshot of the Algolia Settings, API Keys page under Team and Access. Spotlight the Application ID value to copy."><figcaption></figcaption></figure>

Next, copy the Write API Key and paste it in the Write API Key step of your MESA Algolia step.

<figure><img src="/files/d7PhNeQe1IGa7HCuXN7D" alt="Screenshot of the Algolia Settings API Keys page. Spotlight the Write API Key value to copy."><figcaption></figcaption></figure>

Once those fields are populated, click the Add connection button in your Algolia step to complete your connection.

<figure><img src="/files/9Uz9AuhEYjSMLuljGBMk" alt="Screenshot of the MESA Algolia step with the Application ID and Write API Key fields populated. Spotlight the Add connection button."><figcaption></figcaption></figure>


# Amazon

## Configure

To configure an Amazon action, you simply need to copy and paste the Amazon URL that you would like to extract the content from into the URL field of the step.

<figure><img src="/files/lm5bcdGUq57gqLchDU9N" alt="Screenshot of the MESA Amazon action, paste the Amazon URL you want to extract content from. Spotlight the URL field."><figcaption></figcaption></figure>

The content of the webpage will be available as [variables](https://docs.getmesa.com/workflow-builder/fields/variables) via the variable selector in future steps.

<figure><img src="/files/KQSPNmljoxyz6SZB2S7P" alt="Screenshot of a MESA workflow step showing the Amazon webpage content available through the variable selector. Spotlight the content variables."><figcaption></figcaption></figure>

## Technical Notes

* We retrieve the webpage data through scraping, which means we make multiple attempts to extract the information. If we’re unable to get the data, we return the following error message: "Data not found. Please try again with a different URL."\
  \
  This error may appear if the data couldn’t be located or if the URL is invalid.


# Amazon S3

## Connection

When you're setting up your first workflow with Amazon S3, there are a number of setup steps that you must follow before you can connect Amazon S3 with MESA.

<figure><img src="/files/3uiIrz7Qjv4WXMDJOV2x" alt="Screenshot of the Amazon S3 step in the MESA workflow builder prompting you to set up a connection. Spotlight the Add Connection button."><figcaption></figcaption></figure>

**Before you can connect MESA with Amazon S3, you must:**

* Have an Amazon S3 account
  * **If you do not have an Amazon S3 account,** create one here: <https://aws.amazon.com/console/>. Then, click on the Create an AWS Account button to get started.
* Create a bucket in your Amazon S3 account [based on MESA's setup instructions in the Setting up Amazon S3 Bucket section](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html)
* Create an IAM user in your Amazon S3 account [based on MESA's setup instructions in the Setting up AWS IAM User section](#iam-user)

#### Setting up Amazon S3 Bucket <a href="#bucket" id="bucket"></a>

A bucket is a container for objects stored in Amazon S3. For more information about buckets, [click here.](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html)

**To set up a bucket for MESA:**

1\. Sign in to the AWS Management Console and open the Amazon S3 console at: <https://console.aws.amazon.com/s3/>

2\. In the search bar, type "Buckets" and click on the Buckets feature.

3\. Click on the Create bucket button next to General purpose buckets.

![Screenshot of the Amazon S3 console Buckets page in the AWS Management Console. Spotlight the Create bucket button next to General purpose buckets.](/files/fkuf0ryTerFBpbGqtlXp)

4\. In the General Configuration section, select a AWS Region for this bucket and enter a Bucket name.

![Screenshot of the Create bucket page in the Amazon S3 console, General Configuration section. Spotlight the AWS Region selector and Bucket name field.](/files/mSCIlKgcUrNOCx5aFHvY)

5\. In the Object Ownership section, select the ACLs enabled option and Bucket owner preferred option.

![Screenshot of the Create bucket page in the Amazon S3 console, Object Ownership section. Spotlight the ACLs enabled option and Bucket owner preferred option.](/files/ikZkkgCSUd8HI2WIkuPn)

6\. In the Block Public Access settings for this bucket section, Block all public access will be enabled by default. You will want to unselect the checkbox next to it and select the checkbox next to the "I acknowledge that the current settings..." agreement.

![Screenshot of the Create bucket page in the Amazon S3 console, Block Public Access settings section. Spotlight the Block all public access checkbox being unselected.](/files/7Yaeil9FKN2UMP4a1UGm)

<figure><img src="/files/vWEVdKXlRZbFNaOpazyF" alt="Screenshot of the Create bucket page in the Amazon S3 console, Block Public Access settings section. Spotlight the I acknowledge that the current settings acknowledgement checkbox."><figcaption></figcaption></figure>

7\. Scroll all the way down and click on Create bucket. You have now created a bucket for MESA.

![Screenshot of the bottom of the Create bucket page in the Amazon S3 console. Spotlight the Create bucket button.](/files/PMjnI7RCFsDWQfoQRd5B)

#### Setting up AWS IAM User <a href="#iam-user" id="iam-user"></a>

An IAM user represents a human user or workload who uses the IAM user to interact with AWS.

**To set up an AWS IAM User for MESA:**

1\. Open the [IAM console](https://console.aws.amazon.com/iam/home?#home).

2\. From the navigation menu, click **Users**.

![Screenshot of the AWS IAM console. Spotlight the Users item in the navigation menu.](/files/G6cgWdPLnSlEdCjUkPiD)

3\. Click on the Create user button next to Users.

![Screenshot of the AWS IAM console Users page. Spotlight the Create user button.](/files/CxtMns4HO4aCctyXZvZz)

4\. Enter a User name for this user. Example: MESA-User. Then, click on Next.

![Screenshot of the AWS IAM Create user flow, Specify user details step. Spotlight the User name field and the Next button.](/files/VDFiYcAr8RzvHf2AtGlq)

5\. In the Permissions options section, select the Attach policies directly option.

<figure><img src="/files/q72zIK3rEtzux3n7aDLZ" alt="Screenshot of the AWS IAM Create user flow, Set permissions step. Spotlight the Attach policies directly option."><figcaption></figcaption></figure>

6\. In the Permissions policies section, search for "S3Full" and click on the checkbox next to AmazonS3FullAccess. Click on the Next button.

![Screenshot of the AWS IAM Create user Permissions policies search results for S3Full. Spotlight the AmazonS3FullAccess policy checkbox and the Next button.](/files/AUnuC00ebJyaLiLLCxvM)

7\. Then, click on the Create user button.

<figure><img src="/files/Nls8rk0pDtZOVoNCyec6" alt="Screenshot of the AWS IAM Create user Review and create step with the AmazonS3FullAccess policy attached. Spotlight the Create user button."><figcaption></figcaption></figure>

You have now created an IAM User in your AWS account! You aren't completely done but you are almost there! Please read the below section: Creating Access Key

**Creating Access Key**

Once you have an Amazon S3 Account, a bucket, and an IAM user suited for MESA, you will need create an Access Key for your AWS IAM user to officially connect MESA with Amazon S3.

![Screenshot of the Amazon S3 connection setup in MESA showing the Key and Secret fields for the access key. Spotlight the Key and Secret fields.](/files/u8PqcCXDo7G0bBCwHWr7)

**Please follow these next steps:**

1\. Open the [IAM console](https://console.aws.amazon.com/iam/home?#home) and from the navigation menu, click Users.

![Screenshot of the AWS IAM console. Spotlight the Users item in the navigation menu.](/files/G6cgWdPLnSlEdCjUkPiD)

2\. Select your the user suited for MESA from the User table.

![Screenshot of the AWS IAM Users table. Spotlight the MESA user row to select it.](/files/rMjQSDJlZzKAlmmJuzjr)

3\. In the Summary section, click on Create access key.

![Screenshot of the AWS IAM user detail page, Summary section. Spotlight the Create access key option.](/files/d4J0E5ui5vKXyBeMa3jf)

4\. In the Use case section, select the Third-party service option.

5\. At the very bottom, select the checkbox next to "I understand the above recommendation..." confirmation and click Next.

![Screenshot of the AWS IAM Create access key flow, Use case step with Third-party service selected. Spotlight the I understand the above recommendation confirmation checkbox and the Next button.](/files/i1tgMwZbaNcnT5qAGNYG)

6\. On the next screen, click on the Create access key button.

![Screenshot of the AWS IAM Create access key flow final step. Spotlight the Create access key button.](/files/WvV63ZX0pWklPjTgwiZm)

7\. You will now see your Access Key and Secret access key. This is the only time that the Secret access key can be viewed or downloaded. Click on the copy icon under Access key.

![Screenshot of the AWS IAM Retrieve access keys screen showing the Access key and Secret access key. Spotlight the copy icon under Access key.](/files/hAxSr5MSLeOpob4vUgr6)

8\. In a new tab or back in your MESA workflow with the Amazon S3 action, paste the copied values into the Key field.

9\. Do the same for Secret access key from Amazon S3 and paste it into the Secret field.

10\. Click on the Add Connection button and then you are all set! MESA is now connected with your Amazon S3 account.

### Configure <a href="#configuring" id="configuring"></a>

**Required Fields:**

<figure><img src="/files/GwLXQyqwG0lx8gkpMihz" alt="Screenshot of the Amazon S3 action configuration in the MESA workflow builder. Spotlight the Region, Bucket, and File URL required fields."><figcaption></figcaption></figure>

* **Region** and **Bucket**: You will want to select the appropriate values that you just created above in this help guide.
* **File URL**: You can input the URL of a file or use [MESA's variable feature that represents a file URL from an earlier step](/workflow-builder/fields/variables). Also, the file should be publicly available and MESA should be able to directly access the file without downloading it.

**Optional:**

* **File Name:** If used, it is highly recommended that the file URL ends with the actual file extension. For example, if the file is a pdf, the file name should end with **.pdf**


# Asana

### Connection <a href="#connect" id="connect"></a>

When you're setting up your first workflow with Asana, you'll need to create a connection through MESA's Asana app or use your own custom Asana app. Click on the **Connect with Asana** button.

<figure><img src="/files/8tmtRKMNUTbOSTqWImJz" alt="Screenshot of the MESA Asana connection setup for your first Asana workflow. Spotlight the Connect with Asana button."><figcaption></figcaption></figure>

You will see a screen asking you to grant MESA permission to connect with your Asana account. Once you have reviewed the permissions, click on **Allow**.

<figure><img src="/files/87mk8w0sml5RbY9aIdqo" alt="Screenshot of the Asana permission screen asking you to grant MESA permission to connect with your Asana account. Spotlight the Allow button."><figcaption></figcaption></figure>

Afterwards, you will be brought back to your current workflow and you are all set! MESA is now connected with your Asana account.

***

### Configuration <a href="#configuring" id="configuring"></a>

#### Select your Workplace, Project, or Task <a href="#select" id="select"></a>

All Asana [triggers](/workflow-builder/triggers) require you to select a workspace that MESA should work with. If your Asana [trigger or action](/workflow-builder/triggers) contains multiple fields to select, you must click on the **Workplace** drop-down menu first.

<figure><img src="/files/sdlw2DKx0zuuIX5nn2jG" alt="Screenshot of an Asana trigger configuration in MESA where you select the workspace MESA should work with. Spotlight the Workplace drop-down menu."><figcaption></figcaption></figure>

You can also specify the **Project Gid** below the Workplace drop-down menu. Clicking on Project Gid first without selecting a workplace will display an error.

<figure><img src="/files/7U2eEfGFtEuGejlq2ECu" alt="Screenshot of an Asana trigger configuration in MESA showing the Project Gid field below the Workplace drop-down menu. Spotlight the Project Gid field."><figcaption></figcaption></figure>

#### Start off with an Asana Task Added trigger in your MESA workflow <a href="#triggers" id="triggers"></a>

{% hint style="info" %}
When your enabled workflow starts with an Asana Task Added trigger, you will see many Skipped tasks in the workflow's Activity tab. Don't be scared! That is to be expected. 😊
{% endhint %}

You will see many **Skipped** tasks since Asana sends MESA any update that occurs in any of your Asana tasks.

To prevent multiple MESA tasks associated to the same update from triggering the workflow, MESA will automatically mark duplicated MESA tasks as **Skipped**. Please note that **Skipped** tasks will not impact your billing.

<figure><img src="/files/MJZhGQugwy5hAW7AkoOC" alt="Screenshot of a MESA workflow Activity tab showing many Skipped tasks from an Asana Task Added trigger. Spotlight the Skipped task statuses."><figcaption></figcaption></figure>

When viewing the workflow's [Activity tab](/workflow-activity), we recommend sorting your MESA tasks by clicking on the **Status** drop-down menu to view your tasks' statuses more efficiently.

<figure><img src="/files/ULkJnf3NsgX0zx9lLrIO" alt="Screenshot of a MESA workflow Activity tab, sort your tasks by status. Spotlight the Status drop-down menu."><figcaption></figcaption></figure>

#### Update an Asana task after your workflow starts off with an Asana Task Added trigger <a href="#infinite" id="infinite"></a>

{% hint style="danger" %}
Please read the following if your workflow looks like the below screenshot. The below screenshot will cause unintended problems.
{% endhint %}

<figure><img src="/files/swsytpMe8BNGxAuHs7Vb" alt="Screenshot of a problematic MESA workflow that starts with an Asana Task Added trigger and updates the Asana task with no other steps, causing an infinite loop. Spotlight the workflow steps."><figcaption></figcaption></figure>

The **Asana Task Added** trigger not only activates when any Asana task is added but also when an Asana task is updated. Therefore, updating the Asana Task without any other steps in the workflow will cause an infinite loop between these two steps. An infinite loop will cause your workflow to run in a circle and create many MESA tasks.

To prevent this, we recommend adding a [Filter](/tools/filter) step below your workflow's trigger. The Filter should check for whatever you plan to update the task with. If the Filter step locates the item that is used to update the task, then the Filter step will stop the automation.

Your workflow should look like this now:

<figure><img src="/files/iGQNs3YjAp18onZ8Ouqj" alt="Screenshot of the corrected MESA workflow with a Filter step added below the Asana Task Added trigger to prevent an infinite loop. Spotlight the Filter step."><figcaption></figcaption></figure>


# Avis Product Options

## Connection <a href="#configuring" id="configuring"></a>

Your Shopify store’s connection will automatically be selected when adding the Avis Product Options trigger.

Ensure the Avis Product Options app is installed on your Shopify store before using any steps that rely on it.

<figure><img src="/files/2BozX3pVB39yb9cAVEOY" alt="Screenshot of MESA Avis Product Options trigger with the Shopify store connection automatically selected. Spotlight the selected connection."><figcaption></figcaption></figure>

## Configure

### Avis Product Options Order Created Trigger <a href="#create" id="create"></a>

The Avis Product Options trigger will run when an order is received that includes line item properties (option selections).

You can choose to only trigger this workflow when an order contains specific product options by clicking the More fields button in the Setup menu of the trigger.

Checking the Filter by Line Item Property Names checkbox will allow you to enter the Label on Cart of each option you want to filter by, found in your Avis Product Option Set configuration. You can add multiple Label on Cart values to filter from.

<figure><img src="/files/BxPOzQ1TvvIPeZ9kAbU7" alt="Screenshot of MESA Avis Product Options Order Created trigger Setup menu. Spotlight the More fields button."><figcaption></figcaption></figure>

<figure><img src="/files/9oRHsEVeQyzrh8Uygfia" alt="Screenshot of MESA Avis Product Options trigger with More fields expanded. Spotlight the Filter by Line Item Property Names checkbox and the Label on Cart values."><figcaption></figcaption></figure>

If the Avis Product Options "Line Item Property Name" field in your trigger is left empty, all orders that include any Avis product options will trigger the workflow.

## Technical Notes <a href="#potential" id="potential"></a>

* If you change options in Avis Product Options, your workflow must also be updated.
  * For example, any [variables](/workflow-builder/fields/variables) used in your workflow related to Avis Product Options' fields will need to be updated and saved.
* The [manual run](https://docs.getmesa.com/workflow-builder/testing#test-data) interface will display only orders with matching Avis Product Options "Line Item Property Name" values.
* To use [variables](/workflow-builder/fields/variables) associated with the Avis Product Options trigger, you will need to conduct at least one [manual run](https://docs.getmesa.com/workflow-builder/testing#test-data) on the workflow.
* If you need to export old orders with option selections, you can use our [Time Travel](https://docs.getmesa.com/workflow-activity/time-travel) feature in the Activity of the workflow.


# Blog Studio

### Connect Blog Studio with MESA <a href="#connect" id="connect"></a>

When you're setting up a workflow with a Blog Studio [trigger](/workflow-builder/triggers), MESA will automatically connect to the Shopify store that you have installed MESA on and no further action is necessary. 😊

But, when you're setting up a workflow with a Blog Studio [action](/workflow-builder/triggers) such as **Blog Studio Create Article**, you will need to add a [Custom App](https://help.shopify.com/en/manual/apps/custom-apps#create-and-install-a-custom-app) on the external Shopify store that does not have MESA installed on. Then, enter the app's connections into the Blog Studio Connections section.

* **External Site Hostname:** The beginning part of your Shopify store's URL.
* **Access Token**: To find your access token, [you can follow these steps](https://help.shopify.com/en/manual/apps/custom-apps#install-the-app-and-get-the-api-access-tokens).

<figure><img src="/files/1ddsuQqcgCxgg98vPVQN" alt="Screenshot of the MESA Blog Studio Connections section for a Blog Studio Create Article action, entering the External Site Hostname and Access Token from the external store&#x27;s custom app. Spotlight the External Site Hostname and Access Token fields."><figcaption></figcaption></figure>

Afterwards, you can re-use the newly created connection and select it for your future workflows!

### Configuration <a href="#configuring" id="configuring"></a>

#### Select a blog to send the article to <a href="#blog" id="blog"></a>

For MESA's **Blog Studio Create Article** and **Blog Studio Update Article** actions, you will need to specify a Blog, in the Step Configuration's **Blog** field. Your online store has a default blog called **News** but you can select any other Blog. [Click here to learn more about what a Blog is.](https://help.shopify.com/en/manual/online-store/blogs)

<figure><img src="/files/1tHtSqLhbX1no4NdStlR" alt="Screenshot of the MESA Blog Studio Create Article step configuration, specifying the blog to send the article to. Spotlight the Blog field in the Step Configuration."><figcaption></figcaption></figure>

#### I don't see my Blog Studio workflow activating when I update something in Blog Studio? <a href="#triggers" id="triggers"></a>

MESA workflows that contain Blog Studio [triggers](/workflow-builder/triggers) (such as **Article Created** and **Article Updated**) will run on a polling system. Meaning, on every hour or whatever the selected frequency is selected in your MESA workflow, MESA will look for any recent activity in Blog Studio. As a result, you may not see immediate activity in your MESA workflow until the frequency hits.

In Blog Studio triggers, you can find the polling system by selecting **Customize**, then **Schedule**. You can keep the default frequency or adjust it.

<figure><img src="/files/8yZpAYvfxpduZcIK44I5" alt="Screenshot of a MESA Blog Studio trigger, opening the polling settings. Spotlight the Customize button."><figcaption></figcaption></figure>

<figure><img src="/files/vLZLTq5j6vXs2zJdNz1e" alt="Screenshot of a MESA Blog Studio trigger Customize options, opening the polling schedule. Spotlight the Schedule option."><figcaption></figcaption></figure>

<figure><img src="/files/egUOK0zXDcP2xeRPHmw0" alt="Screenshot of a MESA Blog Studio trigger Schedule settings where you keep the default frequency or adjust it. Spotlight the polling frequency selector."><figcaption></figcaption></figure>

Once the frequency hits, MESA will process every single task that has accrued within the previous time frame.

{% hint style="info" %}
Please note that available frequencies will differ depending on your MESA billing plan.
{% endhint %}


# ChannelApe

## Connection

Connections provide secure access to the integrated app that you use in a MESA workflow. Your ChannelApe connection securely links your workflows with your ChannelApe account.

When you're setting up your first workflow with ChannelApe, you'll need to create a connection by contacting ChannelApe's support team via *<support@channelape.com>* to obtain your private API key.

<figure><img src="/files/hFkaBrSrG8Lvy8XNtHP8" alt="Screenshot of the MESA workflow builder ChannelApe step connection setup, pasting your private API key into the API Key field. Spotlight the API Key field."><figcaption></figcaption></figure>

Once you obtain your private API key, you can paste the API key into your workflow connection's API Key field.


# ChatGPT

{% hint style="info" %}
When using ChatGPT, please note that you will incur additional costs from OpenAI which depends on how often MESA interacts with ChatGPT in a single automation run.
{% endhint %}

Each model has its own different capabilities and price points. You can review [OpenAI’s pricing here](https://openai.com/pricing). If you do not wish to incur additional OpenAI costs, you can use AI tool as an alternative. Please note that AI tool is a [premium app which is double the fun and double the automation](/going-further/plans-and-billing#premium-steps). For more information about AI, [click here](/tools/ai).

## Connection <a href="#connect" id="connect"></a>

When you're setting up your first workflow with ChatGPT, you'll need to create an OpenAI **API Key**.

To create an API Key, go to this url: <https://platform.openai.com/account/api-keys>. Once there, click on the **Create new secret key** button.

![Screenshot of the OpenAI API keys page. Spotlight the Create new secret key button.](/files/tRoZmqzeDuZ7sP69fSMo)

Then, click on the copy button in the **API key generated** modal. Paste the copied values into MESA's ChatGPT Account Connections **API Key** field.

Lastly, click on **Add Connection** and then you are all set! MESA is now connected with ChatGPT.

<figure><img src="/files/64qryAhQ6orLO4duNYis" alt="Screenshot of the ChatGPT connection panel in the MESA workflow builder. Spotlight the API Key field and the Add Connection button."><figcaption></figcaption></figure>

***

### Configuration <a href="#configuring" id="configuring"></a>

#### Following OpenAI's Usage Policies <a href="#policy" id="policy"></a>

Please ensure that you follow OpenAI's Usage Policies when using MESA's ChatGPT integration: <https://openai.com/policies/usage-policies>

#### ShopPad's Recommendation <a href="#recommendation" id="recommendation"></a>

We recommend using OpenAI's [playground](https://platform.openai.com/playground) when testing with MESA's **Create Chat Completion** actions. This allows you to try different models and prompts and will estimate the token cost for each automation.

![Screenshot of the OpenAI playground for testing Create Chat Completion prompts. Spotlight the model and prompt controls.](/files/H6lDHEbGiCcFc19c3PpT)

As ChatGPT is not our product, we would like to note that we are not responsible for its output. We recommend visiting the ChatGPT website and attempt to replicate your preferred prompt using the CHATGPT UI to verify that it meets your expectation before trying to automate it with MESA.

### How ChatGPT Uses Your Data <a href="#data-security" id="data-security"></a>

The ChatGPT app makes API calls to OpenAI. Only the variables explicitly configured in the MESA builder will be shared with OpenAI. MESA does not store any of this information beyond your data retention date. OpenAI does not use data submitted to and generated by their API to train OpenAI models or improve OpenAI's service offering.

To opt out of any data sharing with AI models, simply do not use the ChatGPT step in any of your workflows.

[Learn more](https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance) about how and when OpenAI uses use to train their models. Read [MESA's Data Processing Agreement](https://www.getmesa.com/dpa).


# Claude

## Connection

Connections provide secure access to the integrated app that you use in a MESA workflow. Your Claude connection securely links your workflows with your Anthropic account.

When you're setting up your first workflow with Claude, you'll need to create an Anthropic API Key.

<figure><img src="/files/Y0IzXPazXeXEYCashrhW" alt="Screenshot of the MESA Claude step connection setup, linking your workflow with your Anthropic account. Spotlight the API Key credential field."><figcaption></figcaption></figure>

To find your Anthropic API Key, go to: <https://console.anthropic.com/settings/keys>. Click the Create Key button and name your key (e.g. MESA).

<figure><img src="/files/wyknPkTwlg6sStTB2qcg" alt="Screenshot of the Anthropic Console API Keys settings page where you name the key MESA. Spotlight the Create Key button."><figcaption></figcaption></figure>

Click the Copy Key from the pop-up that appears. Once you obtain your API key, you can paste the API key into your workflow connection's API Key field.

<figure><img src="/files/dHww0dq8XrC5OyF0zTUJ" alt="Screenshot of the Anthropic Console API key created pop-up. Spotlight the Copy Key button."><figcaption></figcaption></figure>

## Configure <a href="#configuring" id="configuring"></a>

#### Following Anthropic's Usage Policies <a href="#policy" id="policy"></a>

Please ensure that you follow Anthropic's Usage Policies when using MESA's Claude integration: <https://www.anthropic.com/legal/aup>

#### ShopPad's Recommendation <a href="#recommendation" id="recommendation"></a>

We recommend testing the prompt in the Anthropic dashboard before using MESA's Create Message action. This allows you to try different models and prompts and will estimate the token cost for each automation.

As Claude is not our product, we would like to note that we are not responsible for its output. We recommend replicating your preferred prompt using the Claude UI to verify that it meets your expectations before automating it with MESA.

## How Claude Uses Your Data <a href="#data-security" id="data-security"></a>

The Claude app makes API calls to Anthropic. Only the variables explicitly configured in the MESA builder will be shared with Anthropic. MESA does not store any of this information beyond your data retention date. Anthropic does not use data submitted to and generated by their API to train Anthropic models or improve Anthropic's service offering.

To opt out of any data sharing with AI models, simply do not use the Claude step in any of your workflows.

[Learn more](https://support.anthropic.com/en/articles/7996885-how-do-you-use-personal-data-in-model-training) about how and when Anthropic uses use to train their models. Read [MESA's Data Processing Agreement](https://www.getmesa.com/dpa).


# ClickUp

## Connection

When you're setting up your first workflow with ClickUp, you will need to create a [connection](https://docs.getmesa.com/going-further/credential) in order to connect MESA with ClickUp.

<figure><img src="/files/fMHvScFKZUD6GTT4DF6h" alt="Screenshot of the ClickUp step in the MESA workflow builder. Spotlight the Sign in with ClickUp button."><figcaption></figcaption></figure>

Click Sign in with ClickUp to login to your account and connect your Workspace with MESA.

Once that's done, your connection is complete.

## Technical Notes

### ClickUp Free Plan: Custom Field Limits

#### What's the limitation?

ClickUp's Free Forever plan limits how many times custom fields can be set across tasks in a space.

#### Why does this affect workflows?

Automated workflows can hit this limit faster than manual use.

#### Common problems

* Workflow fails
* Error mentions "Custom field usages exceeded"

#### How to fix it

* Remove unused custom fields in ClickUp
* Reduce how often workflows set custom fields
* Upgrade your ClickUp plan

#### Example

A workflow that updates 3 custom fields on every new task will hit the limit faster than expected.

### Task Update Trigger

Adding an attachment to a task won't run the Task Update trigger, but uploading an attachment to a task comment will.


# Dall-E 2

## Connection <a href="#connect" id="connect"></a>

When you're setting up your first workflow with Dall-E 2, you'll need to create an OpenAI API Key.

<figure><img src="/files/u2DAz70qJhd3LCgovAbR" alt="Screenshot of the Dall-E 2 step in the MESA workflow builder. Spotlight the API Key connection field."><figcaption></figcaption></figure>

To create an API Key, go to this url: <https://platform.openai.com/account/api-keys>. Once there, click on the Create new secret key button.

<figure><img src="/files/KYxHtcUniaOXw3Ajark7" alt="Screenshot of the OpenAI API keys page. Spotlight the Create new secret key button."><figcaption></figcaption></figure>

Then, click on the copy button in the API key generated modal. Paste the copied values into MESA's Dall-E 2 Account Connections API Key field.

<figure><img src="/files/dtERgixoroza0Cc1JxET" alt="Screenshot of the OpenAI generated API key modal. Spotlight the copy button."><figcaption></figcaption></figure>

Lastly, click on Add connection and then you are all set! MESA is now connected with Dall-E 2.

## Configure <a href="#configuring" id="configuring"></a>

#### Generated image expires after 1 hour <a href="#expiration" id="expiration"></a>

When using MESA's Dall-E 2 Generate Image action, you will need to keep in mind that all generated images will expire after one hour. Therefore, it is highly recommended to create workflows that use the generated image immediately after an automation runs. You should not store these images in a third party service because they will no longer work.

#### Best Usage <a href="#usage" id="usage"></a>

For the Prompt field, you will want to write a very detailed prompt. The more detailed the prompt is, the more likely you are going to get the result that you want.

<figure><img src="/files/etq8UbG3PGrhEakSvty7" alt="Screenshot of the Dall-E 2 Generate Image action in the MESA workflow builder. Spotlight the Prompt field."><figcaption></figcaption></figure>

#### Following OpenAI's Usage Policies <a href="#policy" id="policy"></a>

Please ensure that you follow OpenAI's Usage Policies when using MESA's Dall-E 2 integration: <https://openai.com/policies/usage-policies>

#### ShopPad's Recommendation <a href="#recommendation" id="recommendation"></a>

We recommend using OpenAI's [Dall-E website](https://labs.openai.com/) first when conducting a manual run with MESA's Generate Image action. This lets you test the prompt that you enter into the action.

## Technical Notes <a href="#data-security" id="data-security"></a>

### How Dall-E 2 Uses Your Data <a href="#data-security" id="data-security"></a>

The Dall-E 2 app makes API calls to OpenAI. Only the variables explicitly configured in the MESA builder will be shared with OpenAI. MESA does not store any of this information beyond your data retention date. OpenAI does not use data submitted to and generated by their API to train OpenAI models or improve OpenAI's service offering.

To opt out of any data sharing with AI models, simply do not use the Dall-E 2 step in any of your workflows.

[Learn more](https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance) about how and when OpenAI uses use to train their models. Read [MESA's Data Processing Agreement](https://www.getmesa.com/dpa).


# Delighted

## Connection <a href="#connect" id="connect"></a>

When you're setting up your first workflow with Delighted, you'll need to add your API key so that Delighted is a connected app within MESA.

<figure><img src="/files/3oYzwPvBPCXDWW2G4HMH" alt="Screenshot of the MESA Delighted connection setup where you add your Delighted API key to make Delighted a connected app. Spotlight the API key field."><figcaption></figcaption></figure>

You can locate your [API key](https://help.delighted.com/article/571-the-delighted-rest-api#docs) by clicking Integrations on the Delighted Dashboard. Then, locate API and click on it.

<figure><img src="/files/Arpf5gnUGg36RiMHHD54" alt="Screenshot of the Delighted Dashboard where you locate your API key. Spotlight the Integrations menu."><figcaption></figcaption></figure>

<figure><img src="/files/xJWGHchCoMgVWNuG2IbA" alt="Screenshot of the Delighted Dashboard Integrations page after clicking Integrations. Spotlight the API option."><figcaption></figcaption></figure>

You will find the API key under Your API key header. Copy and paste that into your workflow and create a [Delighted Connection](/going-further/credentials).

<figure><img src="/files/ia3NPuF5Q3Y2cYfsb98k" alt="Screenshot of the Delighted API page showing the key to copy for the MESA connection. Spotlight the value under the Your API key header."><figcaption></figcaption></figure>

## Configure <a href="#configuring" id="configuring"></a>

### Delighted Triggers <a href="#triggers" id="triggers"></a>

When starting a workflow with a Delighted Trigger, [MESA will require you to create a Webhook before the workflow works successfully.](https://help.delighted.com/article/556-delighted-webhooks)

<figure><img src="/files/ghRxKFTpaqTigZaEFvUc" alt="Screenshot of a MESA workflow started with a Delighted trigger, which requires creating a Webhook before it runs. Spotlight the Webhook URL field."><figcaption></figcaption></figure>

1\. To create a Webhook, you can click Integrations on the Delighted Dashboard. Then, locate Webhooks and click on it.

<figure><img src="/files/Arpf5gnUGg36RiMHHD54" alt="Screenshot of the Delighted Dashboard where you begin creating a Webhook. Spotlight the Integrations menu."><figcaption></figcaption></figure>

<figure><img src="/files/HvOFIs2fx1bOVlN4cUjS" alt="Screenshot of the Delighted Dashboard Integrations page while creating a Webhook. Spotlight the Webhooks option."><figcaption></figcaption></figure>

2\. From your MESA workflow, copy the Webhook URL seen in the field (save the workflow if you do not see an URL in the field and refresh the page). Paste the URL into the textbox on the screen.

<figure><img src="/files/wbDQkMWKaEvfD25lvo9N" alt="Screenshot of the Delighted Webhooks setup where you paste the Webhook URL copied from the MESA workflow. Spotlight the webhook URL textbox."><figcaption></figcaption></figure>

3\. \*\*Optional Settings:\*\*For response notifications: Set the specifications of the webhook rule (like “promoters only”)For unsubscribe notifications: Select Send unsubscribe notifications. Click Save & turn on.

### Delighted Get & List Actions <a href="#get-list" id="get-list"></a>

Delighted has several actions that can retrieve or list out items like surveys, people, and etc.

In order to retrieve a specific list of things, you will need to use our Parameters option. If you want to list out all things, you can leave the parameter option unselected.

Parameters are what helps MESA request for specific information.

<figure><img src="/files/fTiB9iLgex4EwJl3Hzmh" alt="Screenshot of a MESA Delighted Get or List action where the Parameters option is used to request specific information. Spotlight the Parameters option."><figcaption></figcaption></figure>

<figure><img src="/files/s0pDO2DDuInDnN8TzH9J" alt="Screenshot of a MESA Delighted Get or List action with the Parameters option enabled to enter a parameter. Spotlight the Parameters field."><figcaption></figcaption></figure>

<figure><img src="/files/YDmLeer9sj012wUsBYSH" alt="Screenshot of a MESA Delighted Get or List action with a completed parameter value entered to filter the request. Spotlight the entered parameter value."><figcaption></figcaption></figure>

To use multiple parameters, you will want to add a "&" symbol between multiple parameters. You can also use [variables](/workflow-builder/fields/variables) in the parameters.

If you are not sure what parameter to add, you can check the [Delighted API documentation](https://app.delighted.com/docs/api).


# Digital Humani

### Connection <a href="#connect" id="connect"></a>

When you're setting up your first workflow with Digital Humani, you'll need to add your API Key so that Digital Humani is a connected app within MESA.

<figure><img src="/files/b3GOlPlJpm5vQe4b3hkl" alt="Screenshot of the MESA workflow builder Digital Humani connection setup, adding the API Key. Spotlight the API Key field."><figcaption></figcaption></figure>

From your Digital Humani account, click on Developer from the left hand navigation. Copy the value next to API Key.

<figure><img src="/files/cIKiPP2aRSVHM9h9CLFC" alt="Screenshot of the Digital Humani account Developer page, click Developer in the left navigation and copy the value next to API Key. Spotlight the API Key value."><figcaption></figcaption></figure>

Once everything is entered in the API Key field back in the workflow, click on Add Connection to connect MESA with Digital Humani.

<figure><img src="/files/azMh8zk8I09RHutmPpIA" alt="Screenshot of the MESA workflow builder Digital Humani connection with the API Key entered, click Add Connection. Spotlight the Add Connection button."><figcaption></figcaption></figure>

### Configure <a href="#configuring" id="configuring"></a>

#### Locate Enterprise ID <a href="#enterprise-id" id="enterprise-id"></a>

Some of MESA's Digital Humani [actions](/workflow-builder/triggers), such as the Plant Trees [action](/workflow-builder/triggers), include a field for Enterprise ID. This field is required and ensures that your tree planting request is attributed to your Digital Humani account.

Once you have added a valid Digital Humani connection, click Configure and you should see your Enterprise ID displayed.

<figure><img src="/files/vNlKa6dYM0fm8Wi8lUNk" alt="Screenshot of the MESA Digital Humani Plant Trees action Configure showing the Enterprise ID displayed after adding a valid connection. Spotlight the Enterprise ID field."><figcaption></figcaption></figure>

#### Choose a reforestation project <a href="#reforestation-project" id="reforestation-project"></a>

With MESA's Digital Humani Plant Trees Action, there is a required field called Project ID, which allows you to specify which project you wish your tree planting request to go to.

<figure><img src="/files/5A3QGu9057py2N4y0HB5" alt="Screenshot of the MESA Digital Humani Plant Trees action Configure showing the required Project ID field for selecting a reforestation project. Spotlight the Project ID field."><figcaption></figcaption></figure>

Once you have added a valid Digital Humani Connection, you can click into this field to view, search, and select a list of available reforestation projects. For more details on each project, [click here](https://docs.digitalhumani.com/#appendixlist-of-projects).

#### How tree planting requests work <a href="#tree-planting" id="tree-planting"></a>

When you send a tree planting request, it is forwarded by Digital Humani to the associated reforestation organization. The reforestation organization will send you an invoice directly to pay for the trees planted. More details can be found [here](https://docs.digitalhumani.com/#documentationbilling).


# Discord

## Connection <a href="#connect" id="connect"></a>

When you're setting up your first workflow with Discord, you'll need to connect your Discord account with MESA.

Click on the **Connect with Discord** button to begin the process.

![Screenshot of the Discord step in the MESA workflow builder starting the connection process. Spotlight the Connect with Discord button.](/files/9zwzDt6RMamN343ZoXEN)

You will then see this screen that allows you to select the server you are connecting to. Select the **Server** and click **Continue.**

<figure><img src="/files/50gsK2x4E0WSdXylpeuO" alt="Screenshot of the Discord authorization screen for selecting the server to connect. Spotlight the Server dropdown and the Continue button."><figcaption></figcaption></figure>

You will then see this permission screen. Click **Authorize.**

<figure><img src="/files/LMDMrsT9NubycAWpdNGi" alt="Screenshot of the Discord permission screen granting MESA access to the server. Spotlight the Authorize button."><figcaption></figcaption></figure>

Afterward, you can re-use the newly created connection in your future workflows!

## Error: "You need to verify your account in order to perform this action"

<figure><img src="/files/Z3ziG8BdDcUxAF59ohzH" alt="Screenshot of the Discord connection error in MESA reading You need to verify your account in order to perform this action. Spotlight the error message." width="563"><figcaption></figcaption></figure>

If you see this error after clicking "**Connect with Discord**" in MESA, you will need to verify your account. Another reason could be that you need a private server before authenticating with the MESA app.

[Click this link](https://support.discord.com/hc/en-us/articles/6181726888215-Verification-Required-FAQ#docs-internal-guid-9cd047ed-7fff-8e25-e1e6-0cf5644e2255) for step-by-step instructions on how to verify your account in Discord.


# DocuSign

### Connection <a href="#connect" id="connect"></a>

Connections provide secure access to the integrated app that you use in a MESA workflow. Your DocuSign connection securely links your workflows with your DocuSign account.

When setting up your first workflow with DocuSign, you will need to connect DocuSign with MESA. Click on the **Connect with DocuSign** button.

![Screenshot of the MESA DocuSign connection setup. Spotlight the Connect with DocuSign button.](/files/Py4a1pZPFSP5LaYln6YY)

You may be asked to login into your DocuSign account if not already logged in. Afterwards, you will be brought back to your current workflow and you are all set! MESA is now connected with your DocuSign account.

<figure><img src="/files/OGs2PI4oItZy5frw3fo8" alt="Screenshot of the MESA workflow after being redirected back from DocuSign login, with MESA now connected to the DocuSign account. Spotlight the established DocuSign connection."><figcaption></figcaption></figure>

***

### Implementation <a href="#configuring" id="configuring"></a>

#### Selecting Account <a href="#account-id" id="account-id"></a>

You are required to select your DocuSign **Account ID** if your workflow contains a DocuSign [Trigger or Action](/workflow-builder/triggers).

![Screenshot of a MESA DocuSign step configuration requiring account selection. Spotlight the Account ID field.](/files/MvyNPeyrPDb88fnR8Bl6)

You can verify your **Account** by locating the profile image in the upper-right corner of the DocuSign dashboard.


# Dropbox

## Connection <a href="#connect" id="connect"></a>

When you're setting up your first workflow with Dropbox, you'll need to create a connection through MESA's Dropbox app or through your own custom Dropbox app.

Click on Sign in with Dropbox to complete the process.

<figure><img src="/files/pgey0ZbHI0dum7PUji3C" alt="Screenshot of the MESA Dropbox connection setup. Spotlight the Sign in with Dropbox button."><figcaption></figcaption></figure>

When prompted, be sure to click Continue and Allow to complete the connection.

<figure><img src="/files/eRZhzNP9btT3lEvSYSMU" alt="Screenshot of the Dropbox authorization prompt during connection. Spotlight the Continue button."><figcaption></figcaption></figure>

<figure><img src="/files/8gVvsueRHdqrs5XEZdAI" alt="Screenshot of the Dropbox authorization prompt granting MESA access. Spotlight the Allow button."><figcaption></figcaption></figure>

## Configure <a href="#configuring" id="configuring"></a>

#### Step Configuration fields

* [File url](#file-url)
* [File path](#file-path)

**File url**

This field is designated for the uploaded file's url.

**How to fill out this field**

1\. If you have installed MESA's existing template called [Send Uploadery file to Dropbox](https://www.getmesa.com/connect/uploadery/integrate/dropbox/send-uploadery-file-to-dropbox), the template will have this field pre-filled with: **{{loop.value}}**.

2\. Another common use case would be sending uploaded files to Dropbox every time a Shopify order is created. [Click here to set up this existing MESA template.](https://www.getmesa.com/apps/shopify/integrate/dropbox/send-files-from-a-shopify-order-to-dropbox)

3\. If your workflow set-up is different than the above two scenarios, feel free to reach out to our Customer Success team for further assistance on how to find the correct **File url** variable.

**File path**

You can specify which folder that you'd like to send the files to.

<figure><img src="/files/6stQ4iOmCikC8FCGG6Ti" alt="Screenshot of the MESA Dropbox step configuration for choosing which folder to send files to. Spotlight the File path field."><figcaption></figcaption></figure>

## Technical Notes

* Creating a Shared Link requires higher plans for privacy/password: <https://www.dropbox.com/plans>
* Create File Request's deadline feature requires a paid Dropbox account.


# Easify Product Options

## Connection <a href="#configuring" id="configuring"></a>

Your Shopify store’s connection will automatically be selected when adding the Easify Product Options trigger.

Ensure the Easify Product Options app is installed on your Shopify store before using any steps that rely on it.

<figure><img src="/files/dMHXdwhzewX8OT11KtXD" alt="Screenshot of the MESA Easify Product Options trigger with your Shopify store connection automatically selected. Spotlight the auto-selected Shopify store connection."><figcaption></figcaption></figure>

## Configure

### Easify Product Options Order Created Trigger <a href="#create" id="create"></a>

The Easify Product Options trigger will run when an order is received that includes line item properties (option selections).

You can choose to only trigger this workflow when an order contains specific product options by clicking the More fields button in the Setup menu of the trigger.

Checking the Filter by Line Item Property Names checkbox will allow you to enter the Option name of each option you want to filter by, found in your Easify Product Option Set configuration. You can add multiple Option names to filter from.

<figure><img src="/files/s4IGgMc5lQBLaIGI6T4J" alt="Screenshot of the MESA Easify Product Options Order Created trigger Setup menu, opening the More fields to filter by specific product options. Spotlight the More fields button."><figcaption></figcaption></figure>

<figure><img src="/files/t8gM5ZorjcvQ7t1HrTa2" alt="Screenshot of the MESA Easify Product Options trigger More fields, checking Filter by Line Item Property Names to enter Option names to filter by. Spotlight the Filter by Line Item Property Names checkbox."><figcaption></figcaption></figure>

If the Easify Product Options "Line Item Property Name" field in your trigger is left empty, all orders that include any Easify product options will trigger the workflow.

## Technical Notes <a href="#potential" id="potential"></a>

* If you change options in Easify Product Options, your workflow must also be updated.
  * For example, any [variables](/workflow-builder/fields/variables) used in your workflow related to Easify Product Options' fields will need to be updated and saved.
* The [manual run](https://docs.getmesa.com/workflow-builder/testing#test-data) interface will display only orders with matching Easify Product Options "Line Item Property Name" values.
* To use [variables](/workflow-builder/fields/variables) associated with the Easify Product Options trigger, you will need to conduct at least one [manual run](https://docs.getmesa.com/workflow-builder/testing#test-data) on the workflow.
* If you need to export old orders with option selections, you can use our [Time Travel](https://docs.getmesa.com/workflow-activity/time-travel) feature in the Activity of the workflow.


# Etsy

## Connection <a href="#connect" id="connect"></a>

When you're setting up your first workflow with Etsy, you'll need to create a connection through MESA. Click on **Connect with Etsy V3** to start the process.

<figure><img src="/files/h3SDBPqhTMylSFyct1Q5" alt="Screenshot of a MESA workflow Etsy step connection panel. Spotlight the Connect with Etsy V3 button."><figcaption></figcaption></figure>

Once you are logged into your Etsy account, you can re-use the newly created connection and select it for your future workflows!

### Configuration <a href="#configuring" id="configuring"></a>

#### I don't see my Etsy workflow activating when I update something in Etsy? <a href="#triggers" id="triggers"></a>

MESA workflows that contain Etsy [triggers](/workflow-builder/triggers) (such as Receipt Created or Listing Created) will run on a polling system. Meaning, on every hour or whatever the selected frequency is selected in your MESA workflow, MESA will look for any recent activity in Etsy. As a result, you may not see immediate activity in your MESA workflow until the frequency hits.

In Etsy triggers, you can find the polling system under **Configure**. You can keep the default frequency or adjust it.

<figure><img src="/files/k3ftDRNVS5D5aJsKc2gT" alt="Screenshot of a MESA Etsy trigger Configure section. Spotlight the polling frequency selector."><figcaption></figcaption></figure>

Once the frequency hits, MESA will process every single task that has accrued within the previous timeframe.

{% hint style="info" %}
Please note that available frequencies will differ depending on your MESA billing plan.
{% endhint %}

## Technical Notes

You can no longer send Shipping updates (or access address information) without using Preferred Partners.

You can find more info on this [here.](https://help.etsy.com/hc/en-us/articles/26654295371031-How-to-Use-a-Third-Party-Provider-to-Ship-Your-Order?segment=selling)


# Facebook

## Connection <a href="#connect" id="connect"></a>

When you're setting up your first workflow with Facebook, you'll need to connect Facebook with MESA. Click on the **Sign in with Facebook** button.

You will be asked to login into your Facebook Business account if you have not already logged in.

<figure><img src="/files/hb9RboyFGK8ECNYh0oo6" alt="Screenshot of the Facebook connection step in a MESA workflow prompting to log in to a Facebook Business account. Spotlight the Sign in with Facebook button."><figcaption></figcaption></figure>

Afterwards, you will be brought back to your current workflow and you are all set! MESA is now connected with your Facebook account.

{% hint style="warning" %}
A Facebook connection will expire after 60 days if not used in an enabled Facebook workflow. If you have an enabled Facebook workflow, your Facebook connection will remain active. If your connection has expired, please connect Facebook with MESA again by re-creating a new connection.
{% endhint %}

## Configure <a href="#configuring" id="configuring"></a>

Most Facebook actions will require you to select an **Ad Account** or **Business Account**. These fields are type-ahead selects that will automatically select from the Facebook accounts tied to your connection.

Simply click into these fields and an account should appear. If no accounts appear, ensure that you have created an Ad Account in your Facebook Business Portal and that you have [followed all of the steps outlined above](#connect) to properly set up a connection.

<figure><img src="/files/EAriwmbrb0dl1GBZMRxs" alt="Screenshot of a Facebook action Configure menu in MESA. Spotlight the Ad Account or Business Account type-ahead select field."><figcaption></figcaption></figure>

### Insights <a href="#insights" id="insights"></a>

The Facebook Insights API is a powerful way to build custom reports on Facebook. You can specify fields to return, group by (the Level configuration option), sort by, and custom date ranges to query over.

You can even apply a customized filter to limit the data that is returned. Use the helpful tooltips next to fields for more details about each option and consult the Facebook documentation for a [full list of available fields](https://developers.facebook.com/docs/marketing-api/insights/breakdowns), or [example queries that can be run](https://developers.facebook.com/docs/marketing-api/insights).

### Additional Documentation <a href="#additional-documentation" id="additional-documentation"></a>

Many Facebook actions require specific combinations of parameters to be successfully created and updated. Consult the [Facebook Marketing API documentation](https://developers.facebook.com/docs/marketing-api/reference) for full details.

## Technical Notes

* Changes to your Custom Audiences don't happen immediately and usually take up to 24 hours.
* To increase the match rate for your records, provide multiple fields. For example, \[`Last Name`, `First Name`, `Email`].
* Actions for adding and removing users from custom audiences match the provided identifiers (like email or phone) against Facebook’s database. Matches are processed server-side, and inclusion is not guaranteed.


# Fera.ai

### Connect Fera.ai with MESA <a href="#connect" id="connect"></a>

When you're setting up your first workflow with Fera.ai, you will need to connect Fera.ai with MESA. Click **Add Account**, then select **Connect with Fera**.

<figure><img src="/files/Cyz6ZW6XjMS7w6zdyHAQ" alt="Screenshot of MESA Fera.ai step connection setup. Spotlight the Add Account button."><figcaption></figcaption></figure>

<figure><img src="/files/5daQYlKovKvdFClxgwf7" alt="Screenshot of MESA Fera.ai connection setup after clicking Add Account. Spotlight the Connect with Fera button."><figcaption></figcaption></figure>

You may be asked to login into your Fera.ai account if not already logged in. **Please make sure** to [login into your Fera.ai account](https://app.fera.ai/login) before clicking on **Connect with Fera**. Once logged in, you can continue with the connecting process.

Afterwards, you will be brought back to your current workflow and you are all set! MESA is now connected with your Fera.ai account.


# Gatsby

[Gatsby](https://apps.shopify.com/gatsby?utm_source=mesa\&utm_medium=docs) is a Shopify app that allows you to gather Instagram handles and insights on your customers and their media.

### Connection <a href="#connect" id="connect"></a>

From your Gatsby Dashboard, click on the [Integrations](https://gatsby.run/safe/integrations?utm_source=mesa\&medium=docs) page, and then click on the **Generate Webhook** button on the **Webhooks** card. If you have already created a Webhook, you can select **View Webhook**:

<figure><img src="/files/xi4oFxI9YiqZR4JeJVQC" alt="Screenshot of the Gatsby Dashboard Integrations page, click Generate Webhook on the Webhooks card. Spotlight the Generate Webhook button."><figcaption></figcaption></figure>

Scroll to the bottom of the page, and copy the Webhook URL (clipboard icon). You do not need to fill in any values for the Mapping fields.

<figure><img src="/files/o18GgN4At4lyY1P61SJP" alt="Screenshot of the Gatsby webhook page, scroll to the bottom and copy the Webhook URL using the clipboard icon. Spotlight the Webhook URL clipboard copy icon."><figcaption></figcaption></figure>

Open the MESA Dashboard and paste the URL into the **Webhook URL** field of your Gatsby step:

<figure><img src="/files/rcZAK49Jpm3XJl3IrIVZ" alt="Screenshot of the MESA Dashboard Gatsby step, pasting the copied URL into the Webhook URL field. Spotlight the Webhook URL field."><figcaption></figcaption></figure>

### Configuration <a href="#configuring" id="configuring"></a>

The **Email** and **Instagram Handle** fields are required. If you are not collecting email addresses, you can enter a static dummy email address (for `example dummy@example.com`).


# Gemini

## Connection <a href="#connect" id="connect"></a>

When you're setting up your first workflow with Gemini, you'll need to create an API Key.

<figure><img src="/files/haF1DMRnjhRgIUvTwlK1" alt="Screenshot of the Gemini connection panel in the MESA workflow builder. Spotlight the Gemini API Key field."><figcaption></figcaption></figure>

To create an API Key, go to this URL: <https://aistudio.google.com/apikey>. Once there, click on the Create API key button or select an existing key.

<figure><img src="/files/Otx1YvSXeCYXv1WjES3Z" alt="Screenshot of the Google AI Studio API keys page. Spotlight the Create API key button."><figcaption></figcaption></figure>

Click the Create API key in new project button and copy the generated API key.

<figure><img src="/files/SccqjinGIHHbQ2q7htZf" alt="Screenshot of the Google AI Studio Create API key dialog. Spotlight the Create API key in new project button."><figcaption></figcaption></figure>

Paste the copied value into MESA's Gemini API Key field.

Lastly, click the Add connection button and you're all set! MESA is now connected with Gemini.

<figure><img src="/files/2Ok4SaQQnrd8qGCsmyyZ" alt="Screenshot of the Gemini connection panel in the MESA workflow builder with the API key pasted. Spotlight the Add connection button."><figcaption></figcaption></figure>

## Configure <a href="#configuring" id="configuring"></a>

#### Following Gemini's Usage Policies <a href="#policy" id="policy"></a>

Please ensure that you follow Gemini's Usage Policies when using MESA's Gemini integration: <https://gemini.google/policy-guidelines/>

#### ShopPad's Recommendation <a href="#recommendation" id="recommendation"></a>

We recommend using Gemini's [playground](https://aistudio.google.com/u/2/prompts/new_chat) when testing with MESA's Create Chat Completion action. This allows you to try different models and prompts and will estimate the token cost for each automation.

<figure><img src="/files/RJ58rrv4TrpbHLxHB7LP" alt="Screenshot of the Google AI Studio Gemini playground for testing prompts and models. Spotlight the model and prompt controls."><figcaption></figcaption></figure>

As Gemini is not our product, we would like to note that we are not responsible for its output. We recommend visiting the Gemini website and attempting to replicate your preferred prompt using the Gemini UI to verify that it meets your expectations before trying to automate it with MESA.

### How Gemini Uses Your Data <a href="#data-security" id="data-security"></a>

The Gemini app makes API calls to Gemini. Only the variables explicitly configured in the MESA builder will be shared with Gemini. MESA does not store any of this information beyond your data retention date.

To opt out of any data sharing with AI models, simply do not use the Gemini step in any of your workflows.

[Learn more](https://support.google.com/gemini/answer/13594961?hl=en#what_data) about how and when Gemini uses data to train their models. Read [MESA's Data Processing Agreement](https://www.getmesa.com/dpa).

## Technical Notes

* Each model has its different capabilities and price points. You can review [Gemini's pricing here](https://ai.google.dev/gemini-api/docs/pricing). If you do not wish to incur additional Gemini costs, you can use the [AI tool](https://docs.getmesa.com/tools/ai) as an alternative. Please note that the AI tool is a [premium app which is double the fun and double the automation](/going-further/plans-and-billing#premium-steps).
* When using Gemini, please note that you will incur additional costs from Gemini, which depends on how often MESA interacts with Gemini in a single automation run.


# Globo Product Options

## Connection <a href="#configuring" id="configuring"></a>

Your Shopify store’s connection will automatically be selected when adding the Globo Product Options trigger.

Ensure the Globo Product Options app is installed on your Shopify store before using any steps that rely on it.

<figure><img src="/files/BlTVl2jlc8OWjMjnPZvb" alt="Screenshot of the Globo Product Options trigger connection in the MESA workflow builder. Spotlight the auto-selected Shopify store connection."><figcaption></figcaption></figure>

## Configure

### Globo Product Options Order Created Trigger <a href="#create" id="create"></a>

The Globo Product Options trigger will run when an order is received that includes line item properties (option selections).

You can choose to only trigger this workflow when an order contains specific product options by clicking the More fields button in the Setup menu of the trigger.

Checking the Filter by Line Item Property Names checkbox will allow you to enter the Option name of each option you want to filter by, found in your Globo Product Option Set configuration. You can add multiple Option names to filter from.

<figure><img src="/files/arFmTuWyduMJC5OoblQR" alt="Screenshot of the Globo Product Options Order Created trigger Setup menu in the MESA workflow builder. Spotlight the More fields button."><figcaption></figcaption></figure>

<figure><img src="/files/NbpkulmFSedqWBOSXdYA" alt="Screenshot of the Globo Product Options trigger with More fields expanded in the MESA workflow builder. Spotlight the Filter by Line Item Property Names checkbox and the Option name field."><figcaption></figcaption></figure>

If the Globo Product Options "Line Item Property Name" field in your trigger is left empty, all orders that include any Globo product options will trigger the workflow.

## Technical Notes <a href="#potential" id="potential"></a>

* If you change options in Globo Product Options, your workflow must also be updated.
  * For example, any [variables](/workflow-builder/fields/variables) used in your workflow related to Globo Product Options' fields will need to be updated and saved.
* The [manual run](https://docs.getmesa.com/workflow-builder/testing#test-data) interface will display only orders with matching Globo Product Options "Line Item Property Name" values.
* To use [variables](/workflow-builder/fields/variables) associated with the Globo Product Options trigger, you will need to conduct at least one [manual run](https://docs.getmesa.com/workflow-builder/testing#test-data) on the workflow.
* If you need to export old orders with option selections, you can use our [Time Travel](https://docs.getmesa.com/workflow-activity/time-travel) feature in the Activity of the workflow.


# Gmail

## Connection

Connections provide secure access to the integrated app that you use in a MESA workflow. Your Gmail connection securely links your workflows with your Google account.

When you're setting up your first workflow with Gmail, you'll need to create a connection through MESA's Google App or your own custom Google App. Click on the Sign in with Google button to finish the process.

<figure><img src="/files/QI5uONWdSuBPwJr6tZRi" alt="Screenshot of the MESA Gmail step connection setup using MESA&#x27;s Google App. Spotlight the Sign in with Google button."><figcaption></figcaption></figure>

You will need to check all boxes that are available when prompted during authentication for the integration to work properly.

<figure><img src="/files/YlubjOpYC9JYZd1DolNg" alt="Screenshot of the Google account authentication permissions prompt during Gmail integration setup. Spotlight the checkboxes to select all available permissions."><figcaption></figcaption></figure>

## Important Details

There are different limits and maximum limitations depending on your account type.

* **Free Gmail account:** If you use a free Gmail account, you are limited to sending a maximum of 500 emails in a 24-hour period, and a maximum of 100 addresses per email.
* **Paid Google Workspace account:** If you use a paid Google Workspace account, you are limited to sending a maximum of 2,000 emails in a 24-hour period.
* **Free trial period:** Anyone using the free trial period for a Google Workspace account is subject to 500-email maximums until you convert their account to the full paid version and complete a 60-day waiting period.

{% hint style="danger" %}
**Note:** If you exceed any of the above limits, **your account can be suspended for up to 24 hours.**
{% endhint %}




---

[Next Page](/llms-full.txt/1)

