I am suddenly getting a 401 unauthorized error when trying to retrieve sensor data via a url. What is causing this?
Hey @Mtnbiker88,
We did recently make a change to require API keys on all Notehub API requests for security/accountability reasons.
Can you make sure you’re including an access token on your requests? If not, this documentation article walks you through generating a token for API use: Notehub API Introduction - IoT Connectivity at Blues.
And if that’s not the issue let me know and we’ll try to figure out what’s up.
TJ
Thanks for the reply, TJ. I do use an access token, see my code below:
public static async void PrepareTheBluesSocketAsync()
{
// Setup intial Blues https client
string urlString = https://notehub.io/oauth2/token;
BluesAuthorization.Client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, urlString);
request.Content = new StringContent(“grant_type=client_credentials&client_id=” + BluesAuthorization.ClientID + “&client_secret=” + BluesAuthorization.ClientSecret);
request.Content.Headers.ContentType = new MediaTypeHeaderValue(“application/x-www-form-urlencoded”);
HttpResponseMessage response = await BluesAuthorization.Client.SendAsync(request);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
dynamic dataObject = JObject.Parse(responseBody);
BluesAuthorization.AccessToken = dataObject.access_token;
BluesAuthorization.TokenType = dataObject.token_type;
}
public static async Task GetBluesDataAsync()
{
//Convert start and enddates to epoch time (unix time in seconds)
DateTime startDate, endDate;
DateTime.TryParse(SensorComms.start_date, out startDate);
int dtStartEpochTimeSecs = EpochExtensions.ToUnix(startDate.ToUniversalTime());
string dtStartEpochTimeStr = dtStartEpochTimeSecs.ToString();
DateTime.TryParse(SensorComms.end_date, out endDate);
endDate = DateTime.Now;//Override the endDate passed in
int dtEndEpochTimeSecs = EpochExtensions.ToUnix(endDate.ToUniversalTime());
string dtEndEpochTimeStr = dtEndEpochTimeSecs.ToString();
string urlString = https://api.notefile.net/v1/projects/ + BluesAuthorization.ProjectUID + “/events?deviceUID=dev:” + SensorComms.device_id +
“&startDate=” + dtStartEpochTimeStr + “&endDate=” + dtEndEpochTimeStr + “&dataType=captured”;
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, urlString);
request = new HttpRequestMessage(HttpMethod.Get, urlString);
request.Headers.Add(“Authorization”, "Bearer " + BluesAuthorization.AccessToken);
HttpResponseMessage response = await BluesAuthorization.Client.SendAsync(request);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
}
My GIS system loads all the sensors when the program fires up but then the program is left running (it’s a dashboard and runs for weeks at a time) and rereads all the sensors every hour. It has no problem at startup or for several hours, but then suddenly fails with the 401 error.
John
Can you make sure your access token hasn’t expired? Notehub | API Access
TJ
I set it up to not expire…it is reading fine right now since I restarted the application

