CORS, the app proxy URL and browser calls
A webhook is normally called server to server. If you want to call one from a browser - your storefront, a landing page, a customer portal - two settings matter: Enable CORS and Use app proxy URL. Both live under the webhook's Advanced settings.
Enable CORS
Browsers refuse a cross-origin request unless the receiving server says it is allowed. Switch on Enable CORS and the webhook answers the browser's preflight and accepts the call.
The preflight also allows whichever header carries your token, including a custom header name you set yourself, so a browser does not trip over it.
Use app proxy URL
Every webhook has two addresses, both shown with a copy button under URL settings:
| URL | Looks like | Notes |
|---|---|---|
| Direct app URL | our app domain, ending in the webhook's code | Always works, including on development and password-protected stores |
| App proxy URL | a path on the shop's own domain | Same origin as your storefront, so a browser treats it as a first-party request |
Switch on Use app proxy URL to publish the proxy address. It integrates more cleanly with the storefront, and because it is same-origin you often do not need CORS at all.
Two things to know before you turn it on:
- The shop must be live and not password protected. Shopify does not route app proxy requests for a locked storefront, so on a development store the proxy URL will not answer. Keep it off there.
- The IP allowlists does not apply to the proxy URL: those requests reach us from Shopify's servers, so their address tells you nothing about the original caller.
Authentication works the same on both addresses. So does Duplicate delivery protection, history and the plan limit.
Allow a custom request body
Also in Advanced settings: Allow custom request body switches off strict body validation, so the webhook accepts any JSON shape rather than only the fields you mapped. Use it when the sender's payload is dynamic or you do not control it. Mapped fields still reach Flow the same way - see Payload mapping and Flow variables.
Related
- Authentication - what the browser has to send.
- Payload mapping and Flow variables - which fields reach Shopify Flow.
- Plans and usage - every browser call counts toward the limit.

