Using APIs from a different origin/domain

Topic summary

Cross‑origin API calls to a Shopify store from a different domain trigger CORS (browser security that blocks requests between different origins unless explicitly allowed). The core distinction: Admin API is private (server‑side only); Storefront API is public (client‑side allowed with proper setup).

Key points and guidance:

  • Admin API: Must be called from a backend or via an App Proxy on the same shop domain. Frontend calls from other domains are blocked by CORS and are insecure. Recommended flows: frontend → your middleware → Admin API → return data. Consider rate limits and caching. For embedded apps, route requests through your app/backend; App Proxy can safely expose selected endpoints to the storefront.
  • Storefront API: Designed for client‑side use. Use X‑Shopify‑Storefront‑Access‑Token and endpoints like /api/graphql.js. Tokens can be pinned to a domain; mismatches (e.g., localhost, wrong domain, bad env vars) cause CORS. Official JS Buy SDK is available.
  • Third‑party APIs called from a Shopify theme must enable CORS on the third‑party server (add Access‑Control‑Allow‑Origin for the shop domain).

Notable outcomes/examples:

  • Gatsby/local dev CORS fixed by correcting domain/token and env var.
  • Draft order creation from frontend must use App Proxy/backend.

Status: Largely resolved by documenting correct patterns; some confusion persists, but code samples and links were provided.

Summarized with AI on December 28. AI used: gpt-5.

Any method I’ve attempted to request information from a Shopify store from a different domain results in the familiar CORS error:

Access to fetch at ‘https://x.myshopify.com/admin/api/2019-04/graphql.json’ from origin ‘https://x.ngrok.io’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

I’m trying to create a customer-facing site which is very simple and is just for managing (creating and logging in) customer accounts, and doing specific things with those accounts like setting tags and sending emails to store staff to update details on those accounts once they’re created. Using GraphQL or the REST API, is there a way to get the Shopify store to allow API requests from my separate domain without triggering the CORS error? Any way at all to add the appropriate “Access-Control-Allow-Origin” header in the response from the API endpoint?

(The security implications are not my concern here, as I believe API credentials can be obfuscated using backend middleware on the site doing the requests)

Or am I going about it the wrong way and there’s another recommended way to do this besides those two APIs?

Or is what I’m trying to do only possible on the same domain as the store, by design, no exceptions?

1 Like

If you want to make an API request to the admin API, you have to do it from a back end. Front end requests, as you observed, will be blocked by the CORS policy on our end. What you can do is from your front end, delegate to your backend to make the request, and return the response data from that request to your front end.

5 Likes

Hi,

Can you please explain more how to achieve this delegation from Frontend to Backend?

regards

1 Like

The flow is fairly simple but refer to the docs for extra info on authentication. You should never be trying to access the Admin API from the front end as it’s not secure. You will be passing auth details that anyone could steal so this is just a crazy idea.

General delegation (high level):

  1. You’d send info to your app/middlware instead of directly to the API. Perhaps in the ajax call like you’re doing now.
  2. The middleware will handle the secure authentication to the Admin API - and any other security/rate buffering/etc. Also possible the middleware has cached data and skips calling the Admin API entirely. You have to consider API call rates in your approach regardless.
  3. the middleware passes info back via the response to the ajax call. With that data you do whatever you need to on a front end perspective.

What are you trying to do that needs a call to the Admin API in the first place?

Hi Jason,

Thank you for quick reply,

what I am using is an GraphQL Admin API. This is my sample query

var query = { productVariants(first:1, query:"barcode:${sku}") { edges { node { inventoryQuantity legacyResourceId barcode price compareAtPrice availableForSale } } } };
$.ajax( {
url: ‘https://www.domain.myshopify.com/admin/api/2019-10/graphql.json’,
method: ‘POST’,
data: JSON.stringify({query}),

headers: {“X-Shopify-Access-Token”: “PRIVATEAPPTOKEN”},
crossDomain: true,
success: function(response){
console.log(response);
}

})

I am using a Private APP token.

we are currently facing this issue in our store, can you show us how to implement it ???

Can you show me your code?

PS: don’t show the real api password or any private details

This is not solved. What about the Storefront API. Does that require a backend too? I literally can’t get a straight answer out of this forum because every question is about a different kind of API. Public, private, custom. Dudes. Make better docs.

14 Likes

Think of it this way:

