Developer API and MCP
Everything you manage in the app, you can also manage from your own code or from an AI assistant. Workflow Webhooks exposes two surfaces: a REST API and an MCP server. Both live on the Developer page.
API keys
Both surfaces authenticate with an API key. On the Developer page, under API keys, create a key and pick its access level:
- Read only - list webhooks, read invocation history and stats.
- Read & write - also create, update and delete webhooks.
- Read, write & execute - also fire a test invocation or replay a past one.
The full key is shown once, at creation. Copy it then and store it securely; you cannot see it again. Keys are stored hashed, never in plain text, and you can revoke a key at any time.
Send the key as a Bearer token on every request:
Authorization: Bearer fwk_your_key_hereWhy execute is a separate level
Firing a webhook really does run your Shopify Flow workflows, and those workflows can change your store - tagging orders, sending email, updating inventory. Keeping that behind its own level means a key you hand to a script or an AI assistant for everyday work cannot trigger your automations by accident. Give out read keys by default, and only create an execute key where you genuinely need one.
Base URL
The API and the MCP server are served from a dedicated hostname:
https://shopify.workflow-webhooks.appSo the REST API lives at https://shopify.workflow-webhooks.app/api/v1 and the MCP server
at https://shopify.workflow-webhooks.app/api/mcp. The Developer page shows both with a
copy button.
This hostname serves only /api - the embedded admin UI stays on its own Shopify
-registered URL. Keeping them apart means the address you paste into a script, a CI job or
an AI client is stable and unrelated to the app's embedding.
REST API
The base URL is shown on the Developer page. The main endpoints:
| Method | Path | Level | Purpose |
|---|---|---|---|
| GET | /api/v1 |
none | API index - confirms the API is up |
| GET | /api/v1/me |
read | Check auth and see your key's level |
| GET | /api/v1/webhooks |
read | List webhooks |
| POST | /api/v1/webhooks |
write | Create a webhook |
| GET | /api/v1/webhooks/:id |
read | Get one webhook |
| PUT / PATCH | /api/v1/webhooks/:id |
write | Update a webhook |
| DELETE | /api/v1/webhooks/:id |
write | Delete a webhook |
| POST | /api/v1/webhooks/:id/test |
execute | Fire a test invocation |
| GET | /api/v1/history |
read | List invocations |
| GET | /api/v1/history/:id |
read | Get one invocation, with its payload |
| POST | /api/v1/history/:id/replay |
execute | Replay a past invocation |
| GET | /api/v1/stats |
read | Totals, success rate, daily series |
| GET | /api/v1/templates |
read | Built-in webhook templates |
A quick check that your key works:
curl https://shopify.workflow-webhooks.app/api/v1/me \
-H "Authorization: Bearer fwk_your_key_here"{ "authenticated": true, "shop": "your-store.myshopify.com", "level": "READ" }MCP server
The MCP server lets an AI assistant (Claude, Cursor, VS Code, Gemini CLI and others) work with your webhooks in conversation. On the Developer page, the MCP tab shows the server URL and a ready-to-copy connect command per client, with your key already inserted.
The tools mirror the REST endpoints, and the tool set reflects your key's level: a read-only key does not even see the tools that create, delete or fire webhooks. All authentication and data handling stay server-side.
How your data is protected
Two things are worth knowing before you point an automation or an AI assistant at this API.
Your webhook's auth token is never readable. The token or signing secret you set on a webhook cannot be read back through the API or MCP at any level. Responses tell you only whether a token is set (hasToken), never its value. You can set a new one; you can never retrieve the old one.
Personal data in payloads is masked. Webhook payloads come from outside systems and often contain customer details. Before an invocation payload leaves the server, values that look like personal data are replaced with ***: email addresses, phone numbers, card numbers, and fields named after a person (customerName, shippingAddress and similar). Request headers are sanitised the same way the app's history screen does it.
This masking is careful but not a guarantee. It works on field names and value patterns, so personal data sitting inside a free-text field - a note, a comment, a message body - can still come through. Treat API responses as potentially containing customer data, and store them accordingly.
Test and replay do not use your quota. Invocations you fire through the API are recorded as tests, so they do not count toward your plan's monthly allowance. Replays do not count either, because the original invocation already did.
Next steps
- Introduction to Workflow Webhooks - how webhooks and payload mapping work.
Rate limits
The REST API and the MCP server share one budget per API key.
- 300 requests per 60 seconds per key, as a fixed window.
- Execute-level calls get a second, tighter budget of 60 per hour. They spend both, so a burst of executes also eats into the shared allowance. For this app that means test-invoking a webhook and replaying a history entry, both of which really run your Shopify Flow workflows.
- The same on every plan. Your plan meters invocations, not API calls, so upgrading does not raise these numbers.
- Going over returns HTTP 429. Back off and retry, ideally with exponential backoff.
- If our cache is briefly unavailable the limiter fails open rather than blocking your integration.
Incoming webhooks are not rate limited
Worth being clear, because it is the question we get asked most: we do not throttle incoming webhook deliveries. Send them as fast as they arrive, in whatever bursts your source system produces - there is no per-second or per-minute cap on our side.
The only ceiling is your plan's 30-day invocation allowance. Once that is used up, further calls stop being processed until the window rolls over or you upgrade. Beyond that, the limits that apply are Shopify's: Shopify Flow has its own execution limits, and a trigger payload is capped at 50KB.
Shopify's own limits
These are Shopify's limits on Shopify's APIs, not ours. They apply to what this app (and your workflows) can do on the Shopify side, and you may meet them on a large store even while well inside our limits.
- Input arrays are capped at 250 items across every Shopify API. A request with a larger array is rejected.
- Pagination stops at 25,000 objects. Counts are accurate up to 25,000; above that Shopify returns
25001, meaning "more than 25,000". If you need to go deeper, filter first. - The GraphQL Admin API is metered by calculated query cost, in points per second, and the ceiling depends on the store's Shopify plan:
| Shopify plan | Points per second |
|---|---|
| Standard | 100 |
| Advanced | 200 |
| Plus | 1000 |
| Enterprise (Commerce Components) | 2000 |
The Storefront API is not rate limited.
Full detail: Shopify API rate limits

