Developer API and MCP

Almost everything you can do in the app, you can also do from your own code or from an AI assistant. Workflow Suite has a REST API and an MCP server. Both are set up on the Developer page, and both use the same API keys.

REST API base URL https://shopify.workflow-suite.app/api/v1
MCP server (Streamable HTTP) https://shopify.workflow-suite.app/api/mcp

API keys and levels

On Developer, tab API keys, select Create API key, name it and pick the Access level. The levels build on each other:

Level Allows
Read only List and read workflows, runs, triggers, actions, templates, permissions, plan, secrets by name, files and key-value keys
Read & write Also create, update, delete, turn on and off, test and simulate as a preview, manage secrets, files, key-value entries, senders and alert settings, run functions
Read, write & execute Also everything that runs a workflow for real: run, re-run, a test or simulation with dryRun: false, and a test email

The execute level exists because a leaked write key should be able to misconfigure, but not to change orders or send email in your name. Give each system its own key with the lowest level it needs.

The full key starts with bwk_ and is shown once, at creation. Keys are stored hashed and cannot be shown again. Revoke a key at any time on the same page.

Send the key as a Bearer token:

Authorization: Bearer bwk_your_key_here
curl https://shopify.workflow-suite.app/api/v1/me \
  -H "Authorization: Bearer bwk_your_key_here"
{ "authenticated": true, "shop": "your-store.myshopify.com", "level": "WRITE" }

The endpoints by area

The Developer page lists every endpoint with the level it needs, and GET /api/v1 returns the same list as JSON. In short:

Area Paths What you can do
Workflows /workflows, /workflows/:id and below List, create, read, update, delete, enable, disable, duplicate, upgrade, versions and restore, requirements, webhook-url
Check and try /workflows/validate, /workflows/:id/test, /simulate, /test-step Validate a definition without storing it; test or simulate, a preview by default
Run /workflows/:id/run, /workflow-runs/:id/rerun Start a real run (execute level)
Runs /workflow-runs, /workflow-runs/:id, /cancel, /workflow-stats, /workflows/stats Run history, one run with its steps, cancel a queued or waiting run, numbers
Catalogs /workflow-triggers, /workflow-actions, /workflow-templates, /shopify-mutations, /shopify-queries, /trigger-options Everything a definition can be built from, with samples and ready steps
Store setup /permissions, /secrets, /plan, /alerts, /email-connections, /email-log Read permissions, manage secrets and SMTP senders, read the plan, change alert switches
Data /kv, /kv/entry, /kv/increment, /files, /files/entry, /files/content The key-value store and Files
Functions /functions, /functions/test, /runs, /templates Saved functions, the instant test, function runs
POST/api/v1/workflows

Create a workflow

Needs a read & write key. The workflow is created turned off. The definition names its first step in entry, and every step names its successor in next (a condition uses then and else). Validate it first with POST /workflows/validate, which stores nothing and lists problems, missing permissions and the secrets it names.

Request

{
  "name": "Tag high-value orders",
  "definition": {
    "version": 1,
    "trigger": { "topic": "orders/create" },
    "entry": "is_high",
    "nodes": [
      {
        "id": "is_high",
        "type": "condition",
        "match": "all",
        "rules": [{ "path": "event.payload.total_price", "op": "gte", "value": 500 }],
        "then": "tag",
        "else": null
      },
      {
        "id": "tag",
        "type": "action",
        "actionId": "order-add-tags",
        "inputs": {
          "resourceId": "{{ event.payload.admin_graphql_api_id }}",
          "tags": "high-value"
        },
        "next": null
      }
    ]
  }
}

Response

{
  "workflow": {
    "id": "...",
    "name": "Tag high-value orders",
    "enabled": false,
    "definition": { "...": "..." }
  }
}
POST/api/v1/workflows/:id/simulate

Simulate a workflow with your own event