Storefront API is a public API and the token for it is meant to be used on the client side.

Admin API is a private API and the token is not meant to be shared publicly. If you share this token to everyone by making requests from the browser, they can potentially access private information about your store, financial information, CUSTOMER information etc.

This could lead to both inconvenience to your customers as they would be subject to fraud as well as you could run into legal issues if someone decides to sue you because of it.

Hence, Shopify throws a CORS error when detecting that you use a browser to send a request to a private API. While the CORS error might not be the most appropriate response here, it is valid for them to deny your request.

Hope that clarifies the issue for others encountering this error.

3 Likes

It doesn’t clear up the issue because it doesn’t answer my question. It only reitterates other docs.

The question is Does Storefront API actually work Client-Side or are there unavoidable CORS issues that require a server-side proxy?

I’m not talking about the difference between Storefront and Admin.

You sound like a bot.

5 Likes

Hence, Shopify throws a CORS error when detecting that you use a browser to send a request to a private API.

This is the answer to your question based on my comment. Storefront API is a public API and Admin API is a private one.

That’s exactly why the difference between the APIs was pointed out.

Of course, you do not need a backend for Storefront API.

It takes very little time to verify that by sending a simple fetch request from Chrome dev tools console.

Aside from that, there is also a library (jsbuysdk) made by Shopify that utilizes Storefront API and is meant for the browser.

You can find more here: https://shopify.github.io/js-buy-sdk/

Hi Nester,

My questions are very related to the topic at hand and, although I’m pretty sure it’s a few very tiny things that I’m missing, I too am struggling for answers.

My situation is simple: I have an Express server (Node) that can authenticate and call the Shopify admin API without problems when the process is initiated from a client app sitting on the same domain. When I initiate the oAuth flow from a client app sitting on a different domain (i.e. this client calls my secure server and this server attempts to establish contact with Shopify) then I end up with the CORS error described above.

I believe this is a reasonable (and possibly even popular) architecture and so it must be something simple I’m missing on my end.

Can you confirm if this is possible and - if so - if an example exists that I can study to see where I’m going wrong?

Hein

1 Like

I am using Storefront API using apollo and get CORS, how to handle that?

1 Like

Surprised that no one yet addressed how people managed work around the CORS issue.

2 Likes

The actual answer is despite what the docs say, you have to use a middleman server to use Storefront API as well. You cannot just do it from the frontend like Stripe allows. So spin up a whole server that just passes messages, folks. Worry about it silently falling over at checkout, folks. That’s the only way to use this “serverless solution” of a scam product.

Bottom line, after 2 integrations and endless trouble and even more monthly fees, I can attest, Shopify is a garbage fire built on a garbage framework, run by people who are just swimming in their money bin, don’t care and don’t answer questions on the forum. Good F’ing luck.

8 Likes

You’re doing it wrong. If you use Storefront API as intended, there is no CORS issue.

Shopify is fundamentally built with the exact same HTTP protocols as all other Internet properties. Shopify is not pushing any unique technology, so comparing it to Stripe as if Stripe is somehow doing Internet computing different or more correct, is plain silly. Once you can do one pattern with one service, you can repeat with any other. oAuth is oAuth, for example.

It’s ok to just say you don’t understand, and ask for help. Mostly, you have to learn to help yourself. Like anything worth doing.

1 Like

Using it as intended? I’ve used it on 2 projects and you need a middle man server to use Storefront API and the docs suck. Period.

and Stripe.JS allows for client side calls to the stripe.com api, so does google analytics script tag. that’s how CORS works, dick.

You are the expert of a pile of ■■■■■

2 Likes

You sure you are not mixing up Storefront API with the GraphQL Admin API?

Storefront API even has a simple library - JS Buy SDK that can be used on any website to implement product catalog / cart functionality with your Shopify store.
You can see an example here: https://jamstack-ecommerce.nesters.me/

That’s a static Nuxt.js storefront outside of Shopify that is utilizing Storefront API.

GraphQL Admin API rightfully will have CORS issues due to sensitive data that can be exposed if you leave your credentials available to everyone on the internet.

Puberty is hitting you hard! I get it though, I had kids, so your 'tude is like water off a ducks back. One day you’ll be out of your mom’s basement, and perhaps less bitter about things you should be enjoying more.

1 Like

That’s a lot of assumptions Hunky Bill. It’s okay to admit this platform is garbage and ruining e-commerce for developers.