A developer from PriceZag reports authentication failures for new Shopify customers using their legacy API integration method, which has worked successfully for 8 years with existing customers. The issue involves curl requests using the format https://key:password@storename.myshopify.com/admin/api/YYYY-MM/products.json, which now returns “Invalid API key or access token” errors for new users.
Root Cause:
Shopify deprecated the REST API (as of October 2024) and the simple API key/password authentication method. New integrations must use OAuth 2.0 and GraphQL.
Solution Process:
Register app in Shopify Partners dashboard to obtain Client ID and Client Secret
Direct users to authorization URL where they grant permissions
Handle redirect with temporary authorization code
Exchange code for permanent access token (shpat_* format) via POST request
Use access token in future API requests
Key Takeaway:
The OAuth flow allows Shopify and store owners to control, modify, or revoke third-party API access with granular permissions (“scopes”). The developer successfully tested the new authentication flow and provided a detailed, code-friendly explanation for others facing similar migration challenges. Legacy tokens starting with different prefixes continue working for existing customers.
Summarized with AI on November 5.
AI used: claude-sonnet-4-5-20250929.
I’m Nicholas, lead developer at PriceZag, a platform that monitors stores competitors.
For the last 8 years we provided our customers with a direct integration to Shopify so they can import their products to our platform directly from Shopify, and also update the price in their store based on the competitors and their repricing rules.
Everything worked fine for all these years, and still does for old customers, but it seems Shopify changed something recently that makes the authentication fail for new customers, or at least for some of them.
We use curl to make requests to Shopify. We wrote our own code for handling requests so we cannot use any Shopify library (which isn’t available anyway in the programming language we use).
It has always worked very well, we ask our customers their storename, API key and password which they generate in their Shopify account for us, and curl simply uses the standard authentication method with these tokens.
But recently we get this error with new customers (while old customers have no problems) :
{“errors”:“[API] Invalid API key or access token (unrecognized login or wrong password)”}
I’ve seen this whole thing about the OAuth method which seems unnecessary complicated. Despite having decades of experience in both back-end development and cryptography I still can’t wrap my head around it. The docs available on Shopify’s website are very confusing and don’t get to the core of what the actual HTTP request should have or how we generate that with real code.
So can someone please help me with this?
If we stick to old school HTTP+SSL and nothing else (no library to depend on), what raw data should we send, and what should we ask our new customers?
Is that OAuth complicated method mandatory now? Did Shopify change this in the last few weeks?
Thanks but even when using “2021-04” which a lot of our old customers still use successfully it doesn’t seem to work for new customers.
I tried every version possible, but none seem to work with the standard HTTP “Authorization” header (which is what curl does when using the [email removed] format).
That’s what I’m trying to understand. And the docs are extremely vague and complex about all this.
Handle Redirect: After the user authorizes your app, Shopify will redirect to your specified redirect URI with a temporary code. Exchange Code for Token: Use this code to request an access token:
This is finally clear, as you used some coder-friendly language (while Shopify docs seem to be written by bureaucrats rather then coders).
I have created a test store and successfully made all requests manually which ended up returning a final shpua_* token that we can then use for future requests.
For anyone visiting this page with the same issue and confused by Shopify docs I will summarize below what to do (in coder-friendly language) :
First, to answer my question “Why so complicated?”, the obvious reason is that Shopify wants to be able to control and revoke API access to any third party (like us), either themselves or to let the store owner do that. They can also modify the permissions granted rather than revoking the whole thing.
So from the user perspective (the person having a Shopify store) the process goes like this:
User clicks some “Connect my Shopify store” link on the third party’s website (like us PriceZag)
That links goes to their own store where they are prompted to grant permissions to that app called “PriceZag”
They click an “Install” button and are redirected back to that third party’s website
That URL to which they are redirected thanks them for linking Shopify, but also gets from Shopify some URI parameters it will use for back-end requests.
So what coders must do for all that to happen:
1. The third party app (like us PriceZag) must create an account at partners.shopify.com where they define the name of the app and so on.
2. In that platform they get a “Client ID” and “Client Secret”, each is a 32-long hex string (128 bits)
3. They also must define “Redirection URL(s)” which is not what sets the URL but what ALLOWS specific URL(s) to be used to redirect the user back to the website in the process I described above.
4. As JiniApps mentioned, the URL to which to send the Shopify user when then click some “Connect my Shopify store” button is:
5. After clicking “Install that App” the user is redirected by Shopify to that “redirect_uri” which now contains various URI parameters:
&code= : a temporary 128-bit in hex format to save, they call it {authorization_code} in their docs. This is NOT how we make all future requests to the store, there’s still one more step…
Besides “code” there are a few more useful URI parameters which you can see at step 2 in the link above, they are: hmac, host, shop, state, and timestamp.
6. Finally, as JiniApps mentioned, you make a back-end POST request using that “code” you got in the URL parameters when the user was redirected. With curl it would look like this:
7. You made it! Now you can use that shpua token for all future requests to that store by putting it as a “X-Shopify-Access-Token” HTTP header, for example: