Shopify Flow & GraphQL: Master Automated Draft Order Deletion

Hey everyone,

It’s always great to see our community come together to solve tricky problems, and I recently stumbled upon a fantastic thread that really highlights the power of Shopify Flow and GraphQL when you know how to wield them. This discussion, kicked off by luxepalmer, was all about automating the cleanup of those pesky, forgotten draft orders. You know the ones – customers start them, maybe even get an abandoned cart email, but then they just sit there, cluttering up your admin.

The Challenge: Deleting Stale Draft Orders with Shopify Flow

luxepalmer had a smart setup already: a Shopify Flow that tags draft orders as “Stale” after 48 hours. The next logical step? Automatically deleting them. But when they tried to add a “Send Admin API request” action to delete these "Stale" drafts, they hit a snag. The error message was a bit cryptic: "Exception: Mutation had errors: "Variable $input of type DraftOrderDeleteInput! was provided invalid value"".

Here's what luxepalmer's initial setup looked like, aiming to get rid of those tagged drafts:

The screenshot luxepalmer shared showed the Flow was correctly identifying the "Stale" draft orders, but the deletion step was the sticking point. This is a common hurdle when you're diving into the GraphQL Admin API for the first time – understanding the exact data format it expects.

The Community Steps In: Understanding GraphQL IDs

This is where the collective wisdom of the community really shone. ShopIntegrations quickly pinpointed the problem: the API expects a very specific GraphQL ID format, like gid://shopify/DraftOrder/12345, not just the plain numeric ID. If your JSON variables block is malformed, or you're just passing the numeric ID, you'll get that "invalid value" error.

tim_1 echoed this crucial point, even sharing the official Shopify API documentation for draftOrderDelete to show the expected input structure. This documentation is always your best friend when dealing with API calls:

draftOrderDelete - GraphQL Admin API Documentation
Shopify API Documentation Screenshot
Deletes a draft order.

As tim_1 pointed out, Flow usually gets full IDs, but it's good to know the difference between the full GraphQL ID and the numeric legacyResourceId:

{
  "id": "gid://shopify/DraftOrder/162487337014",
  "legacyResourceId": "162487337014"
}

If, for some reason, your Flow wasn't providing the full gid, you might need to construct it like this, as tim_1 suggested:

{
  "input": {
    "id": "gid://shopify/DraftOrder/{{- getDraftOrderDataForeachitem.id -}}"
  }
}

Here's what luxepalmer was seeing when the error occurred:

The Winning Solution: Using draftOrder.adminGraphqlApiId Directly

The key takeaway, and the solution that ultimately worked for luxepalmer, was provided by ShopIntegrations. Instead of trying to construct the ID or pass it as a separate variable, you can directly embed the correct GraphQL ID using Liquid in your mutation query. This is super elegant because Shopify Flow automatically provides the draftOrder object with its adminGraphqlApiId when a draft order is the subject of your Flow. This adminGraphqlApiId is exactly the gid://shopify/DraftOrder/12345 format the API is looking for.

Here's the exact GraphQL mutation code that ShopIntegrations suggested, which luxepalmer confirmed resolved the issue:

graphql
mutation {
  draftOrderDelete(input: {id: "{{ draftOrder.adminGraphqlApiId }}"}) {
    deletedId
    userErrors {
      message
    }
  }
}

Maximus3 also provided a helpful approach, suggesting to use "id": "{{ getDraftOrderDataForeachitem.id }}" if you're fetching draft order data in a prior step. This also works well, provided the getDraftOrderDataForeachitem.id is indeed outputting the full gid and not just the numeric legacyId. The adminGraphqlApiId property is generally the most robust and direct route for this specific scenario.

Here are the steps Maximus3 shared for setting up the API call:

{
  "input": {
    "id": "{{ getDraftOrderDataForeachitem.id }}"
  }
}

Step-by-Step: Setting Up Your Shopify Flow to Delete Stale Draft Orders

Ready to implement this yourself? Here’s how you can set up a Shopify Flow to automatically clean up those stale draft orders using the most robust method from the community discussion:

  1. Start Your Flow: In your Shopify admin, go to Flow and click Create workflow.
  2. Choose a Trigger: Select a trigger that makes sense for your "Stale" tag. If you have a separate flow tagging them, a good trigger here would be Draft order tagged.
  3. Add a Condition: To ensure you're only deleting the correct drafts, add a condition. For example:
    • Draft order tag is equal to Stale
  4. Add an Action: This is the crucial part. Click Add action and choose Send Admin API request.
  5. Configure the API Request:
    • API client: Select Shopify Admin GraphQL.
    • GraphQL query: Paste the exact mutation provided by ShopIntegrations into the query box.
    • graphql
      mutation {
        draftOrderDelete(input: {id: "{{ draftOrder.adminGraphqlApiId }}"}) {
          deletedId
          userErrors {
            message
          }
        }
      }
      
    • You don't need a separate "Variables" block with this method, as the Liquid directly embeds the ID into the query.
  6. Test and Activate: Save your Flow and give it a test run with a dummy draft order (or one you don't mind deleting) to ensure it's working as expected before activating it fully. If you run into issues, remember tim_1's advice to check your Flow logs for the exact ID format being passed.

And that's it! Once activated, your Flow will automatically pick up any draft order tagged as "Stale" and send the correct GraphQL API request to delete it. This not only keeps your admin cleaner but also helps you focus on active orders and customer interactions, without getting bogged down by old, unfulfilled drafts. It's a fantastic example of how a small tweak in understanding API requirements, combined with the power of Shopify Flow, can lead to significant operational improvements. Big thanks to luxepalmer, ShopIntegrations, Maximus3, and tim_1 for sharing their insights and helping the community solve this one!

Share:

Use cases

Explore use cases

Agencies, store owners, enterprise — find the migration path that fits.

Explore use cases