Azure API Management is awesome! The thought of API virtualization and the power, flexibility and ease-of-use it can bring, is impressive to say the least.
I have the chance to ‘play’ with the technology with a project I’m working on for one particular client. Starting to play with things you often miss the simplest details or take things for granted. This is such a story…
So, I went on to set-up an API, provided some operations, configured security, etc…
However, using Postman, one error I kept getting was the following:
{ “statusCode”: 401, “message”: “Access denied due to invalid subscription key. Make sure to provide a valid key for an active subscription.” }
No matter what I did, I kept getting the error. Removing the Ocp-Apim-Subscription-Key in the header, provided me with the following error:
{ “statusCode“: 401, “message“: “Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API.” }
It was clear I needed to provide the Azure APIM subscription key, but I was providing the wrong one it seems.
It’s already tricky to find your subscription keys and I had to ask some colleagues more than once where to retrieve it.
To retrieve your keys, go to the Azure portal, select your API Management service, select Users (the below picture mentions Users – PREVIEW, since the transition to the current portal is not finished yet) and you’ll find your subscription keys for your “products” there.
One of the things about Azure API Management is that any developer can subscribe to start using your API. This can be a paying customer or a customer which you just need to register. For that, there is the Azure API Management developer portal. A completely customizable portal with developer documentation, test forms, etc… based on the settings you determine in the administration portal.
In Azure API Management, a Product contains one or more APIs as well as a usage quota and the terms of use. Once a product is published, developers can subscribe to the product and begin to use the API’s which are part of the product’.
This time, from the developer portal, I copied the subscription keys and added a new header “Ocp-Apim-Subscription-Key”, containing the key copied from the Azure portal.
Still, I kept getting the same error…. it kept me busy for far too long… until I tried to call the Echo API. This is the default API, provided with any Azure API Management service.
I noticed, when trying to call this API from within the developer portal, that the header was already provided. I did not have to provide it myself for the Echo API…
Then it dawned to me: I didn’t bother to add my API to one of the (default) products! In the API configuration, you can see in which products your API is included:
I quickly included my API into the Starter and Unlimited products and saved.
Seconds later, refreshing the developer portal for my own API gave me the following result:
Now, sitting here and writing this up, I still don’t have my API working, but at least some poor soul will perhaps some day have the same issue and find this page.
Lesson learned
Always add your API to your product()s, or you will not be able to call them.
Hope this helps at least someone, since I didn’t find this within the MANY Google searches I performed.
Cheers,
Pieter
Thanks Pieter, this helped get my API mock up working in Azure APIM
LikeLiked by 1 person
My pleasure Fatih! Good luck in your endeavors!
LikeLike
Thank you!
LikeLiked by 1 person
You’re welcome Ravi, have fun!
LikeLike
Thanks Pieter, it really solved my problem.
LikeLiked by 1 person
Glad I could help, my pleasure!
LikeLike
Hi Pieter,
Great article and well explained!
Thank you and kind regards,
Dennis
LikeLiked by 1 person
Really Helpfull
LikeLiked by 1 person
Hi Pieter,
Great article. You saved me a lot of time
Cheers
Nic
LikeLiked by 1 person
This was helpful today.. 🙂
LikeLiked by 1 person
Thank you Pieter 🙏👍
LikeLike
Hi Pieter. I have a quick question. I am trying to do a https request in nodejs and I am passing the Ocp-ami subscription key in the header but keep getting status code 401. Any advice on where I may be going wrong or what the correct syntax should be. It works fine in postman by the way. Thanks
LikeLike
Are you sure you are providing the correct subscription key? This would be a typical issue of that. What kind of operation are you trying? Have you tried with the trace header set to true? (“Ocp-Apim-Trace” = “true” as seen here: https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-api-inspector
LikeLike
Hey Pieter – thanks for the quick reply. Yes I am definitely providing the correct subscription key as I get a successful status code of 200 in postman when I include the subscription key in the header. I think its more of a case of how I am passing the header info in the call (I am developing an Alexa skill using nodejs in the back end. Here is my code: var Options = { headers :{name : “Ocp-Apim-Subscription-Key”, value : “xxxxxxxxxxxx”}}; and then in my call const getRemoteData = function (url) { return new Promise((resolve, reject) => { const client = url.startsWith(‘https’) ? require(‘https’) : require(‘http’); const request = client.get(url({Options}), (response) => { if (response.statusCode 299) { reject(new Error(‘Failed with status code: ‘ + response.statusCode)); } const body = []; response.on(‘data’, (chunk) => body.push(chunk)); response.on(‘end’, () => resolve(body.join(”))); });
Without the Options variable I get a status code of 401 which means I am hitting the URL. I think its just syntactically wrong in my code. Any help would greatly appreciated as I’ve been stuck on this for a few hrs now. CheersAndrew
LikeLike
Actually Pieter I’ve re-jigged a bit, but it still doesn’t work – var headers = { ‘Ocp-Apim-Subscription-Key’: ‘xxxxxxxxxxxxxxxxxxxxxxxxxx’} const options = { method : ‘GET’, url : url, headers: headers} const getRemoteData = function (options) { return new Promise((resolve, reject) => { const client = url.startsWith(‘https’) ? require(‘https’) : require(‘http’); const request = client.get(options, (response) => { if (response.statusCode 299) { reject(new Error(‘Failed with status code: ‘ + response.statusCode)); } const body = []; response.on(‘data’, (chunk) => body.push(chunk)); response.on(‘end’, () => resolve(body.join(”))); }); request.on(‘error’, (err) => reject(err)) })};
LikeLike