Needs a read & write key for a preview. Runs the saved definition, or a definition you post, against your event and returns the path taken and every step's result. dryRun defaults to true: reads and conditions run, changes are previewed. A literal dryRun false runs every step for real and needs an execute key. For a change trigger, send changes next to payload. A posted definition is never saved.

Request

{
  "event": {
    "payload": { "admin_graphql_api_id": "gid://shopify/Order/1", "total_price": "749.00" }
  },
  "dryRun": true
}

Response

{
  "simulation": {
    "runId": "...",
    "dryRun": true,
    "status": "COMPLETED",
    "piiMasked": true,
    "definition": "saved",
    "path": [
      { "nodeId": "is_high", "type": "condition", "status": "SUCCESS", "branch": "then" },
      { "nodeId": "tag", "type": "action", "status": "SUCCESS" }
    ],
    "steps": [ "..." ]
  }
}
POST/api/v1/workflows/:id/run

Run a workflow for real

Needs an execute key. Starts a real run: it changes your store, counts against your plan and alerts on failure, exactly like Run now in the editor. The answer is 202 with the run id; read the result with GET /workflow-runs/:id. Limited to 60 calls per hour per key.

Request

{
  "payload": { "vendor": "Acme" }
}

Response

{
  "runId": "..."
}
PUT/api/v1/files/entry

Store a file

Needs a read & write key. Stores a file in Files, up to 3.5 MB per request: text as it is, anything else as base64. Larger files arrive through the Download file and File transfer steps. Read it back with GET /files/entry?key= (metadata, and the text of a small text file) or GET /files/content?key= (the file itself).

Request

{
  "key": "imports/stock.csv",
  "text": "sku,quantity\nABC,12\n",
  "contentType": "text/csv"
}

What the API never returns

  • No secret and no credential: a secret's value, an SMTP login, an API key, your store's access token. Lists say hasValue or hasPassword instead.
  • The incoming-webhook URL holds a secret. Read keys only see hasWebhookUrl; GET /workflows/:id/webhook-url needs a write key.
  • Run data is masked for personal data. A run's event, its step results and error texts pass through a mask that recognises typical fields and patterns: names, email addresses, phone numbers, addresses, card numbers, tokens. Lists carry no payloads at all.
  • Key-value values and file contents are your own data and are returned as stored, not masked.

What stays in the app only, and why

In the app only Why
Granting or revoking a permission Shopify's own consent dialog needs a person in the Shopify admin. GET /permissions returns what is missing and the admin URL where you grant it
Connecting a Google or Microsoft 365 sender A sign-in in the browser. These senders are not available yet in any case; SMTP senders can be created over the API
Adding an alert recipient or a phone number Each needs a confirmation by its owner: a link by email, a code by text message
Choosing a plan; turning billed extra runs on or off Nothing that costs you money can be switched on by a key. GET /plan shows the setting
Creating and revoking API keys A key must not mint keys. A leaked key could otherwise replace itself
The step debugger It is an interactive session in the browser. simulate, test and test-step give the same insight without a session

Real runs and test runs

  • run and rerun start real runs. They count against your plan and alert on failure.
  • test, simulate and test-step are test runs: free, no alert, stored as tests. With dryRun: false they still change your store, which is why that needs an execute key.
  • cancel stops a run that is queued or waiting. It ends as Cancelled and does not count as a failure. A run that is already running cannot be cancelled.

Rate limits and versioning

A leaky bucket per key, the same model Shopify uses: a burst of up to 300 requests, refilling 5 per second. The function run endpoint has its own bucket of 60, refilling 1 per second. Running a workflow for real is limited to 60 calls per hour. Over the limit you get 429 with a retry time: back off and retry. Limits are the same on every plan.

The API is versioned in the path (/api/v1). A breaking change would ship as /api/v2 with notice, and v1 keeps working.

MCP server

The MCP server offers the same operations as tools for an AI assistant. See Build workflows with an AI assistant over MCP.