But after some time it starts to fail with the 401…I will try to get a better feel for when it does that, for example, after x number of tries, or at a certain time of day…
Hmmm, weird. The only thing we changed on our end was related to requiring tokens.
Let us know if you start having issues again and I can dig into the logs on our end and see I notice anything that looks off.
TJ
TJ,
During the night the sensor readings failed with a 401 unauthorized. Could you please investigate on your end?
Thank you.
@Mtnbiker88 Actually, I missed this earlier, but based on your code it looks like you’re using oauth tokens to authenticate your requests, which expire after 30 minutes.
I’d try removing the call to oauth2/token and instead just including your personal access token in the Authorization header. See Notehub API Introduction - IoT Connectivity at Blues.
TJ
Well, I guess I am not following what you are suggesting. I thought that is exactly what I am doing. See the code below. I call the Prepare… method once at startup to retrieve and set the personal access token named BluesAuthorization.AccessToken, then call the GetBluesDataAsync every time I read a sensor. In that I thought I am using the personal access token as suggested in the Notehub API documentation.
public static async void PrepareTheBluesSocketAsync()
{
// Setup intial Blues https client
string urlString = “https://notehub.io/oauth2/token”;
BluesAuthorization.Client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, urlString);
request.Content = new StringContent(“grant_type=client_credentials&client_id=” + BluesAuthorization.ClientID + “&client_secret=” + BluesAuthorization.ClientSecret);
request.Content.Headers.ContentType = new MediaTypeHeaderValue(“application/x-www-form-urlencoded”);
HttpResponseMessage response = await BluesAuthorization.Client.SendAsync(request);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
dynamic dataObject = JObject.Parse(responseBody);
BluesAuthorization.AccessToken = dataObject.access_token;
BluesAuthorization.TokenType = dataObject.token_type;
}
public static async Task GetBluesDataAsync()
{
//Convert start and enddates to epoch time (unix time in milliseconds)
DateTime startDate, endDate;
DateTime.TryParse(SensorComms.start_date, out startDate);
int dtStartEpochTimeSecs = EpochExtensions.ToUnix(startDate.ToUniversalTime());
string dtStartEpochTimeStr = dtStartEpochTimeSecs.ToString();
DateTime.TryParse(SensorComms.end_date, out endDate);
endDate = DateTime.Now;//Override the endDate passed in
int dtEndEpochTimeSecs = EpochExtensions.ToUnix(endDate.ToUniversalTime());
string dtEndEpochTimeStr = dtEndEpochTimeSecs.ToString();
string urlString = "https://api.notefile.net/v1/projects/" + BluesAuthorization.ProjectUID + "/events?deviceUID=dev:" + SensorComms.device_id +
"&startDate=" + dtStartEpochTimeStr + "&endDate=" + dtEndEpochTimeStr + "&dataType=captured";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, urlString);
request = new HttpRequestMessage(HttpMethod.Get, urlString);
request.Headers.Add("Authorization", "Bearer " + BluesAuthorization.AccessToken);
HttpResponseMessage response = await BluesAuthorization.Client.SendAsync(request);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
}
There are two different types of tokens you can use with the Notehub API: personal access tokens and Oauth bearer tokens.
Your code is using Oauth bearer tokens (see the call to https://notehub.io/oauth2/token). If you switch to using a personal access token you will no longer need to make that HTTP call at all—instead you can include the personal access token you got from Notehub in your Authorization header as shown here Notehub API Introduction - IoT Connectivity at Blues .
TJ
Ohhhhh, I see. I was using that call to get the actual value of the personal access token key. I originally had that oauth code inside the same method as the sensor query, so it was being called every hour. I moved it to be called once at startup and that’s when the problems started to occur (since before the 30 mins was fine as long as I was calling that every hour). I did not see anywhere how to retrieve the actual value of the personal access key and so that’s the reason for the oauth call.
So, I ran it once and got the personal access key and just assigned it as a variable/constant in the code. So far so good…how otherwise do I know what/how to retrieve the value of the personal access key? I do not see the value for the key in the Notehub API Access, all I see is it’s name…
I will let you know how this goes…thanks again TJ!
You cannot retrieve the value of your personal access token once you’ve created it for security reasons.
If you don’t have your token saved, you’ll need to generate a new token in the Notehub UI, save its value, and use that value in your code.
TJ
I don’t see where in the Notehub UI the value is written. I ran the startup code and retrieved it from my https oauth call then stored it as a value in my code…
When you create a new token in the API Access area of Notehub you’ll see the following dialog that includes your token’s value.
Ahhhhh, okay, it all makes sense now! I did not write it down when I created it the first time.
I just created a test and see the dialog you refer to. Thanks again!!! Your support has been invaluable!
I just started the program this morning and got a 401 right away…could you pls check the logs?
I just created a new personal access token, modified it in my code, and it is working for now…
