Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Shopify is evolving its platform to enhance performance and provide more powerful features. As part of this evolution, Shopify has announced the deprecation of the Shopify Admin REST API. In response, we are updating our services to align with this change, transitioning fully to the GraphQL Admin API.
Deprecation of REST Admin API: Starting October 1, 2024, the REST Admin API is considered a legacy API. Shopify will begin phasing it out, with critical endpoints like product and variant endpoints ceasing to function on February 1, 2025. While product and variant endpoints are the first to be deprecated, Shopify plans to deprecate all REST endpoints in the future.
GraphQL Admin API: All new developments and updates will utilize the GraphQL Admin API exclusively. This shift is aimed at leveraging the enhanced capabilities and efficiencies that GraphQL offers.
Shopify wants to maintain one API and have decided to discontinue the REST Admin API in favor of the GraphQL Admin API. GraphQL addresses several limitations of REST, offering significant benefits such as:
Efficient Data Retrieval: Fetch precisely the data you need in a single request.
Enhanced Flexibility: Customize queries to suit your specific needs.
Library Tasks Update: All our library tasks will be updated to use GraphQL only. You will get a notification via email and in app if there is an update available for a task you have installed. Tasks that can be auto-updated will be updated for you. These updated tasks will serve as examples to help you migrate your custom tasks.
Action Required: To ensure uninterrupted service, please begin updating your custom tasks to GraphQL as soon as possible.
Product and Variant REST liquid objects will cease functioning
REST lookups in email task options will no longer work
Any tasks using REST API for product/variant operations will stop working
We recommend migrating all tasks to GraphQL now, not just those affected by the February deadline, as all REST endpoints will eventually be deprecated.
Update Tasks from the Library: You will get a notification via email and in app if there is an update available for a task you have installed. Tasks that can be auto-updated will be updated for you.
Hey there! :) I'm Isaac, the creator of Mechanic.
As of this writing (currently March 30, 2025), AI is not very good at Mechanic. We're seeing a pretty steady stream of folks having issues with AI-generated tasks — issues arising because the AI does not know how Mechanic works. AI code frequently "invents" Mechanic features that do not exist, or fails to invoke necessary Mechanic features.
A time may absolutely come when this gets better. :)
=Isaac
Great! Mechanic is made for this. Here's where to start. :)
Mechanic's automation tasks are written in Liquid, which is a template language used heavily in and around Shopify. This means that developers of all levels, with even a little Shopify development experience, can get started with Mechanic.
Lastly: if you already have a developer on your team, or have an existing connection to a developer, send them this article and see if they can help you!
Custom Tasks Migration: If you have custom tasks relying on the REST API, they will need to be migrated to use the GraphQL API before the deprecation deadlines. See our guide .
for Product and Variants will now pass resource IDs instead of full REST objects - tasks will need to look up objects using these IDs
Review Our Migration Guides: We have prepared comprehensive guides to assist you in migrating your custom tasks to GraphQL. Access them .
Learn More About GraphQL: Familiarize yourself with GraphQL by visiting Shopify's official .
Hire a Partner: Browse our for expert help
Community Support: Join our to ask questions about migrating your tasks
tldr: Mechanic generally requires more precision than affords.
For now, if you're having issues with an AI-written task, your absolute best bet is to talk with a professional from the Mechanic partners list at . Your task may need to be retooled, and possibly fully rewritten from scratch, by someone who can dynamically account for the practical realities of Mechanic and Shopify. As of right now, this seems to generally mean a human.
We-the-platform-team are available for issues with the platform itself, but we can't get hands-on with custom code. For a general overview of custom code on Mechanic, see .
To learn about how we at Lightward Inc roll with AI, please visit , and say hello. :)
Mechanic is a development platform – in the hands of a developer, it can be used to accomplish almost anything in Shopify. While our covers many use cases, Mechanic's true strength is in letting developers solve merchant problems quickly, giving merchants easy configuration forms for managing the resulting tasks.
Need something that you think others might need too? The Mechanic community accepts , and the top-voted requests are regularly selected for implementation.
To find a developer for hire, you can contact Mechanic Partners directly at . This is a growing list of established developers, both independent and agency, who can help you with your implementation.
If you're familiar with Liquid, and Shopify's Admin APIs, start by picking something from our that's close to what you're looking for, then modify it as needed.
Make sure to take advantage of the documentation found here, beginning with the section. Mechanic is a powerful system, and grounding yourself in the fundamentals is a good way to begin.
Finally, join Mechanic's Slack workspace at to exchange support with the community. The #general channel is a great place to start, and it's filled with people who are using Mechanic to solve problems every day. :)
Community Support: We encourage you to join our Slack community, where you can seek advice and share experiences with other Mechanic developers. Often, community members can offer insights or solutions based on their experiences.
Partner Directory: We recommend hiring a developer if the issue requires more in-depth technical expertise. Our partner directory lists qualified developers familiar with Mechanic task development.
Our support team assists with platform issues and issues with tasks from . For custom tasks not included in our task library, our support service is limited to Mechanic platform support.
Joining the Community: You can join our Slack community through the following link: .
Finding a Developer: Visit our partner directory at to find a developer who can customize or optimize your task. If you want to be matched with a suitable developer, use our .
I'm glad you're here. :) –Isaac
Mechanic is a Shopify development and automation platform.
Are you working on something Shopify-related?
Mechanic is only available for Shopify.
We have hundreds of common scenarios already handled with pre-written, open-source, modifiable, off-the-shelf tasks.
Mechanic's toolkit goes beyond Shopify's APIs, but a Mechanic task can only interact with Shopify data in ways that Shopify supports.
Whether you need a developer or already have that covered, the path to creating a custom Mechanic task is well-established.
Mechanic's automation tasks are written in Liquid, which is a template language used heavily in and around Shopify. This means that developers of all levels, with even a little Shopify development experience, can get started with Mechanic.
This is a super common path, and the Mechanic community is here to help. :)
for an off-the-shelf solution
for a task that fits you perfectly
if you need something else
Find Mechanic on the Shopify App Store:
Mechanic is a Shopify development and automation platform, which comes with a rich – and our users write their own custom tasks every day. Let's find out if Mechanic might work for you.
Is what you're looking for already available from ?
As far as your problem concerns Shopify data, is what you want to do supported by the ?
Are you open to ?
That list wasn't exactly a formal flowchart, but we hope it's helpful as you're evaluating Mechanic for your purposes. At its best, Mechanic is a platform and toolkit that you go to, and return to, when you hit the limits of the Shopify admin. And it's a community that collectively has learned how to solve many, many kinds of problems. (Join our !)
Got a question you need answered now? 💬
A developer writes – Mechanic's term for a piece of automation. These tasks can respond to many different , like a Shopify webhook, a manual trigger, a regular interval (e.g. hourly, daily), or an incoming email. Tasks use to signal their interest in specific event types.
When a task receives an incoming event, it can choose to generate an – an operation that has an effect.
The action makes changes to a Shopify store, like tagging, publishing, creating or deleting resources. It provides direct and complete access to Shopify's admin API, with support for both REST and GraphQL.
The action is for sending email. It supports custom templates, and attachments.
The action is for uploading files to an FTP or SFTP server. These files may be generated by the task, or can be fetched from external locations.
The action performs any request, to any HTTP endpoint. This facilitates integration with third-party APIs.
The action generates a variety of file formats, including PDF, CSV, ZIP, and anything retrieved from a public URL. Files generated this way receive a temporary URL of their own, and can be fed into other tasks for further processing.
For a complete list of supported actions, see .
Mechanic makes heavy use of – a template language created by Shopify. Its primary use is in . In the same way that a Liquid theme receives browser requests and renders HTML, a Mechanic task receives events, and renders actions (by defining them with JSON).
In Mechanic, our Liquid implementation includes additional support for constructing and , and includes many useful , making data processing more efficient.
Mechanic performs work using queues of , with no limit on how large each queue can become. If there is a sudden surge of incoming events for a Shopify store, the store's dedicated Mechanic queue could become delayed. This is an important difference between Mechanic and many other systems: in a high-traffic period, Mechanic will never refuse incoming events for a store; instead, it will process each one as soon as possible, by putting them into a run queue. The rate at which Mechanic processes work varies, depending on and the .
To find a developer for hire, you can contact Mechanic Partners directly at . This is a growing list of established developers, both independent and agency, who can help you with your implementation.
If you already have a developer on your team, or have an existing connection to a developer, send them and see if they can help you!
When building a new task, it's often easier to modify an existing task than to create a task from scratch. Searching GitHub is a good place to start, when looking for inspiration.
The Mechanic community maintains a board of task requests, where anyone can submit their idea for an addition to the Mechanic task library.
We accept task requests in two categories:
Tasks that are broadly useful off-the-shelf for non-technical users
Tasks that are useful foundations for developers, for further modification or inspiration
Mechanic's task library is a compendium of e-commerce automation tasks and documentation, written by the Mechanic community and the Mechanic core team. , everything is open-sourced under the highly permissive , making all library tasks appropriate for re-use and modification.
To browse the task library, visit .
The Mechanic community can request new tasks – see .
The task library is open for contributions, by way of pull requests – see .
If you need a task that's specifically tailored to a unique situation, or if you have a tight timeline, the task requests board is likely not a good fit. Instead, to create something that suits your needs specifically.
The Mechanic staff commission these from developers in the Mechanic community. If you're a developer interested in receiving this kind of work, get in touch at .
Head to . :)
Mechanic was made for working together. Our Slack workspace is where hundreds of folx compare implementation notes, collaborate on projects, and talk about the evolution of Mechanic itself – and it's the best place to ask your questions. You are always invited. :)
Got some code to share in Slack? Use to share code with line numbers, and syntax highlighting, in a way that doesn't take up lots of vertical space in the channel. Don't share lots of code without a snippet!
We follow the same process any open-source project does when it comes to code management and code contributions. One bonus of contributing to the Mechanic task library is that once you learn the process here, you'll know how to contribute to open-source projects going forward.
Forking means taking a copy of our repository, so that you can make your changes and additions.
Make your changes in your forked repository.
While in the project directory, run the following commands to build the docs:
npm run build
and npm run test
.
If all goes well with the build, you'll see your task listed in the automatically created documentation in docs/README.md
Mechanic's is a central resource for the entire community, and is continually enriched through contributions, via pull requests .
You've created a custom task, and you want to share it with the world! This brings us so much joy, and this is what the Mechanic project and this community are all about. If you get stuck along the way, please hop onto the , and we'll be glad to help.
The task library is hosted in a Git repository on GitHub. You'll make your contribution via a .
You'll the task library .
Make a , which will trigger a review of your proposed changes and the merging of them into the main repository, making your task available to everyone using the app.
You'll need a GitHub account, you can signup for one .
Visit the and fork it as shown below. You'll make your changes to this copy of the repository.
The task library is made up of the and the supporting documentation. In these next few steps, you'll ensure you can build the , so that you can complete this step when you are ready to submit your contribution.
Building the docs requires nodejs and npm. You can install them from here:
Now that you can build the docs you are ready to !
Your task documentation, options, subscriptions, code, are done in Mechanic. If you choose to use an external editor that's great, you still need to transfer it into Mechanic, so that you can export the task in the JSON format you need for the library. Importing/Exporting tasks from Mechanic is covered .
If you're changing an existing task you the JSON, and replace the contents of the task/task_file_name.json
and then run the commands npm run build
and npm run test.
If you are contributing a new task, you'll the JSON from Mechanic, and save the JSON file in the tasks/directory
of your forked repository, named with an appropriate handle for the task. (For example, a task named "Hide out-of-stock products" should have its JSON export stored in "tasks/hide-out-of-stock-products.json"
.) And, then you'll execute the commands:
You're now ready to make your pull request! Head over to and click New pull request, you should see the changes you committed to your fork, and you'll proceed with filling out the pull request form.
After you submit your first pull request, you will be required to read and accept . The will leave a comment, giving you a statement of agreement that you must paste into a comment of your own.
This process could sound confusing if you haven't done it before, but once you've done it once, it's simple and it is also pretty exciting to go through the process. The other bonus is, you'll be ready to submit a pull request to any open-source software project in the future. If you need help please out to us in the .
This tutorial walks you through setting up a custom task in Mechanic, which is called on Contact Form submission on your Shopify frontend, the contents of the form are passed to the task, which emails the contents in CSV format.
Before beginning this tutorial, here's what you'll need:
We have an online store called Mario's Mushrooms, hosted on Shopify. Business is booming, and our mushrooms are being shipped all over the world. Our CEO, Mario, asks us to connect our default Shopify contact form to our legacy customer relationship management (or CRM) system. We are eager to help! While the CRM doesn't have an HTTP API, it can receive CSV imports via email, which it will then import into its database. This gives us our path forward!
We are going to make a task in this cool Shopify app called Mechanic. ;) Here's what the task will do:
Over on the Mechanic side, the task will receive the form contents, and format them as a CSV file
Time to build the task! Out of Mechanic's entire toolkit, here's what we'll use:
We have options here! The only hard requirement is that we use a POST request to send form data to our webhook. This can be done using pure JavaScript, or using a library like jQuery, or even by using plain HTML to set the form tag's action
attribute to our webhook URL.
First things first: we're going to make sure of the element ID, for our contact form. This will be important for writing JavaScript that addresses this form. After investigating, we discover that the form ID is "ContactForm". Easy enough!
Next, we're going to write some JavaScript that listens for thesubmit
event of this form – functionally, this means that we're going to wire up some code to run when the form is submitted. The goal: to jump in when the form is submitted, send the form data to our webhook (which will then trigger our Mechanic task), and then allow the form to submit as usual. This way, we add Mechanic functionality without disabling the form's existing behavior.
Let's get started on our JavaScript. In your Mechanic task editor, scroll down and find the "JavaScript for Online Storefront" area. This will add this feature to our task, and we'll be given a place to add in our JavaScript, which will be automatically loaded into our shop frontend.
Copy in the JavaScript below, reading the comments for details on what's going on. Remember the "ContactForm" ID? Here's where we get to use it!
When pasting in this code, a new task option will appear, allowing the user (that's us, for now) to configure the webhook URL. Here's where we use the Mechanic-generated webhook URL from earlier.
With all that in place, save the task. We're leaving the task code empty for right now, and that's okay!
To make sure what data we're working with, let's submit the contact form, and then examine the resulting event data in Mechanic. (It's okay that we hit the captcha prompt; the important part is making sure that we're sending data to Mechanic.)
Heading to the "Events" page of the Mechanic app, we can see our data coming in.
Clicking through to that new event, we can see the event data on the right, reflecting what was in the form at the time of submission. (Depending on the nature of your specific contact form HTML, you might see something slightly different.)
This is perfect! The data we are interested in is inside of an event data property called "contact"
. This means that, in Liquid, we can access the contact data using {{ event.data.contact }}
.
Here's how we'll configure the task, using the task option fields that automatically appear based on our task code:
With everything assembled, we head back to the contact form, and make a submission. Back in the task editor, we see a new event appear in "Recent activity", with a green checkmark indicating that the task generated and performed an action.
We did it! We augmented our existing contact form with the ability to send submission data to our new Mechanic task, which relays the data to our CRM system using a CSV email attachment. 🎉
If you'd like to quickly pull in all of the task code and configuration we used here, use this task export:
A Shopify store, which has Mechanic installed (see )
A basic knowledge of Liquid ()
A basic knowledge of JavaScript ()
The task will add some JavaScript to the online Shopify store, which will capture the contents of the contact form when submitted, and then send those contents over to Mechanic via
The task will then send an to our CRM system, containing the CSV file as an attachment
Start with the tutorial for this part. Webhooks should be configured with respect to the source that supplies them with data, so for this tutorial, use the webhook name "Contact Form" and the event topic "user/webhook/form".
For this tutorial, we'll use JavaScript. And because we're using Mechanic, we don't even have to edit the theme directly to add in our code – instead, we can use the task editor's feature to have our code automatically loaded into the online storefront. (Under the hood, Mechanic leverages Shopify's API.)
For this tutorial, I created a development store and installed the . I use the contact form that comes with the theme as the form that submits to our webook. You can use any contact form on any theme, or create a form specifically for the purpose of submitting to our webhook.
Moving back to the task editor, the first step is to extract this data, and assemble it into something we can format using the filter. Because that filter is made to handle tables of data, this means that we'll create an array of "rows", and fill it with arrays of "columns", and then pass the result into the csv filter.
After that, we'll add an action, configuring it with our CSV data as an attachment. We'll also add a few more task options that will make it easy to reconfigure this task in the future, without having to touch the task code.
When writing a task, it's important to think about , and how they appear to the user (and to Mechanic itself). This task always sends a simple email for every event it receives, and doesn't require any special permissions, so we don't need to do any preview work here. If the task only sent an email under limited conditions, or if it needed to access the Shopify API, we'd need to do more work to make sure the task generates an intentional preview.
To learn more about this, see .
Thanks for reading! If you've got questions or suggestions, join the . :)
When Mechanic receives data via a webhook, it fires off an event with the user topic of your choice. (For example, if you've set up an IFTTT webhook that sends you tweets, you might choose the Mechanic topic user/ifttt/tweet
.) To make use of these events, create one or more tasks that subscribe to this topic. That's it!
Let's review a detailed example.
Start by opening Mechanic, from the "Apps" section of Shopify. Once in Mechanic, click the "Settings" button in the upper-right corner, then navigate to the "Webhooks" tab.
Webhooks should be named after the service that will be sending you data, with an event topic that makes sense, using the format user/subject/verb
.
For this example, we'll simply call ours "Example", with an event topic of "user/webhook/test".
Click the submit button to save the webhook, and use the copy button to copy the resulting webhook URL.
The URL will look something like this:
Back on the Mechanic homepage, click the "Add task" link.
Then, click the "Start a blank task" button.
Lastly, save the task.
Click the "Send" button, and you'll see a 204 response returned within ReqBin.
Over in Mechanic, watch for the new event on the "Events" page (or in the "Recent events" section of the Mechanic homepage):
Click on that event to see the results of our task and its echo action.
This last part is up to you! Provide the webhook URL, generated by Mechanic, to whatever service you'd like to use. When provided with this URL, the service will start sending your data over to Mechanic for processing.
That's it! :) Adjust to taste.
A typical REST products loop in Mechanic will have the structure below. While this is a concise format to get all products in shop, its main drawback is the inability to limit or filter the number of records and fields returned. This generates a significant amount of extra data for the task to manage in memory during a task run, especially if connected resources are looped as well (e.g. variants).
GraphQL paginated queries work by using the same (potentially filtered) query repeatedly to retrieve resources until the end of the list is reached or the querying is terminated by code logic. In Mechanic, paginated queries are typically implemented by using an outer "for loop", with an arbitrary number of maximum loops (e.g. the 100 in {% for n in (1..100) %}
).
Within the query itself, the first
filter limits the number of records returned in this batch, and the after
filter will instruct which "cursor" the query should start at. This cursor will initially be set to nil
, which indicates starting at the beginning, and it will be updated by the looping logic before the next query is run, using {% assign cursor ... %}
.
In this tutorial, you'll learn how to publish a Google sheet to the web as a comma-separated values (CSV) file and then fetch that data from Mechanic.
You can either create a sheet with the sample data shown below or you can use your own data for this tutorial. Keep in mind that the column headers in the first row will be the exact keys that you need to reference in the task when iterating over the data rows for your own usage.
Sharing sheets openly this way on the web so that is accessible by Mechanic works best for non-identifying data. Be sure to clean all customer-specific data and branding from your sheet data before publishing.
From the File / Share menu, choose the Publish to web option.
From the Link tab of the modal dialog that opens, select the sheet you wish to share and the Comma-separated values (.csv) option, and then click the Publish button.
After clicking OK on the confirmation dialog, the modal will update to show you the URL link that you will need to copy into the demonstration task configuration settings. You can safely close this dialog window now.
After adding the task you should update the Gsheet URL option field with the link to your sheet that was generated in the prior step. Update the Alert email recipients with one or more email addresses where you want to be notified in case Mechanic is not able to access the shared sheet (e.g. the share is disabled).
Run the task manually using the Run task button and it will run the first sequence of the task, which will make an HTTP request to GET the sheet data.
To see the results of the data retrieval you need to click on the mechanic/actions/perform child event after it appears.
Until further notice, Shopify will continue to send product webhook data in a REST-like format. Tasks that only use the fields available in the webhook (e.g. product.title
) may not need to be converted by the deprecation notice date. However, if connections to other resources are made from that product (e.g. product.collections
), then that will require conversion.
This is a simple task to loop through a product's collections, check if the collection contains a certain tag, then log out the collection title.
The GraphQL version of the the task above use a paginated query to get all of the collections a product is a member of. The outer loop upper range (e.g. the 10 in {% for n in (1..10) %}
) is arbitrary, and you may adjust it to the approximate maximum number of collections any given product might have.
This technique has several limitations:
Shopify doesn't support delivering the feed contents as plaintext. To get technical, this means that the feed will always be delivered with a content type of text/html.
Because this task stores feed values as a shop metafield, feeds created with this technique may only contain and display up to 65,535 characters.
Start with our example task, using the "Try this task" button to add it to your account:
Immediately after adding the task, run it by clicking the "Run task" button. This will populate your shop's records with the initial value of the feed.
This task replicates Shopify's own product inventory CSV export. Feel free to make changes to the script, and don't hesitate to get in touch if you have questions. :)
This is the template that will be responsible for displaying your feed contents, without the usual page formatting that your shop's theme usually applies.
To do this, navigate to the "Themes" section of your Shopify admin (under "Online Store", or by searching for "themes"). Then, under the "Actions" menu for your current theme, click the "Edit code" link.
Next, click "Add a new template".
Then, select the option for creating a "page" template, of type "liquid", and fill in the text box with the name "feed" (or another template name to your liking).
Next, fill in the template contents with the following:
... and click the "Save" button. Your template should look like this:
Navigate to the "Pages" section of the Shopify admin (under "Online Store"), and click the "Add page" button (or search the admin for "add page"). Name the page "Feed" (or another name of your liking), and change the page template to "page.feed.liquid".
Save the page.
Webhooks are the nearly ubiquitous carriers of information to and from services across the internet - services like IFTTT, Zapier, Stripe, PayPal, JotForm, and countless more. You can use webhooks to send information from these services into Mechanic, where you can then perform any and you need.
This is a tutorial for getting started quickly. To learn more about webhooks themselves, see .
Keeping things simple for this example, we'll title the task "Webhook test", with a subscription to "user/webhook/text" (to match the webhook configuration), and a simple in the task code.
Open , and construct a request to our webhook. Here, we'll select "POST", paste in the webhook URL, and fill in a simple piece of content. (Webhooks support plain text, form-encoded content, and JSON; for this example, we'll use JSON.)
Finally, the query
filter of a resources query gives the ability to drastically reduce the number of records returned, allowing for very targeted inclusion and exclusion rules (e.g. products having a certain tag). Each resource has its own list of query filters, which can be reviewed in the docs
If a query has the potential to return a very large number of resources (including connected resources) in a shop, then a query may be better suited than using paginated GraphQL queries.
To assist with generating a paginated query block, you can use the in the Mechanic code editor, and it will prompt you to choose the object type to paginate over (e.g. products).
To see a code diff from a Mechanic library task that was recently converted in this manner, click .
You can either add the demonstration task using the Try this task button from this task library link - - or you can add it from within the Add task screen inside of Mechanic.
Using the reference information available in these docs, write your own Mechanic script to iterate over the rows of data (array of hashes) that is parsed from the CSV, and make useful using the GraphQL or REST APIs.
If you have any questions, head to .
The event preview block in this task sample makes this code appear to be overly verbose, however the is often an important step to ensure that Mechanic prompts for the correct scopes for reading and writing Shopify API data.
To assist with generating a paginated query block, you can use the in the Mechanic code editor, and it will prompt you to choose the object type to paginate over (e.g. products).
Working on getting better at task-writing? See .
Use , to show the merchant a preview of what the task will do
2. Move to , using stub data
3. Remove the stub data, and add two : one for a @gmail.com address, and one for another address
Note: this technique is useful for
See to learn about looping through results using cursors
In this tutorial, you'll learn how to create a feed of your shop's data, and make it available on your online store, at a URL like https://example.com/pages/feed
Tip: The data you generate can be imported directly into Google Sheets. Learn more:
To move beyond these, consider using the to upload your feed to your own server.
Open up the page you just created, and you should see the contents of your feed. :) If you have any questions, head to .
Important Notice
These conversion tutorials will be be based on products, variants, and associated resources, but the methodologies are applicable to other type of REST resources as well.
Identify REST usage within a task
Broadly, any usage where one Liquid REST object is used to reference another Liquid REST object with dot notation. This does not include fields on the original REST-like webhook resource (e.g. product.title
).
For the product and variant resource deprecations specifically, this includes:
shop.products
shop.variants
collection.products
inventory_item.variant
inventory_level.variant
line_item.product
line_item.variant
product.collections
product.metafields
variant.inventory_item
variant.inventory_levels
variant.metafields
variant.product
Update Mechanic task code : Replace the relevant REST calls with Mechanic-flavored Liquid GraphQL query and result objects (see the tutorials following this page for examples).
Testing: Trigger the updated task to make sure it returns the expected results and/or takes the expected actions.
The product webhook does include an array of images and variants in the product JSON which will still be accessible via dot notation. Note that these are not the same as the previously available Mechanic REST lookups for those resources.
At its core, accessing a single resource via either API is effectively the same. Typically this involves passing the ID of the resource to the API and getting back the data for that resource.
In a REST call, every field of that resource will be returned, allowing the usage of simple dot notation to utilize whichever fields are desired without first requesting them.
The equivalent query in GraphQL would need to be augmented to include the desired fields.
Occasionally, the REST and GraphQL APIs do not use the same field names. And in some cases, there are some fields with no counterpart between the APIs. Review the API docs in detail for the resource being queried to make sure the task code is using the correct field names.
This is a basic task to check a product's status, type, and tags, and then output a log entry if that product qualifies.
The preview block is only showing the fields from the REST product webhook that will be used in the task. In reality, there are about 150+ lines of detail from a product webhook which has only a single variant and image. This grows much larger as variants and images are added to the product.
The product id used in the GraphQL query below comes from the REST-like product webhook, which will still exist after the REST product endpoint deprecation.
The preview block simulates the relevant shape of the returned data, which typically matches exactly what was requested in the query. This could vary though based on the task logic following the preview block.
While metafields can be queried directly using their ID, this attribute is not present in the product webhook data. The standard approach in GraphQL is to query the product resource for the metafield(s) and value(s), passing the namespace
and key
as the "key" value, in the same manner as the REST dot notation lookup.
In specific cases, events may be triggered by activity associated with an earlier event. In these scenarios, we describe the subsequent event as a child event, and the preceding event as a parent event.
Tasks responding to child events may reference to the parent's event using {{ event.parent }}
. Parent events are recursively available (as in {{ event.parent.parent.parent }}
), to a limit of 5 generations back.
When viewing any given event in Mechanic, look in the event details to find any parent or child relationships that apply. Click through to any displayed parent or child event to view that event's details.
As written, this task will "fan out": it will generate 1 child event, which will then generate 2 child events, each of which will then generate 3 child events, and each of those will then generate 4 child events, and finally, each of those events will generate 5 child events of their own. The result: 154 events, created with a single click. 💪
Importantly, note the "task_id"
option, applied to the Event action. This option ensures that only this task, and no other, will respond to the new event. While it's unlikely that any other task will subscribe to "user/fan/out" events, this option is important for ensuring expected behavior.
In Mechanic, an event represents anything that happens. This could be an order being paid, or a customer record being created, or a fulfillment being delivered.
Events are fed into Mechanic by the responsible party – for events that are about things in Shopify, for example, the events come to Mechanic from Shopify itself.
Shopify is deprecating the Shopify Admin REST API which the Mechanic REST objects depend on. The first round of deprecations involve the product and variant endpoints. Read about the deprecation and .
Use the going forward. The and objects will cease to work on on Feb 1, 2025 due to the changes being made by Shopify. Shopify will phase out the REST API completely over time, you can read more about this .
Understanding the Shopify GraphQL schema Familiarize yourself with the objects, queries, and mutations.
Review how to use GraphQL in Mechanic Start and peruse the to see examples of GraphQL usage in tasks.
product.images
product.variants
Field mapping: Identify the objects, fields, and nested structures needed in GraphQL based on the existing REST usage within a task. Build and validate queries using .
The images and variants data arrays should be used with caution once Shopify releases , in conjunction with the product and variant REST endpoint deprecations. The product webhook will only include full detail for the first 100 variants. It is not yet clear what Shopify will do with images in the product webhook.
To assist with generating an object query block, you can use the in the Mechanic code editor, and it will prompt you to choose the object type to generate a query and preview block for (e.g. product).
To see a code diff from a Mechanic library task that was recently converted in this manner, click , and review the code variations between the {% if event.topic == "shopify/orders/create" %}
blocks.
For every Shopify resource object that supports metafields, Mechanic has traditionally provided a way to directly access those metafields from the resource using . This shortcut will no longer be accessible for product and variant REST resources once they are fully deprecated.
The generates a new child event, when performed
A subscription to the topic generates new child events as actions are performed
An event always has a , and data (even if the data is null/nil). Event attributes may be referenced in Liquid using the .
Events may trigger any number of , resulting in any number of .
Incoming events may be selectively skipped using .
One method of conversion for lookup fields is to utilize a GraphQL query directly in the option field, which naturally has some caveats.
Event preview blocks are not evaluated in task option fields. Instead, default values should be assigned to any webhook fields utilized by the query (e.g. product.admin_graphql_api_id). This will keep the task parser happy and allow you to save the task. Be careful though to not assign a default value to a webhook field that can have a null or blank string as a valid value.
It can be helpful when using a GraphQL query in a task option field to add the code flag to the option field, which will add line numbers and give access to Mechanic code snippets.
A task may have any number of subscriptions.
... are accomplished using subscription offsets, as described below. This heading is here for folks searching for a way to delay their tasks. ;)
Subscription offsets are appended to the subscription topic, and are of the form "+1.hour". Offsets may be given using seconds, minutes, hours, days, weeks, months, or years. There is no limit to how large the subscription offset may be.
A subscription with an offset looks like shopify/customers/create+1.hour
.
In practice, large offsets can make debugging difficult! If you're thinking about work to be done weeks or months or years from now, consider running an hourly or daily task that scans for work that's due to be done, instead of scheduling tasks for the distant future.
To reload the data in a Shopify variable, use something like this:
One subscription is permitted per line. Blank lines and leading/trailing whitespace are permitted.
A topic looks like "shopify/customers/create", and it has three parts:
The domain describes the source of the event. Shopify events have "shopify" as their domain, and events generated by Mechanic itself use "mechanic".
The subject describes the type of resource the event describes. Events that are about customers have "customers" as their subject, and events that are about orders have "orders".
The verb describes what has just occurred. Events that are about creating resources generally have "create" as their verb, and events that are about deleting resources generally have "delete".
The User event domain is for custom, user-generated events, having any subject and verb (e.g. "user/foo/bar"). As with all events, a User event topic must use the standard three-part topic form, but only the "user/" prefix is mandatory.
Mechanic allows developers several ways to generate custom User events:
An oft utilized feature of Mechanic is the ability to add Liquid tags into task options fields, such as a configurable email body. Additionally, these Liquid tags (currently) support inline resource lookups for data not available in the event webhook. However, for products and variants this will no longer work as of the .
The code above could be utilized directly in a . and it would output a string of text (e.g. "Special product notice for Widget - Red...") into the assigned option field variable.
A task subscription is the expression of a task's intent to receive certain , filtering by . A subscription consists of an event topic, optionally combined with a time offset, which creates a delay.
A subscription offset (sometimes called a delay) defines the amount of time a task should wait or delay (!!) before responding to the incoming event. It's the easiest way to add a delay to a task's subscription to a specific topic. (For finer control over event timing, try using the run_at
option of the .)
To learn more about scheduling work with Mechanic, see .
The available to tasks always contain data drawn from the event itself. If a task has a offset event subscription, this data may be outdated by the time the task runs.
Remember, Mechanic does not permit access to the Shopify API during . Using this unless
statement ensures that reloading only happens during a live event.
A task's subscriptions are parsed for Liquid, at the time the task is saved. Combined with , this is an opportunity to generate subscriptions based on user configuration, adding or removing subscriptions based on the user's choice, or adjusting subscription offset based on a user-entered value.
In Mechanic, a task is a bundle of logic and configuration, that responds to and interprets . The result of a task can define , which are the task's opportunities to have an effect on the world.
A task responds to events based on its . When an event is received that matches a subscription, the task processes the event using its . The code has access to the event data; it also has access to the user's task configuration, through . Task code is written in Liquid, and is responsible for rendering a series of JSON objects (including , , and objects), defining work to be performed once task rendering is complete.
A task uses its to communicate ahead of time the work it intends to do. Previews are important for users, and are also important for Mechanic itself – Mechanic looks to the task preview to understand what permissions a task requires.
Tasks may be written from scratch, or installed from the Mechanic library (available in-app and ). Once installed, a task's code may be modified at any time.
Working on getting better at task-writing? See , and .
This very basic task subscribes to shopify/customers/create, and renders an , using an email subject and body taken from user-configured .
To make events easy to identify, each event has a topic. Tasks signal their interest in specific event topics using .
The can be used with any User event topic
may be configured to generate events using any User event topic
A task's code is a template. In the same way that a Shopify storefront might use a Liquid template to receive requests and render HTML, a task uses its Liquid code to receive events, and render a series of JSON objects. These JSON objects define , , and .
Learn more:
Task code always has access to a set of , which can be used to make decisions about what JSON objects to render.
A task must purposefully consider its , so as to accurately communicate its intent to users and to the Mechanic platform.
To find many examples of task code, browse .
A task's Liquid code always has access to a set of environment variables, defined by Mechanic.
Variable
Contents
shop
event
An object containing information about the current event
cache
task
An object containing information about the current task
options
For example, a subscription to shopify/customers/create will make available a variable called customer
. A subscription to shopify/products/update will expose a variable called product
, etc.
All Shopify events support an additional variable named after the event topic. For example, when a task responds to a shopify/customers/create event, it will have access to an additional variable named customer
, containing the customer data contained in the event.
Shopify variables in Mechanic do not necessarily contain the same attributes as Liquid variables used in Shopify (in places like themes or email templates) – even if they share the same name.
In Mechanic, Shopify variables always contain data from Shopify events, which are delivered to Mechanic via webhook. This means that Shopify variables always have the same data structure as Shopify webhooks, corresponding to Shopify's REST representation for this data.
Environment variables may be reassigned as needed. (When preparing a task preview, this may be a necessary technique.) To learn more, see .
An object containing
The current store's object, supporting lookups for cached values
An object containing task , configured by the user
The available to tasks always contain data drawn from the event itself. If a task has a offset event subscription, this data may be outdated by the time the task runs.
Remember, Mechanic does not permit access to the Shopify API during . Using this unless
statement ensures that reloading only happens during a live event.
When a task is actually invoked for an event, it may have access to an additional variable, determined by the specific event it is responding to. When this is the case, the additional variable will be named after the event subject, and its contents will be established by the event's data. The name of this variable is communicated by the Mechanic task editor, based on the task's current .
Shopify events always contain data from Shopify's REST representation of each resource; therefore, automatic Shopify variables always contain data from the REST representation as well. The best resource for the data available for each variable type is .
For example, while Shopify themes support customer.name
, Mechanic does not (because does not contain a "name" property). On the other hand, Mechanic supports customer.created_at
, while Shopify themes do not.
Log objects are useful for recording information for later reference. They have no side-effects. Carefully chosen log objects can massively simplify post-hoc debugging, especially (as we've found) when investigating merchant bug reports.
A log object is a plain JSON object, having the following structure:
The log details can be any JSON value.
Log objects appear wherever task run results are visible, including the task preview and when viewing an event.
Options are made available in the options
variable, which is a hash having key-value pairs for each option key and option value. The option key must only contain ASCII numbers, lowercase letters, and underscores. The option key is reformatted for use as the option name presented to the user – underscores are replaced by spaces, and the entire line is sentence-cased.
Because option keys are registered via static analysis, options must each be referenced using a standard lookup (e.g. options.foobar
) at least once.
Options are displayed to the user in the order in which they are first referenced in the task code.
Because this may not result in a natural sequence, it can be useful to prefix task code with a comment block, explicitly referencing each option so as to force the overall order.
Option flags control how an option appears and behaves in a task's configuration form, and also control the type and format of the option value.
Most flags may be combined with other flags, for more nuanced control.
If no flags are used for an option, an option will be made available as a plain text field, and the option value will be a string.
Options that allow text input are evaluated for Liquid when a task processes an event. Liquid evaluation for options occurs before it occurs for task code, which means that any Liquid variables created by task code are not available to task options.
Log objects are most easily generated using the .
accept user configuration via options. Options are created dynamically, by reference: each option referenced in a task's results in that option being added to the task's configuration form. In the option reference {{ options.foo_bar__required }}
, the option key is foo_bar__required
. The appearance and behavior of the option's form element is based on flags in in the option key – in this example, only the "required" flag is in use.
Mechanic flags provide only limited option validation. A task may define , by rendering error objects according to the task's its own validation logic.
Liquid code in task options have access to the same set of that are made available to the task code, including event
, shop
, cache
, and any event subject variables.
Flag
Effect
required
Requires the user to populate this option before the task can be saved
boolean
Renders a checkbox; the option value is a boolean
multiline
Renders a multiline text field; the option value is a string
Renders a text field of type "email"; the option value is a string
number
Renders a text field of type "number", configured for value steps of 1; the option value is a number
code
Renders a text field that's formatted for code; the option value is a string
keyval
Renders a compound form element, allowing the user to provide zero or more key-value pairs; the option value is a hash, containing these key-value pairs
array
Renders a compound form element, allowing the user to provide zero or more values; the option value is an array, containing these values
An action object is a plain JSON object, having the following structure:
Action options vary by action type. Depending on the action type, its options may be another complete object, or an array, or a scalar value.
Actions may optionally include meta information, annotating the action with any JSON value.
This information could be purely for record-keeping, making it easy to determine why an action was rendered, or to add helpful context:
An action object defines work to be performed by an , after the task is fully finished rendering. Action objects are most easily generated using the .
Use the to skip the boilerplate while writing actions. All tasks in the Mechanic task library use the action tag, rather than writing out the action object in raw JSON.
Learn more:
The action type is always a string, having a value that corresponds to (e.g. "shopify"
, or "http"
).
Or, this information could be used to facilitate complex task flows, in concert with a subscription to mechanic/actions/perform (see ). An action's meta information can supply followup task runs with information about state, allowing the task to cycle between different phases of operation.
A task uses its preview to demonstrate what actions the task intends to generate. Among other purposes (see below), this is also how tasks request the Shopify permissions they require.
Mechanic generates a task preview by rendering the task code using a preview event, which resembles a live event that the task may see. The task is then responsible for rendering preview actions in response to the preview event, actions which are visually presented to the user and are analyzed by the platform, but are never actually performed.
A preview has three critical purposes:
Showing the user that the task will do what they expect it to do
Showing the task developer that the task code is functioning as intended
Showing the Mechanic platform what permissions the task requires
Core to the design of Mechanic is the idea that we can make it easy to make it easy – in this case, making it easy for developers to show their users what a Mechanic task can be expected to do.
Developers may think of previews as a sort of test, using preview actions to prove that their task code is functioning as intended. A quality task will exercise all of its code in response to a preview event; doing so gives the developer instant feedback on task results, without actually having to run the task with a live event.
At the platform level, Mechanic uses previews to determine what permissions a task requires.
Mechanic gets this information from the actions that a task generates during preview, as well as from analysis of the Liquid lookups and GraphQL queries that a task uses during runtime.
Previews are generated using synthetic, temporary, non-persisted events – at least one for each event topic that the task subscribes to. These events are sourced from one of three places, in order of priority:
Or, if the Mechanic account has a recent event with a matching topic on file, the preview will use data from that event;
A preview event is identical to a live event in all respects but one: it contains a preview
attribute, set to true
, identifying it as a preview event.
For live events, the preview
attribute does not exist. This means that event.preview == false
is not a valid way to detect a live event. Instead, use event.preview != true
, or event.preview == nil
.
A preview event's data is taken from the Mechanic account's event history, providing a realistic sample of the data a task can expect to see. (If the account history has no events for a given topic just yet, Mechanic will attempt to use anonymous sample event data of its own.)
A developer can choose between rendering static and dynamic preview actions. Static preview actions are hard-coded, written to appear whenever event.preview
is true. Dynamic preview actions are the result of the task code running normally, using event data in preview in the same way that it would use that event data with a live event. Because dynamic preview actions are the result of meaningfully exercising the task's code, they can provide a good indicator of how the task will behave with a live event. By contrast, static preview actions do not provide useful feedback on how a task is coded.
In the following example, a static preview action demonstrates that the task intends to tag incoming orders with "web". In actuality, the task's intent is to only tag orders that arrive via the Online Store channel; because the task can't be sure whether or not the preview event will contain such an order, a static preview action is used to ensure that a preview event always results in a tagging action.
Branching a task like this has two problems:
The actual condition of the task is not exercised during preview. The task will need to be tested with live orders from multiple channels, in order to verify that the task works properly.
Duplicating code makes it easier for one copy of the code to fall out of date. By using completely different code for the preview and live actions, it becomes easier for developers to forget to keep the two copies in sync as the task evolves.
A dynamic preview action is the natural result of exercising a task's code as completely as possible, without adding any business logic that responds to event.preview
. Put another way, the idea is to make the preview (that appears during task editing) look as similar to a live event as possible.
There are two techniques available for "steering" the task towards desired outcomes during preview.
To provide tasks with relevant sample data during preview, developers can (to construct relevant scenarios at the event level) or use (to swap in predefined values for , or for the results of data that would otherwise come from the Mechanic cache or the Shopify Admin API).
By rendering preview actions, a task can prove to the user that it is interpreting their configuration as they intended. For example, by rendering a preview action, a task can show the user that their configured email content is appearing as expected inside the email body. This increases trust in the task, and allows users confidence in the task's outcome, even before the task processes a live event.
For example, if a task renders a action containing a mutation, Mechanic will prompt the user to grant access to the write_customers
Shopify OAuth scope. If Mechanic observes a task using shop.customers
, or observes the filter receiving a customer-related GraphQL query, it will prompt for the read_customers
scope.
Some GraphQL mutations have multiple potential scope requirements, like or . Because the requirements of these mutations hinge on their arguments, make sure that your preview actions are rendered with realistic ID strings (e.g. id: "gid://shopify/Product/12345"
). Mechanic will look for these IDs to determine what scopes to request.
If the task for a given topic, the preview will use the defined event;
Or, if the event topic is standard and known to Mechanic (i.e. not a part of ), the preview will use illustrative example event data defined by the Mechanic platform.
A static preview action is rendered in direct response to event.preview
. In general, it's better to use , but an understanding of both techniques is useful.
Use to control preview event data, without ever having to add preview-related code to the task itself. This is the cleanest way to control data provided by the event during preview.
Use to dynamically swap in preview-friendly values. This is generally not necessary for preview event data, but may be necessary when querying Shopify for data during a task: because the Shopify API is disabled during preview, using stub data can be useful for swapping in realistic values that would be returned during a live run.
A task may enforce custom validation for options by including validation logic in its code, inspecting the current value of an option and rendering an if the option does not meet its criteria.
A modification to a task option will always result in a new being rendered. In this way, a task developer may provide the user with immediate feedback on their task configuration.
Once the option is filled in, the task preview will be rendered. If the user has entered a zero, or a negative number, the is used to generate an . The error message will then be shown to the user, and they will be prevented from saving the task until they provide valid input.
When a task renders an error object, the task run will be marked as failed, and no rendered action runs will be performed. This is a good way to communicate an intentional failure to the user, when your Liquid code detects a certain condition.
Unlike a "raised" exception in other programming languages, a rendered error object is simply added to the list of the task run's JSON objects. At the completion of task code rendering, all objects are evaluated; at that point, if an error object is among them, the error is then raised and shown to the user.
An error object does not halt rendering of the task's Liquid code, but it does prevent any other rendered objects from having an effect. Specifically, this means that the presence of an error object means that any action objects will be ignored.
This also means that rendering an error object will not prevent the task from reaching any syntax errors (or other problematic code) later on in the task's Liquid code.
An error object is a plain JSON object, having the following structure:
The error details can be any JSON value. This value will be represented to the user as the reason for the task failing.
A task that renders an error object will interrupt the preview, and visibly communicate the error to the user. This makes error objects a useful way to validate .
Error objects are most easily generated using the .
By default, each preview event's data is sampled from previous events that the Mechanic account has seen, for the same topic.
However, developers may define their own preview events, containing whatever data the developer wishes to use for preview. This may be useful for several reasons:
Most tasks conditionally respond to events based on their data. Controlling the event data present during preview allows the developer to deterministically verify the results of the action.
Multiple preview events may be defined per event topic. This allows developers to verify that their task renders the appropriate results under a variety of circumstances.
Defined preview events can be labeled with a description, which is visible in the task preview pane. This makes it easy to identify the scenario that a preview event is meant to represent.
Preview events may be defined using the "Edit preview events" button, in the task preview pane.
The configuration area for preview events contains a quickstart link for each event topic the task subscribes to, allowing developers to get started using sample data if the event topic is known to Mechanic. Or, the developer may start with a blank preview event definition, filling in whatever topic and data are useful.
A developer may define any number of preview events per topic. If no preview events are defined for a given topic, Mechanic will construct its own ad-hoc event during preview.
Displayed beneath the event topic in the preview pane, allowing the developer to distinguish one scenario from another.
Identifies the event definition to Mechanic, when Mechanic goes to construct preview events by topic.
Used to construct event.data
, and may be set to whatever values are useful in representing a specific scenario. The data structures used here should resemble what Mechanic will receive for a live event of the same topic.
Notably, the data here can be limited to just the properties that are useful. For example, while Mechanic might normally generate a complete payload for shopify/orders/create, the developer might only care about the "email"
property of the order – and so their defined preview event data might be limited to just that property. (Note that the inverse may not be true: defining preview event data for traversals into other objects, e.g. using preview event data to define a value for order.line_items[0].product.title
, will not work.)
For a trivial task, subscribing to shopify/customers/create, and having the following task code...
... we define two preview events, one which represents a Gmail user, and one which does not. This allows us to easily assert that the task behaves properly in both scenarios.
Preview event definitions are stored along with the task itself, and thus are present in the tasks version history (and, naturally, in task exports).
Because definitions are a part of the task itself, they're appropriate for use as a testing tool, allowing the developer to verify that a task behaves as intended at every stage of the task's development.
During , Mechanic scans the task's . For each found, Mechanic constructs a synthetic preview event, resembling one that the task might encounter during live use.
Further, by deterministically/predictably generating actions, the developer can consistently demonstrate the permissions they need to Mechanic. (To learn more about this, see .)
Defining preview event data is usually simpler than defining .
Stubbing the event
variable (or any of the ) removes any intelligence from the objects Mechanic generates from event data, a drawback avoided by defining a preview event and its data. Using the as an example, a task may typically access its custom attributes via order.note_attributes.color
, or via order.note_attributes[0].value
. This dynamic behavior is lost if the event
variable is stubbed out, which can result in behaviors that are difficult to diagnose.
Preview event definitions cannot provide for return values from Shopify query operations (i.e. output from the , or the result of traversing Shopify Liquid objects, as in customer.orders.first
). For those purposes, use the technique.
Stub data is hard-coded into a task, providing an unchanging source of data for . It is an important tool when generating . Stub data may be used for user-defined variables, but may also override as needed.
For controlling preview event data (i.e. the values in event.data
, and values found in ), use to cleanly specify these values outside of the task code.
Most tasks make decisions based on the automatically provided, making it a common practice to stub them during preview mode. Any and all Liquid variables may be replaced by stub data, including event
and any .
In simple cases, replacement objects may be constructed using the tag.
It's also possible to construct this data using .
Mechanic makes GraphQL data available to tasks via the filter. Mechanic observes the shopify filter in action during preview mode, using its inputs to inform Mechanic's knowledge of what permissions the task needs.
It can be useful to specify stub data using JSON, fed through the filter. Sample JSON is easy to generate using .
This version is used in all activity related to the current task, including:
REST API calls performed to support Liquid lookups
All Shopify API versions are named with a specific date (i.e. "2021-07"), except for "unstable". This version receives regular updates from Shopify, and its features may change without notice.
Most tasks should use a dated version, to maximize the amount of time a task can rely on a specific set of Shopify API features.
Shopify supports each version for 12 months (except for "unstable", which is always available). 30 days before a task's version becomes unsupported, Mechanic will automatically begin calling the closest supported version instead.
The selector for a task's Shopify API version is available in Advanced mode, below the task code area.
Each task is configured with a specific , defaulting to the latest version at the time of the task's creation.
GraphQL calls performed by
All Shopify API calls performed by , including
Shopify may, at times, mark certain API features as deprecated. If a Mechanic account calls a deprecated API, Mechanic will display the deprecation notice in the app. Learn more about .
Mechanic supports this by allowing each task to specify its own JavaScript, to be injected into the online storefront.
Here, the developer can add in their own JavaScript code, taking advantage of Liquid for mixing in data from the current store, or from the current task's options.
Shopify allows apps to inject JavaScript into the online storefront. (This is facilitated by in the Shopify API.)
A task's JavaScript content only has access to to the shop
and options
Liquid variables. The rendering context is similar to that of ; Liquid code here does not have access to any data related to events, and cannot dynamically respond to any information about the visitor's current request.
Individual tasks may be optionally configured with their own documentation, formatted with Markdown, providing the user with anything they should know about the task's usage and operation.
Task documentation may be managed in Advanced mode.
In Basic mode, documentation is displayed below the task options.
Task documentation may be formatted with Markdown, a common syntax for text formatting.
Element
Markdown Syntax
# H1 ## H2 ### H3
**bold text**
*italicized text*
> blockquote
1. First item 2. Second item 3. Third item
- First item - Second item - Third item
code
---
[title](https://www.example.com)

We support this with an advanced task setting called "Perform action runs in sequence", configured in two parts:
Perform action runs in sequence – When enabled, Mechanic will only run one of the task's resulting actions at a time, performing them in the order in which they were generated.
Halt the sequence when one fails – When this option is also enabled, Mechanic will only run the next action if the current action was performed successfully. If the action fails, all following actions will be marked as failed as well, with error messages explaining the situation.
Action run sequences are enforced within each task run. This means that a task could see more than one of its actions performed at the same time, if the task itself were to run multiple times, simultaneously.
To explain by example: a task that responds to mechanic/scheduler/10min, generating a sequence of 5 actions that each take 1 minute to run, will never see those actions overlap. However, if the task generated 15 actions instead, the actions would begin to overlap, as the task generates 15-minute action sequences every 10 minutes.
Task documentation is shown to the user below the task's . Documentation is also shown in the confirmation prompt a user sees when they trigger a task that subscribes to either mechanic/user/trigger or mechanic/user/text.
The following table comes from , and is presented with no changes, under the license.
Mechanic's works asynchronously, performing as much work as possible, as quickly as possible. However, there are cases where it's important that actions run in a sequence – one after the other.
Mechanic has the ability to import tasks from JSON individually and in bulk, from the "Import tasks" screen.
Each task loaded via this route may be saved as a new task, or – if the task name exactly matches the name of a task already in the Mechanic account – it may be saved over the existing task. This latter path provides a way for batches of updated tasks to be loaded into a Mechanic account all together, preserving the version history for each task.
To import one or more tasks from a JSON export, use the "Import tasks" button on the Mechanic home screen.
On the next screen, follow the prompts to load your JSON task exports into Mechanic.
When working in the task editor for a specific task, use the "Import" button to load in task JSON and have it applied to the current task.
When viewing the task list on the Mechanic home screen, use the "Export" button after selecting one or more tasks to copy a JSON export of all tasks to the clipboard. This export can be used with Mechanic's task import area, described above.
When working in the task editor for a specific task, use the "Export" button to copy a JSON representation of the current task to the clipboard.
This action supports two styles of options: a more verbose nested structure, and a simpler set of positional arguments.
All commands must define a cache key, matching the regular expression /^[a-z0-9_:\-\.\/]+$/i
.
In this option style, the cache command is given as the root key of the options object. The root value is itself an option, containing the arguments needed for the selected cache command.
In this option style, the cache command and its arguments are given in a list. Use the cache command reference below to find the argument order required for each command.
Each cache entry is given a default TTL value of 60 days, or 5184000 seconds. (A cache entry's TTL may not exceed 60 days.)
A cache command will always reset the entry's TTL value upon execution, regardless of the TTL's original value.
Stores a value. Requires key
and value
. The stored value may be any JSON object.
Using a defined TTL (an expiration interval) given in seconds, stores a value. Requires key
, ttl
, and value
. The stored value may be any JSON object.
Deletes a stored key. Requires key
.
Increments a numeric key by 1. Requires key
. If the key is not already set, the value before incrementing will be assumed to be 0.
Increments a numeric key by the value of your choice. Requires key
, and an integer increment
. If the key is not already set, the value before incrementing will be assumed to be 0.
Decrements a numeric key by 1. Requires key
. If the key is not already set, the value before incrementing will be assumed to be 0.
Decrements a numeric key by the value of your choice. Requires key
, and an integer decrement
. If the key is not already set, the value before incrementing will be assumed to be 0.
An action type determines the class of operation to be performed. While actions may vary greatly, there are only a few action types.
Action
Purpose
Performing operations on the store's Mechanic cache
Debugging; displays the options that it is provided, with no side-effects
Sending transactional email
Generating custom user events
Generating files of various types, storing them at a temporary Mechanic-provided URL
Performing FTP file uploads and downloads
Performing HTTP requests
Mechanic maintains a set of integration actions, offering first-class support for several external services.
Google Drive
Upload files to Google Drive
Google Sheets
Create, Update, Export Google Sheets
Shopify Flow
Sending customer, order, product, and general triggers to Shopify Flow
Shopify Admin API
Sending requests to the Shopify Admin API, supporting both REST and GraphQL
Report Toaster
Requesting reports from Report Toaster, or updating data within Report Toaster
The Echo action has no effects: it returns the options that are given. This action can be useful for testing or debugging, by temporarily replacing some other action with an Echo action having the same options. In this way, a developer can safely get feedback on what data is in play, without side effects.
Option
Description
to
Required; an array or comma-delimited string of recipient addresses
subject
Required; a string specifying the message subject
body
Required; an HTML string of body content; supports HTML and CSS
cc
Optional; an array or comma-delimited string of cc addresses
bcc
Optional; an array or comma-delimited string of bcc addresses
reply_to
Optional; a single reply-to address
from_display_name
Optional; a string controlling the name (but not the address) of the sender
headers
Optional; a hash of email header strings and value strings
template
Optional; a string naming an email template from the current Mechanic account
attachments
...
Additional options may be provided, and will be made available to email templates as variables, named after each option
Mechanic parses each email body for HTML and CSS, allowing authors to use <style>
tags without having to think about email client compatibility.
This action only supports sending from a single address (regardless of the sender name, as controlled by the from_display_name
option).
By default, the sender address is a Mechanic address based on the store's myshopify.com subdomain. For example, the store example.myshopify.com will default to having its mail sent from example@mail.usemechanic.com.
Changing the sender address involves adding it to the store's Mechanic account, and then configuring the email domain name with some DNS records for verification.
To use a specific email template with the Email action, use the template
option to specify the name of the desired email template.
All options used with the Email action will be made available as Liquid variables for the email template. This means that standard options may be used, like {{ subject }}
and {{ body }}
, and also custom options: passing in an "order_data"
option, containing order data, may allow the email template to show the order name via {{ order_data.name }}
.
Note that custom options, like all task options, must be provided using standard JSON. This means that the data made available to email templates will be derived from plain JSON values.
For example, consider this action:
The template named "order_acknowledgement" could include the following Liquid, and get the expected results:
This action supports attachments given in Mechanic's file generator format. This structure allows the sender to construct a variety of files, including ad-hoc text-based files, PDFs rendered from HTML, files dynamically downloaded from external locations, and ZIP files containing any other files.
Events generated by this action may be responded to by other tasks, or by the task that generated this action.
Option
Description
topic
data
Required; any JSON value (including null
), to be used as the event data
run_at
Optional; a Unix timestamp integer, or any string that can be parsed as a time
task_ids
Optional, cannot be used with task_id
; an array of task UUID strings, specifying which tasks are allowed to respond to this event
task_id
Optional, cannot be used with task_ids
; a string containing a single task UUID, specifying which task is allowed to respond to this event
If a run_at
value specifies a time in the past, the new event will be run immediately.
Uses the optional task_id
parameter to control which singular task is allowed to respond to this event.
That task must be subscribed to the event topic being used.
You can limit a task to itself by referencing it's own task.id
This example uses the run_at
option to run the task at a later scheduled time.
This task emails a customer daily until their order is paid. It works by scheduling a follow-up run of the same task, one day in the future, using the run_at
option.
This task emails a customer daily until their order is paid. It works by firing the follow-up event immediately, using a subscription offset to respond to it a day later.
Mechanic tasks may be imported and exported as JSON, using the "Import" or "Export" button below the task editor. The JSON schema used for representing tasks is identical to that used by the task library, making it suitable for .
The Cache action allows developers to interact with the store's Mechanic , using commands inspired by Redis. Cache entries have a key, a value containing up to 256 kilobytes, and a ttl value ("Time To Live") in seconds, defaulting to the maximum of 60 days (i.e. 5184000 seconds).
The required arguments for each command are given below, in the order in which they are supported for .
When a command is given using , the ttl
value (in seconds) is always supported.
In Mechanic, an action is an instruction for performing work that has an effect. Actions are generated by , in response to . Each action has a type, specifying the class of operation to be performed, and options, providing specifics about what that operation will do.
Actions are defined by tasks using , which are simple JSON objects specifying an action's type and options. Action objects can be constructed using the .
Learn more:
This action accepts any and all options, restricted only in that they must be valid JSON values (as with all results of ).
If the Echo action is given a "__error"
option, it will raise that error when the action run is performed. Use this feature when it's useful to indicate an issue with a task run, without marking the entire task run as a failure (as would be the case when using an ).
The Email action is for sending email. ✅ It supports the store's , and supports attachments constructed by .
Mechanic sends email via , our email provider. Currently, Mechanic only supports Postmark's transactional message stream, which means that marketing and other bulk mail may not be sent. To learn more about what is and isn't a transactional message, see Postmark's article: .
Optional; an object specifying files to attach, using
If you're simply trying to add formatted text and aren't ready to dig into the code yourself, try using a tool like to quickly generate usable HTML.
Images may be embedded using the <img>
tag, but must be hosted independently. Shopify provides basic file hosting, appropriate for uploading images for use with Mechanic emails. To learn more, see .
For more on this, see .
To achieve easily reusable headers and footers, Mechanic can be configured with one or more email templates, available in the Mechanic account settings. To learn more about configuring email templates, see .
But, because order_data
is a plain based entirely on JSON data, instead of being an enhanced order object (see ), the following Liquid usage would fail:
For more on this, see .
The Event action is for generating custom events in the . It's used to queue up follow-up work, either immediately or in the future, and can be useful when designing complex workloads, separating work between tasks.
Events generated by this action are of the event responsible for the current action.
Required; a string specifying an of the form "user/*/*"
Tasks specified by task_ids
or task_id
must subscribe to the event topic being used. As with all subscriptions, may be used, and will be respected.
See to have a user configurable input instead of hardcoding the task id(s).
The HTTP action performs HTTP requests. It is commonly used to invoke third-party APIs.
method
String, required
Must be one of "options"
, "head"
, "get"
, "post"
, "put"
, "patch"
, or "delete"
url
String, required
Must start with https://
or http://
body
String, required for non-GET requests
Format varies, see below
files
Hash, optional
headers
Hash, optional
May be set to a JSON object, mapping header names to header values
follow_redirects
Boolean, optional
Defaults to true
, may be set to false
; controls whether or not 3xx responses with Location
headers are automatically followed to their destination
proxy
String, optional
May be a proxy URI string beginning with https://
, http://
, or socks5://
; see "Using a proxy" below
verify
Boolean, optional
May be set to false
to disable SSL certificate verification
error_on_5xx
Boolean, optional
May be set to true
to have 5xx HTTP response codes be considered action errors
The HTTP action has intelligently varying behavior, based on the presence and value of the Content-Type header, and the data type of the body
option.
If the Content-Type header is unspecified or set to application/json
, and if the body
option is set to a JSON object or array, the request body will be automatically serialized to a JSON string, and the request will contain a Content-Type header set to application/json
.
If the files
option is not given, and if the Content-Type header is set to application/x-www-form-urlencoded
, and if the body
option is set to a JSON object or array, the request body will be serialized to a form-encoded string.
The HTTP action supports HTTPS, HTTP, and SOCKS5 proxy connections via the "proxy"
option, set to a URI string beginning with https://
, http://
, or socks5://
. When configured, Mechanic will open a connection to your proxy server, and pass your request through that connection.
An HTTP action returns an object containing the following keys:
File property
Description
status
An integer, specifying the response code
headers
An object containing response headers, where each key is a string and each value is an array of values found for that header
body
The interpreted value of the response body; see below
body_base64
The original response body, encoded using base64
Because HTTP allows for the same header name to be present multiple times, this action's result specifies an array for each response header – even if the header was only present once.
If the response contained a Content-Type header set to application/json
, the body
result value will be the result of parsing the response body for JSON.
By default, this action will consider any valid HTTP response to be a success, regardless of its response code.
However, because 5xx responses should often be considered a retryable error, this action supports the error_on_5xx
option. When set to true
, this action will interpret any 5xx responses as an action error.
A Files action returns an object having the same keys (i.e. filenames) as its input. Each value is an object, having the following properties:
File property
Description
expires_at
An ISO8601 timestamp, specifying when the file will expire
mime_type
name
The filename, as given in the original action options
size
The size of the generated file, in bytes
url
The URL at which this file will be available, until it expires
This task generates a variety of files. It then re-invokes itself (via mechanic/actions/perform), sending an email containing links to each of the generated files.
The Google Drive action allows you to upload files to your Google Drive.
The uploads
hash supports these properties:
This action requires connecting a Google account with the appropriate Drive permissions. To connect an account:
Go to the Settings screen
Click Authentication
Follow the Google account connection flow
Files can be organized in folders by including path information in the filename:
Use forward slashes to separate folder names (e.g., "reports/2024/monthly/file.pdf")
Folders will be created automatically if they don't exist
Can only access folders created by this integration
Invalid characters not allowed: < > : " / \ | ? *
The action returns details about the uploaded files. The response is an object with the following structure:
Upload and download files via FTP, FTPS, or SFTP.
A single FTP action may download a maximum of 20MB of data, across all downloaded files.
The user
option is always required.
When connecting to an FTP or FTPS server, authenticate with the password
option.
When connecting to an SFTP server, authenticate using either password
or private_key_pem
, or both. PEM certificates may be given directly in the task code:
Both uploads
and downloads
allow the task author to define file paths. If only the filename is given (e.g. "sample.pdf"
), the file will be resolved in the home directory of the user. If a relative path (e.g. "subdirectory/sample.pdf"
) or absolute path (e.g. "/tmp/sample.pdf"
) is given, it will be respected accordingly.
Each individual file operation (i.e. each upload or download) will be attempted a maximum of 3 times within the FTP/FTPS/SFTP session, retrying if an error occurs during upload or download.
This example action results in (a) an upload to an absolute path, starting from the server root, (b) an upload to a nested directory within the user's home folder, and (c) an upload to a nested directory in another user's home folder (which may fail, depending on filesystem permissions).
Uploads are processed before downloads; it can be useful to test by uploading a file, and then immediately downloading it again:
This task compiles all SKUs with their titles and prices, and uploads it as a CSV every night or on demand.
To use the response from an HTTP action, add a task subscription to .
When developing task code, verify your HTTP action's behavior with (making sure not to share sensitive information with this service).
May be set to a JSON object, mapping filenames to
If the files
option is given, its contents will be evaluated for , and the results will be used to construct a multipart/form-data
upload request, combining generated files with any key-value pairs found in the body
option.
To authenticate a request using and the "Basic" authentication type, use something like this:
We recommend using an HTTPS proxy server (rather than HTTP or SOCKS5) for a secure connection between Mechanic and your proxy. is a good option for this kind of service.
Learn more:
To retrieve a specific header in a task responding to , use something like this:
For all other cases, the body
result value will be an UTF8 string, regardless of the response body's original encoding. To access the response body in its original encoding, use the body_base64
result value, passing it through the Liquid filter if necessary.
As with all runs, HTTP action errors are subject to .
This task prompts the user for text input, and submits it to a public API that returns everything submitted to it. The task then re-invokes itself, using the action to display the response status, content type, and body.
The Files action evaluates its options using , temporarily storing the resulting files and making them available via a randomized Mechanic URL.
This action is most useful in concert with , by which a task may take the resulting file URLs and pass them on to another service. Used by itself, this action can also be useful for quickly testing file generators.
This action accepts a JSON object, whose keys are filenames and whose values are . In this way, many files may be defined and generated by a single Files action.
Learn more:
The of the generated file
It supports various file types and can generate files dynamically using , including text files, PDFs, CSVs, and HTML files. Mechanic interacts with Google Drive via the Google Drive API, using OAuth2 for authentication.
The FTP action can upload and download files via , , or . The files to be uploaded are evaluated using . Downloaded file data is available either as an UTF-8 string, or as a base64-encoded string, and can be used in followup task runs via .
A connecting service like can be used to relay these uploads on to other cloud locations, like Dropbox, Google Drive, and Amazon S3.
Learn more:
An FTP action returns the following data structure, most useful in combination with mechanic/actions/perform (see ):
Note that each uploaded and downloaded file is keyed by the path provided for that file in the action's options. Downloaded file data is available as a UTF-8 string; for binary data that cannot be represented in UTF-8, use the base64-encoded version, possibly in concert with the filter.
If a server is unavailable for testing, consider using , with . This is a (nearly) configuration-free avenue for testing, using my.couchdrop.io for FTP, FTPS, or SFTP.
Alternatively, can be used to create a public tunnel to a local FTP or SSH server. By running ngrok tcp 22
(adjusting for the appropriate local port), ngrok will generate a temporary public host and port that's appropriate for use while testing.
account
string
Required: the Google account email address to authenticate with
uploads
hash
Required: a has specifying files to upload and their contents
mode
String, optional
May be set to "ascii"
; defaults to "binary"
verify
Boolean, optional
May be set to false
to ignore SSL certificate errors
overwrite
boolean
Optional: when true, files with matching names will be overwritten. Defaults to false
[path/filename]
string | hash
protocol
"ftp"
, "ftps"
, or "sftp"
The protocol to use for connection; inferred if omitted
host
String, required
The hostname or IP address of the destination server
port
Number, optional
The server port to connect to
user
String, required
The username for authentication
password
String, optional
The password for authentication
uploads
Hash, optional
downloads
Array, optional
File path strings (relative or absolute) to download
private_key_pem
String, optional
A complete PEM-formatted private key for authentication
verify
Boolean, optional
May be set to true
in combination with "known_hosts"
to validate the host
known_hosts
String, optional
The Flow action sends data to Shopify Flow, arriving as one of four possible Flow triggers.
The Flow action accepts at most one resource option, identifying a specific Shopify resource, and resulting in a resource-specific Flow trigger. If no resource option is provided, Mechanic will use the General trigger.
These resource options only accept fully-numeric resource IDs (i.e. 12345). They do not accept global IDs (i.e. gid://shopify/Customer/12345).
customer_id
"Mechanic sent customer data"
product_id
"Mechanic sent product data"
order_id
"Mechanic sent order data"
(when no resource option is given)
"Mechanic sent general data"
This action also sends user-defined data, with one option available for each of Flow's supported datatypes. These options are always sent to Flow, even if they're omitted from the action definition; when omitted, their values are set to the documented default.
user_boolean
Boolean
false
user_email
Email address
"hey@mechanic.invalid"
user_number
Number
0
user_string
String
""
user_url
URL
"https://mechanic.invalid/"
The Google Sheets action allows you to interact with Google Sheets. It supports creating new spreadsheets, appending data to existing sheets, and exporting spreadsheets in various formats. Mechanic interacts with Google Sheets via the Google Sheets API, using OAuth2 for authentication.
account
string
Required: the Google account email address to authenticate with
operation
string
Required: the operation to perform. One of: "append_rows", "create_spreadsheet", "export_spreadsheet"
spreadsheet_id
string
Required: for append_rows and export_spreadsheet; the ID of the target spreadsheet
title
string
Required: for create_spreadsheet; the title for the new spreadsheet
rows
array
Required: for append_rows and optional for create_spreadsheet; array of arrays containing the data to write
sheet_name
string
Optional: for append_rows; defaults to "Sheet1"
file_type
string
Optional: for export_spreadsheet; the format to export. One of: "xlsx" (default), "csv", "pdf", "html", "ods", "tsv"
folder_path
string
Optional: for create_spreadsheet; the folder path where the spreadsheet should be created (e.g., "reports/2024/monthly")
Adds new rows to an existing spreadsheet.
account
spreadsheet_id
rows
sheet_name (defaults to "Sheet1")
Creates a new spreadsheet, optionally with initial data.
account
title
folder_path (path where spreadsheet should be created)
rows (initial data to populate the spreadsheet)
Exports a spreadsheet in various formats.
account
spreadsheet_id
file_type
xlsx (default)
csv
html
ods
tsv
This action requires connecting a Google account with the appropriate permissions. To connect an account:
Go to the Settings screen
Click Authentication
Follow the Google account connection flow
The action can only access spreadsheets it creates, no other spreadsheets in your drive.
When creating spreadsheets, you can specify a folder path to organize your files:
Use forward slashes to separate folder names (e.g., "reports/2024/monthly")
Folders will be created if they don't exist
Can only access folders created by this integration
Invalid characters not allowed: < > : " / \ | ? *
The action returns different responses based on the operation performed:
Example:
Example:
The plaintext file generator is used implicitly, when a JSON string is given in place of a standard file generator JSON object. The resulting file will contain the content of the string, with no further processing. This makes the plaintext generator suitable for text files, CSV files, TSV files, and any other file format that can be expressed using plain text.
The plaintext generator cannot be invoked explicitly; "plaintext"
cannot be used as a named generator type.
Because this file generator is used implicitly, when a string is given instead of a file generator object, this file generator does not use options.
The Base64 file generator accepts a base64-encoded string, and returns a file containing the decoded value.
This generator is useful when producing images, or other binary content that cannot be represented with a JSON string.
This file generator accepts a base64-encoded string. It does not support any other options.
Important Notice
This action has several usage styles, each with a different set of constraints on action options.
This example shows how the query and variables may be built up separately, and provided to the action using concise tag syntax.
Important Notice
Operation Must be one of "create"
, "update"
, or "delete"
.
Resource specification When creating, use a single string (e.g. "customer"
). When updating or deleting, use an array (e.g. ["customer", 123]
).
An object of attributes Only applies to creating and updating.
This example creates a (minimal) customer record.
This example appends a line to the order note (assuming a task subscription to shopify/orders/create).
This example deletes a product, having a certain ID.
Important Notice
Operation Must be one of "get"
, "post"
, "put"
, or "delete"
This example creates a (minimal) customer record.
This example appends a line to the order note (assuming a task subscription to shopify/orders/create).
This example deletes a product, having a certain ID.
One or more file paths mapped to their content. Paths can include folders (e.g., 'reports/monthly/file.txt'). Content can be either a direct string or a .
An object whose keys are file paths (relative or absolute), and whose values are
An sshd-compatible known_hosts file (, )
This page is about the Mechanic action that sends data to Shopify Flow. For a review of Mechanic's entire integration with Flow, see .
For a detailed review of usage, see .
See this great in the task library.
→
The Shopify action sends requests to the . It supports both REST and GraphQL requests.
Shopify is deprecating the Shopify Admin REST API which the Mechanic REST objects depend on. The first round of deprecations involve the product and variant endpoints. Read about the deprecation and . Use the going forward. The and objects will cease to work on on Feb 1, 2025 due to the changes being made by Shopify. Shopify will phase out the REST API completely over time, you can read more about this .
All of our will be ported to use GraphQL only, which will provide a model for how you can update your custom tasks. You'll be able to update your non-customized library tasks with a click of a button Please see these for migrating your custom tasks to GraphQL.
In Mechanic, writing data to Shopify must happen using an action. While the Shopify action is usually the right choice, the action can also be used for this purpose, by manually configuring authentication headers.
To learn more, see .
This usage style invokes the . In this style, a single GraphQL query string is supplied as the action options. The tag has specific support for this action type, allowing this string to be provided as the contents of an action block.
To prepare complex query inputs, use the Liquid filter.
This usage style invokes the , and supports combining GraphQL queries with . This can be useful for re-using queries with multiple inputs, and is critical when dealing with very large pieces of input. Because GraphQL queries (excluding whitespace) are limited in length to 50k characters, GraphQL variables can be used in cases when large inputs (like Base64-encoded images) need to be submitted.
Shopify is deprecating the Shopify Admin REST API which the Mechanic REST objects depend on. The first round of deprecations involve the product and variant endpoints. Read about the deprecation and . Use the going forward. The and objects will cease to work on on Feb 1, 2025 due to the changes being made by Shopify. Shopify will phase out the REST API completely over time, you can read more about this .
All of our will be ported to use GraphQL only, which will provide a model for how you can update your custom tasks. You'll be able to update your non-customized library tasks with a click of a button Please see these for migrating your custom tasks to GraphQL.
This usage style invokes the . It accepts an array of option values, containing these elements in order:
Shopify is deprecating the Shopify Admin REST API which the Mechanic REST objects depend on. The first round of deprecations involve the product and variant endpoints. Read about the deprecation and . Use the going forward. The and objects will cease to work on on Feb 1, 2025 due to the changes being made by Shopify. Shopify will phase out the REST API completely over time, you can read more about this .
All of our will be ported to use GraphQL only, which will provide a model for how you can update your custom tasks. You'll be able to update your non-customized library tasks with a click of a button Please see these for migrating your custom tasks to GraphQL.
This usage style invokes . It accepts an array of option values, containing these elements in order:
Request path The entire, literal request path to use, including the requested — e.g. "/admin/api/2020-01/orders.json"
A JSON object of attributes In general, this means a wrapper object whose key is named after the current resource type, and whose value is the same set of data that would be used in the style
Option
Description
query
Required; a string containing a GraphQL query
variables
Required; a JSON object mapping variable names to values
The ZIP file generator accepts an options object, specifying a set of files (themselves defined using file generators) to be compressed into a single ZIP file. The resulting ZIP file may optionally be password-protected.
Option
Description
files
Required; an object specifying a set of filenames mapped to file generators
password
Optional; a string specifying a password to use for encrypting the file
The task runs that arise from a scheduled event run will not be established until the event run is performed. (This does not apply if the task_ids
option is used, which determines ahead of time which tasks may be run in response to the new event.) This means that changes to the set of enabled tasks can have an impact on what tasks are actually run, in response to a scheduled event run.
Event runs generated in response to scheduler events are always adjusted for the store's local time.
Subscription offsets are a property of the task, and are applied by the task run – not the event run. This means that the subscribed-to event must be created and run before the subscription offset is calculated and applied.
If a task is disabled or deleted at the time a task run comes due, the task run will still perform at the scheduled time, but will fail instantly.
When performed, a run has a result. Depending on the type of run, this result may define additional runs to be performed after it concludes.
Event runs, when performed, may result in a set of enqueued task runs.
Task runs, when performed, may result in a set of enqueued action runs.
At the moment a run is performed, it loads in all related data (which may include the related store, or the related event, or the related task).
A normal flow in Mechanic looks like this:
Each action run is performed. During this phase, Mechanic executes each action, given the options that were provided for it by the task run's result.
Understanding this sequence of events is important. Task runs do not come into existence until the event run has been performed, and action runs are only performed after their task run has fully concluded.
Critically, this means that tasks do not have direct access to the effects of the actions they generate. Actions are performed later in the sequence, and their effects will only be seen by subsequent task runs.
In general, given a mix of event, task, and action runs that are all due, Mechanic will perform due action runs first, then due task runs, and finally due event runs.
Unscheduled
The run has not been assigned a time to be performed
Scheduled
Scheduled to be performed, but that time has not yet arrived
Due
The run is ready to be performed, and is waiting for a runner
Started
The run is being performed
Failed
The run has been performed, and an error has been recorded
Succeeded
The run has been performed, without errors
File generator
Purpose
Decodes base64-encoded content, returning a file containing the results
Renders HTML using a full Webkit browser, returning a PDF file of the results
Allows defining file contents using a plain string, instead of a file generator object
Downloads and returns a file
Accepts its own set of file generators, returning a ZIP archive of the results
Generated files may each be a maximum of 20MB.
In practice, file generator objects are given as values in a larger JSON object, in which filenames are mapped to file generators.
These are the Mechanic actions that support file generators.
Action
Usage
Uses file generators to prepare email attachments
Uses file generators to prepare temporary URLs, from which the generated files can be downloaded
Uses file generators to prepare FTP uploads
Adds generated files to a multipart/form-data HTTP request
Shopify's "update" webhooks do not contain information about what piece of data has changed. (For example, a product update webhook does not specify what attribute of the product has changed.) For this reason, it's not possible to subscribe to changes in specific resource attributes (like product SKUs, or order tags).
Shopify does not offer a strict guarantee on webhook delivery. In rare cases (and usually in high-volume situations), we've observed Shopify fail to send a webhook.
Your app shouldn't rely solely on receiving data from Shopify webhooks. Because webhook delivery isn't always guaranteed, you should implement reconciliation jobs to periodically fetch data from Shopify.
This applies to Mechanic tasks as well (which are, essentially, tiny apps).
For tasks that respond to events on Shopify resources, we recommend the following, using shopify/orders/create as an example:
Update the task code to mark orders as having been processed. This could take the form of an order tag (e.g. "processed-by-task-xyz"), or a metafield. Additionally, ensure that this code skips orders that are already marked as processed.
Mechanic supports several methods of reading data. The following articles discuss usage, and when each technique might (or might not) be appropriate:
To protect the health of the system and to ensure performance for every store on the platform, Mechanic have several concurrency limits, defining the conditions in which Mechanic will perform runs simultaneously.
Each store's Mechanic account has a fixed run queue size. This limit controls how many runs Mechanic will perform simultaneously for your store. With a limit of 5, this could mean 5 events, or 5 tasks, or 1 event and 2 tasks and 2 actions, or any other combination of runs. Additional runs will be performed as the preceding runs complete.
In some cases, a run that has already been performed may be performed again, using a retry.
When a run is retried, its previous result is permanently discarded. Because of this, runs that already have a meaningful result (i.e. an event run that gave rise to task runs, or a task run that generated actions, or an action run that succeeded) cannot be retried.
Runs are given automatic retries when a non-permanent error is encountered. In some cases, Mechanic permits manual retries for runs, allowing users to reset a run's result and perform the run again.
Retried action runs will always use their original action options, as dictated by the task run that generated them. Action runs are entirely unaffected by updates to their task.
Mechanic will automatically retry these runs up to 4 times, for a total of 5 attempts. Retries are subject to a variable backoff delay, of approximately 0:30, 1:16, 2:32, and 5:08 respectively, for each of the 4 retries.
Some task runs may be manually retried, via the Mechanic user interface.
Task runs may be retried...
... if the task run itself failed (due to a Liquid error, an API error while reading data, or something else)
... or, if the task run did not generate any actions
Only failed action runs may be retried.
For tasks, the simplest way to manage this is by using subscription delays, offsetting the time at which each task is run. For example, if you have two tasks that subscribe to shopify/customers/create, you might adjust one so that it it subscribes to shopify/customers/create+10.minutes instead. This way, your first task has a chance to execute and run before the other.
This is not a perfect solution: naturally, if the first task takes more than 10 minutes to run, there will still be overlap. So, Mechanic makes
Begin by making a list of the tasks for which you need to guarantee run order, sorted by the desired run order. For these purposes, all of these tasks should subscribe to the same event topic.
Beginning with the task that should run first, (a) enable "Perform action runs in sequence", and (b) add an "event" action at the very end of your task script. The intent here is for this action to kick off a unique event topic that the second task should the subscribe to.
Having added that "event" action, update the second task so that it subscribes to your new event topic, instead of the original event topic. If there is a third task that should follow this one, repeat step 2 for this task as well, in preparation for kicking off the third task.
Repeat until you reach the final task in your list. This task does not need an "event" action at its conclusion; it only needs to have its subscription updated to listen for the penultimate task's generated event.
Downloaded files may be a maximum of 20 megabytes, even when used within other file generators (like ).
and runs may be scheduled to perform in the future. They will not have any effect until they are performed. This means that their eventual performance may be impacted by changes to a store's Mechanic account, prior to the scheduled performance time.
Event runs may be scheduled using the action, using its run_at
option to define the time at which the run should be performed.
Mechanic supports several (such as mechanic/scheduler/hourly), allowing tasks to be automatically invoked by the platform on a regular repeating interval.
Task runs may be scheduled using , in which a task states that it wishes to run later (by some amount of time) than the event that triggers it.
To achieve precise scheduling (e.g. "run on December 16th at 2:30pm"), or to accomplish scheduling for an interval not supported by Mechanic's scheduler topics, use the action to schedule an event run at any chosen time, with a . Make sure that the desired task is subscribed to the same custom topic, and consider using the Event action's task_id
option to specify that only the desired task is allowed to respond to the new event.
Task runs that are scheduled for the future will always use a task's latest configuration, including the task's , , and .
, , and are all processed using queues, in which a piece of work is enqueued, and performed in its turn. Each piece of work is called a run. Thus, Mechanic performs work using event runs, task runs, and action runs.
Action runs, when performed, have behaviors that vary by .
If the originating task , each action run will spawn a new event containing that action's results. This new event will be processed in an enqueued event run, creating an opportunity for the task to respond to the action's results.
Most runs are scheduled to be performed immediately. Some runs may be for the future. Some runs may be , once performed.
An event is created – possibly by a , or by a , by the , or by an .
An event run is created, and performed. During this phase, Mechanic scans the store's tasks to see which ones are relevant for the current event, by checking the subscriptions on file for each task. For each task that Mechanic discovers for the event, a task run is created. (If the task subscription involved an , as in mechanic/scheduler/daily+2.hours, the task run will be set to wait for that amount of time.) The result of the event run is this set of task runs.
Each task run is performed. During this phase, Mechanic takes each task's , and renders it using the associated event. The result of the task run is the set of JSON rendered by the task's Liquid code. Each action object is used to create an action run.
If Shopify's rate limit for either the GraphQL or REST Admin API has been reached, Mechanic will skip over task runs and over runs, until both rate limits have been recovered. In these cases, Mechanic may choose to perform due runs of a lower priority, while it waits for the Shopify API rate limits to recover sufficiently to perform the higher priority runs.
File generators are invoked by to create new files, using options provided by the action, and handing the resulting file back to the action for further use. In this way, can make choices about what files to generate, and what to do with the results.
Mechanic allows action run results to be fed back into the system (). File generators usually end up having their resulting files represented in the action run results, and base64-encoding 20mb of binary data makes for a lot of JSON. We have to draw a line somewhere.
File generator objects, like , are plain JSON objects each having a single key, and a single value. The object key specifies which file generator is to be invoked; the object value contains the options used for that generator.
The file generator is invoked implicitly by supplying a string, instead of supplying the usual file generator object.
In the following example, a action is defined, mapping filenames ("invoice.pdf"
, "external.jpg"
, and plain.txt
) to file generators (a PDF generator, a URL generator, and – implicitly – a plaintext generator). Note how the file generator invocation varies, based on the specific file generator in play.
The PDF file generator accepts an object containing an HTML string, and uses to render it as a PDF document. Pdfcrowd employs the for HTML rendering, which uses the same foundation as Google Chrome. This allows Mechanic to generate PDFs with modern CSS and JavaScript features, including chart libraries and web fonts.
For a complete list of options, see .
If it's unclear why something isn't rendering properly, start by testing the HTML being used in a Pdfcrowd playground, at . If the issue is reproducible in the playground, use the "Help" button along the left-hand sidebar to get the ID of your specific playground, and instructions for contacting Pdfcrowd support with the details of your test.
Shopify uses webhooks to notify apps like Mechanic about new activity. Mechanic supports every type of Shopify webhook in its set of . By setting up to these topics, a task may respond to any supported type of Shopify activity.
Note that Shopify does not strictly guarantee webhook delivery. See for more on this subject.
If a task needs to react to a specific attribute change, the task must scan for and "remember" the original value of that attribute, so as to compare incoming updates with that remembered value. A task could use the action to store these values in the Mechanic cache, or it could use the action to save the remembered value in a metafield.
For an example implementation, see the task.
Quoting from for this scenario:
Add a , like mechanic/scheduler/15min. Then, update the task code so that these scheduled runs are used to scan for and process new orders in the last 15 minutes that have not yet been processed. This is the reconciliation step, ensuring that all new orders are ultimately processed, one way or another.
In general, Mechanic will process as many simultaneously as possible. This means that multiple tasks subscribing to the same event topic are very likely to execute simultaneously, when such an event occurs.
In most cases, an inefficient run queue is best addressed by combining or reorganizing tasks, improving (converting REST requests to GraphQL is often helpful), or by making judicious use of .
Related FAQ:
Use GraphQL to query Shopify, to keep your data usage efficient. (To learn more, see .)
For options for ordering execution of runs, see .
Retried event runs will always reflect Mechanic's current configuration, including any .
Retried task runs will always use a task's latest configuration, including the task's , , and .
When non-permanent errors are encountered, Mechanic will automatically retry a run. For , this might be a connection error. For , this might be a temporary outage with our email provider.
During task development, it can be useful to set up a task to only render . A task run which only rendered log objects can be retried, and this ability to retry can be convenient when rapidly iterating on task code.
In general, Mechanic's system does not guarantee the execution order for runs that have been created at the same time (see ). This applies to all kinds of runs: events, tasks, and actions.
Each task has an advanced option called "". When this is enabled, all generated actions for a given task run will be executed precisely in order.
The best tool to leverage here is the , coupled with action sequences (see above).
One more tool is worth mentioning: tasks may subscribe to mechanic/actions/perform to be re-triggered when each of their own actions are performed. For more on this strategy, see .
If you're working with multiple pages of data, you might use set up a forloop, using a cursor to retrieve page after page:
... you want to make things more efficient. GraphQL is fantastic for being really precise about what data you want, which makes your tasks run in less time: no more looping through collections to find your data, and no more downloading data you don't require.
... it's easier and more readable to use Liquid objects, unless performance becomes an issue. Ultimately, the most important thing is that your task works well tomorrow – and that includes making sure that whoever works on it next understands what you're doing. If that means using a quick-and-simple Liquid lookup over a moderately-more-complex GraphQL lookup, go for it.
... you find yourself staring at nested loops. Looping through all orders is one thing – it's quite another to loop through pages of orders and loop through pages of line items within each order. For those scenarios, whenever possible, use a bulk operation.
Use these access points within the Shopify admin to send resources like orders and customers to Mechanic for processing.
For supported resources, you'll find "Send to Mechanic" links within the Shopify admin. These links point to a Mechanic app URL that translates selected Shopify resources into Mechanic events for on-demand processing. Depending on the user's resource and task selections, their submission may result in one or more new events. Event data consists of the latest stable REST Admin API representation of the selected resource(s).
Important: Starting Feb 1, 2025, the product
and variant
resource types will no longer include full REST Admin API data in these events. Instead, only resource IDs (id
and admin_graphql_api_id
) will be included, due to Shopify REST API deprecations. If you need additional product or variant details (e.g. title, vendor, etc.), you must fetch them via Shopify's GraphQL API.
customer
mechanic/user/customer
mechanic/user/customers
order
mechanic/user/order
mechanic/user/orders
draft_order
mechanic/user/draft_order
mechanic/user/draft_orders
product
mechanic/user/product
mechanic/user/products
variant
mechanic/user/variant
mechanic/user/variants
collection
mechanic/user/collection
Note: After Feb 1, 2025, product
and variant
events will only include resource IDs:
Mechanic distinguishes between "individual" and "batch" modes to enable a greater variety of possible workflows. Some tasks may benefit from having knowledge of all selected resources at the same time within the same task run, while some tasks may be more suited to receiving a single resource at a time.
For example, tasks that are created to print deliberately-sorted pick lists might benefit from batch mode, whereas tasks aimed at refunding specific orders might benefit from individual mode.
For supported Shopify resources, the "Send to Mechanic" action link can be found in the "More actions" menu. Click this link to route the currently-viewed Shopify resource to Mechanic.
After selecting a processing mode, select from the available compatible tasks – i.e. from enabled tasks that subscribe to a relevant event topic. You can send this event to one or more tasks that subscribe to the correct event topic.
Note: For product
and variant
, as of Feb 1, 2025, only an id
and admin_graphql_api_id
are provided. Additional fields (e.g. product.title
) must be fetched from Shopify GraphQL.
By contrast, a mechanic/user/orders event will make available a variable called orders
, which contains an array of Order objects.
Tasks that already subscribe to related Shopify event topics lend themselves well to invocation via Shopify admin action links. For example, a task subscribing to shopify/orders/create may be adapted to these action links by adding mechanic/user/order to the task's subscriptions.
Because this task straightforwardly references the order
environment variable, this task is a good candidate for a subscription to mechanic/user/order. Once modified in that way, the task will be able to send PDF invoices on demand, whenever a user sends orders to the task via a "Send to Mechanic" link.
Mechanic supports Shopify's bulk operations GraphQL API, allows developers to submit a query to Shopify for asynchronous processing, and making the results available to the task once complete.
This approach dodges the issues inherent in synchronous methods of reading data (like GraphQL via the shopify filter, or REST via Liquid objects). Unlike these methods, the bulk operations API does not exhaust Shopify API limit for your Mechanic account, and therefore does not slow down other tasks. It also does not require any special logic for pagination, since Shopify handles all data collection.
Shopify only permits apps to run a single bulk operation at a time, per store. Actions that create another bulk operation, while one is already running, will return an error.
The set of objects returned by the bulk operation is made available as bulkOperation.objects
, allowing you to scan returned data immediately, using an expression like {% for object in bulkOperation.objects %}
.
In most cases, every object that has an ID will appear as a separate object, in the same set of objects. For example, if a product and five variants are returned, there will be six objects returned – the variants are not nested inside of the product object.
The JSON objects returned from bulk operation queries each include a "__parentId"
attribute for connected objects, containing the parent object's ID. To make managing task scripts easier, Mechanic allows you to simply call {{ object.__parent }}
to look up an object's parent.
... your task needs to collect and process a lot of data. Tasks responding to bulk operations operate with a higher memory allowance than other tasks, decreasing the chances of your task being terminated for memory exhaustion.
... paginating for data would be too complicated. Pagination in GraphQL can be tricky when using nested resources.
Shopify variables in Mechanic do not necessarily contain the same attributes as Liquid variables used in Shopify (in places like themes or email templates) – even if they share the same name.
In Mechanic, Shopify variables always contain data from Shopify events, which are delivered to Mechanic via webhook. This means that Shopify variables always have the same data structure as Shopify webhooks, corresponding to Shopify's REST representation for this data.
Tasks may use the to convert GraphQL query strings into simple result objects, by sending the query to the . The easiest way to build these queries is via the , which allows queries to be interactively constructed.
The shopify filter does not support running mutations (i.e. writing Shopify data via GraphQL). To run mutations, use the .
The accepts a GraphQL query string, and returns everything back from Shopify's GraphQL admin API. This means that reading back GraphQL data is as easy as this:
The also supports GraphQL variables!
You'll note that this code includes stub data when running during a preview event. This technique is extremely useful for generating , by allowing you to exercise your entire task script.
The hardest part of using GraphQL in Mechanic is writing the query itself. :) For help with this, we recommend installing . It provides an environment where, using auto-complete and built-in documentation, you can rapidly build the right query for your task.
Note: GraphQL queries (excluding whitespace) are limited to 50,000 characters. That's a hard limit, enforced on Shopify's end – if you bump up against it, you'll need to adjust your query strategy to always stay under that limit. If you're saving large values to a metafield, for example, consider separating those values using GraphQL variables, keeping the query itself trim. Learn more about this scenario using the , or with the .
The allows developers to submit any request to the Shopify Admin API. By , the data returned by Shopify can be retrieved, and re-used by the calling task.
This approach should (probably) only be used as a last resort, when Mechanic's other methods of do not cover the scenario.
Tasks can qualify for this style of on-demand Shopify resource processing by subscribing to event topics like mechanic/user/{resource} (singular) for individual processing, and mechanic/user/{resources} (plural) for batch processing. See below for a complete table of resources and event topics.
Shopify admin action links are a form of , and as such equivalent URLs may be constructed manually using known resource IDs. For example, an admin order notification email could be written to include such a link, allowing the email recipient to send the relevant order to Mechanic.
This mode creates an event for each selected Shopify resource, resulting in as many events as there were selected resources. Tasks subscribing to an individual mode event topic (e.g. mechanic/user/order or mechanic/user/customer) may use an named after the singularized resource name, e.g. order
or customer
.
This mode creates one (1) event whose data consists of an array holding all selected Shopify resources, up to a maximum of 50 resources total. No matter how many resources were selected, only one event is created. Tasks subscribing to a batch mode event topic (e.g. mechanic/user/orders or mechanic/user/customers) may use an named after the pluralized resource name, e.g. orders
or customers
.
For supported Shopify resources, the "Send to Mechanic" link is also available as a , supporting selections of up to 50 resources at once. Find the "Send to Mechanic" link after in the menu of additional actions, in the floating action list that appears after selecting one or more resources.
Shopify admin action links are a form of , following this pattern:
These URLs may be manually constructed, using resource type parameter values drawn from the table above, and using integer REST resource IDs.
Using a Shopify admin action link brings the user to the page shown below, in which selected resources are shown for preview, and a choice of is offered.
To qualify a task to receive these events, subscribe to an event topic from the table above.
For these events, Mechanic makes available an named after the third term in the event topic. For example, a mechanic/user/order event will make available a variable called order
, which contains an with data pulled from the Shopify Admin REST API.
Event data for these topics is often very similar to data from , but there are occasionally differences. For example, shopify/orders/* events do not include customer data. By contrast, customer data is included in the Shopify Admin REST API representation for the Order resource. Therefore, event data for mechanic/user/order and mechanic/user/orders events do contain information about the customer, unlike shopify/orders events.
Additional changes may be necessary. Always test thoroughly, and follow .
The task, from the Mechanic task library, is well-suited to this kind of adaptation. To illustrate, here is the portion of the task code that addresses the order itself:
This article reviews Mechanic's support for bulk operations. If this feature is new to you, start by reading Shopify's tutorial on the bulk operations API:
This area deserves improvement! To discuss the future of this behavior, visit the related feature request:
Use the action to execute a bulkOperationRunQuery mutation (see ). Mechanic will detect this mutation, and will begin monitoring the bulk operation in progress.
Add a to mechanic/shopify/bulk_operation.
Once Mechanic detects that the bulk operation has been completed, the platform will automatically re-invoked the same task with an event having the topic "mechanic/shopify/bulk_operation", containing the bulk operation's data, when the bulk operation is complete. (As with , Mechanic will only invoke the current task when the bulk operation completes; no other task will be notified.)
When processing a mechanic/shopify/bulk_operation event, the task will have access to an called bulkOperation
, containing all attributes of the bulk operation ().
... you only need a little bit of data. Use the filter instead.
... you're responding to a Shopify event, and the data you need comes along with the event data. Use instead.
There is a single correct answer for writing data to Shopify: the action. :)
Mechanic-flavored Liquid comes with a complement of , each of which is tied to a resource in the . Many objects support access to related objects via lookups (e.g. {{ shop.customers[customer_id].orders.first }}
); in this way, the REST API can be traversed by resource.
Shopify is deprecating some of the Shopify Admin REST API. The first round of deprecations involve the product and variant endpoints. Read the deprecation notice .
Our recommendation is to use going forward. The and objects will cease to work on on Feb 1, 2025 due to the changes being made by Shopify. It appears that Shopify will gradually phase out the REST API over time.
All of our will be ported to use GraphQL only, which will provide a model for how you can update your custom tasks. You'll be able to update your non-customized library tasks with a click of a button
Access to these Liquid objects varies, based on the context in which Liquid is rendered. For example, a task that subscribes to shopify/customers/create will have access to the object in its code, via a variable called customer
. To learn more about how these objects are made available to task code, see .
For example, while Shopify themes support {{ customer.name }}
, Mechanic does not (because does not contain a "name" property). On the other hand, Mechanic supports {{ customer.created_at }}
, while Shopify themes do not.
Each task is given a set of to work with, out of the box. Mechanic's task code editor will tell you which ones are available. For example, for a task responding to a shopify/orders/
event, you might see this:
The , , , and objects are always available for tasks; the object (as in this example) contains the order to which the current event relates.
Mechanic has native awareness of Shopify's Admin API rate limit, and will accordingly manage the execution of operations that require access to the Shopify API. Mechanic users do not need to manage the API rate limit themselves.
If the rate limit is reached during a run's performance, Mechanic will automatically wait and retry any affected API queries until they succeed, up to a certain number of retries. If the API rate limit does not recover in a reasonable amount of time, Mechanic will raise a permanent error for the run.
This setting can be found in the Mechanic account settings, in the Permissions area. (This setting is only shown for Shopify Plus accounts.) Before adding your API token, you must ensure that the private app has every access scope that Mechanic requires. A list of current required access scopes is provided just below the token field.
Once configured, this custom API token will be used for all user-configured Shopify operations, wherever supported. (It will not be used when querying for publications, since this resource is only accessible to public apps like Mechanic.)
Each Mechanic task has an individually-configured Shopify API version, defaulting to the latest stable version at the time of the task's creation. A task's version will apply to all Shopify API calls generated by its task code, in addition to all calls performed by that task's actions.
Each stable Shopify version is supported for one year. 30 days before a version ends support, tasks on that version will be silently upgraded to the next stable version. As a consequence, versions that are unsupported (or are within 30 days of no longer being supported) are not available in Mechanic.
Every quarter, Shopify releases a new version of the Admin API, and simultaneously removes the oldest version of the admin API. (Subsequent calls to removed APIs will be responded to by the oldest still-supported version.)
As Shopify prepares to pull support for specific API calls, deprecations are announced, and are communicated in API responses.
If support for a task's Shopify API version will be pulled soon, its deprecations will be shown above the main task list.
Deprecation details are available in the advanced task editor, in the Runtime tab.
Deprecation warnings can be dismissed by doing one of the following:
Selecting a new Shopify API version for the task
Updating the task script
Disabling the task
Deleting the task
If the rate limit has been reached, any due task runs or runs will wait to be enqueued until the rate limit has recovered.
Learn more about the Admin API rate limit from Shopify, at .
When querying for data within a task, use whenever possible, rather than using . GraphQL is much more resource-efficient, and usually results in greater operational throughput.
When working with large volumes of data, use a . This way, Shopify bears the burden of collecting all relevant data, without in any way playing against the Shopify API rate limit for Mechanic.
Keep an eye on tasks that are running at the same time, competing for resources. The Shopify API rate limit is shared across each store's entire Mechanic account, which means that simultaneously-running tasks may be in competition for Shopify API usage. Adjustments to task timing (possibly using ) can be useful, when making sure that tasks aren't competing. And, in some cases, it may be useful to decrease the overall for a Mechanic account, by emailing .
In high-volume scenarios for Shopify Plus accounts, Mechanic's performance can be improved by creating , having the same permissions that you've granted to Mechanic. Because this private app represents your explicit control and intent, it usually comes with a higher API rate limit. (And, in some cases, Shopify can grant this custom app a higher API usage limit, upon request.) By providing Mechanic with this custom app's Shopify Admin API access token, you can extend this higher limit to Mechanic.
This feature is also useful for accessing Plus-only APIs, which are only available to custom Shopify apps. Notably, this includes gift cards (using ).
The Shopify API supports versioning for their REST and GraphQL admin APIs. (Learn more: .)
{% error "Oh no!" %}
tag.{% action "echo", __error: "Oh no!" %}
tag.