SmartThings API Help

Hi,

So I recently had a brainwave to do something with the SmartThings API, basically turn off a light.

Easy I thought. Got a PAT token, gave it the permissions I wanted, made a request and sent it… volia the light went off.

Now the API is broken due to the PAT TTL change that’s now limited to 24 hours…

Anyways, I’m trying to make this an OAUTH request but the document’s are mind boggling…

I have:

Not sure what else to do… using the PAT was super easy but this is a mess, and the documentation is not clear or simple for someone that’s not a developer in any way.

Has anyone got any simple steps or pointers to get this working?

Thanks

OK, let’s see what I can do using a Windows command line and a browser. The rest is fluff to start with.

First we need to set up the ‘app’ at SmartThings end, which is easiest using the CLI because it walks you through it. At this stage don’t bother with a target URL. That only gets used if you are into subscriptions and things. The redirect URL comes into play in the next section. At this point you are whitelisting valid URLs that you can use, just as you are whitelisting scopes that you are allowed to select.

> smartthing apps:create
? What kind of app do you want to create? (Currently, only OAuth-In apps are supported.) OAuth-In App

More information on writing SmartApps can be found at
  https://developer.smartthings.com/docs/connected-services/smartapp-basics

? Display Name In search of highland cattle
? Description In which highland cattle are sought.
? Icon Image URL (optional)
? Target URL (optional)

More information on OAuth 2 Scopes can be found at:
  https://www.oauth.com/oauth2-servers/scope/

To determine which scopes you need for the application, see documentation for the individual endpoints you will use in your app:
  https://developer.smartthings.com/docs/api/public/

? Select Scopes. r:devices:*, w:devices:*, x:devices:*
? Add or edit Redirect URIs. Add Redirect URI.
? Redirect URI (? for help) https://httpbin.org/get
? Add or edit Redirect URIs. Finish editing Redirect URIs.
? Choose an action. Finish and create OAuth-In SmartApp.
Basic App Data:
─────────────────────────────────────────────────────────────────────────────────
 Display Name     In search of highland cattle
 App Id           cc425d75-ea53-4d68-84d4-230092e599d7
 App Name         ainsearchofhighlandcattle-0d972122-0280-4cf7-b72b-a309c0700cb0
 Description      In which highland cattle are sought.
 Single Instance  true
 Classifications  CONNECTED_SERVICE
 App Type         API_ONLY
─────────────────────────────────────────────────────────────────────────────────


OAuth Info (you will not be able to see the OAuth info again so please save it now!):
───────────────────────────────────────────────────────────
 OAuth Client Id      0817f4d5-d764-4d09-a741-d5da52889b6c
 OAuth Client Secret  9da0e5f8-80c9-4f35-a59f-16ba88774f62
───────────────────────────────────────────────────────────

At this point get the ID and secret copied somewhere.

Now move onto a browser and call this URL:

https://api.smartthings.com/oauth/authorize?client_id=0817f4d5-d764-4d09-a741-d5da52889b6c&response_type=code&redirect_uri=https://httpbin.org/get&scope=r:devices:*+w:devices:*+x:devices:*

See you are using the client ID here. You also need to specify a redirect URL. This has to be one that you whitelisted in the first stage and it has to be valid (it is checked). However it can be anything that it is polite to use. In this case https://httpbin.org/get is made available for looking at HTTP type stuff so it is fair usage.

If that works you should find yourself taken to the Samsung account login screen if you aren’t already logged in on your browser, where you can marvel at what an unbelievable mess they’ve made of their login flow. You will then get transferred back to something more obviously SmartThings in nature where you will get to select which Location you want to authorise. You will then get presented with a long list of tick boxes that allows you to fine tune the access you will have. Then when you are finished you are transferred to the redirect URL you specified. You aren’t interested in the content at this point, you are just looking for the URL to be:

https://httpbin.org/get?code=ZHUJGd

If it hasn’t all worked you’ll get a different query string. The code is all you care about though which is why you don’t need your own server at this stage.

You now need to trade your code for tokens. As you have both an ID and a secret you should use both. They get used in a bog standard Basic authentication which requires an authorization header using your client ID as your username and your client secret as your password. So here we can go back to a command line.

Curl will do the job. The -u creates the header for the Basic authentication and the -d creates a POST with the content type set to application/x-www-form-urlencoded,

curl -u "0817f4d5-d764-4d09-a741-d5da52889b6c:9da0e5f8-80c9-4f35-a59f-16ba88774f62" https://api.smartthings.com/oauth/token -d "grant_type=authorization_code&client_id=0817f4d5-d764-4d09-a741-d5da52889b6c&code=ZHUJGd&redirect_uri=https://httpbin.org/get"

Even though you aren’t being redirected anywhere you still need to supply one of your whitelisted redirect URLs.

All being well you will get a JSON response which will all be in one line but which I have tidied up.

{
    "access_token":"5ec066a9-d108-4af4-9276-eedc850043d3",
    "token_type":"bearer",
    "refresh_token":"d4b93907-6bf8-46f0-8d14-ed007d5712c0",
    "expires_in":86399,
    "scope":"x:devices:* w:devices:* r:devices:*",
    "installed_app_id":"e906cd16-b899-44d6-874a-e9d01b16e5b9",
    "access_tier":0
}

You only get to change the code into tokens once. Nayely will be nodding knowingly at this point.

The end result is that you now have an access token. It still only lasts 24 hours and also this is a location level token which isn’t as much fun as the PAT, but it is likely to be all you need.

Now if you want to extend the life of this token you can. You’ll need the ID and secret for authentication and just the refresh token. Your refresh token will last thirty days. Again I’ll use curl on the command line.

curl -u "0817f4d5-d764-4d09-a741-d5da52889b6c:9da0e5f8-80c9-4f35-a59f-16ba88774f62" https://api.smartthings.com/oauth/token -d "grant_type=refresh_token&client_id=0817f4d5-d764-4d09-a741-d5da52889b6c&refresh_token=d4b93907-6bf8-46f0-8d14-ed007d5712c0"

Again a tidied up response:

{
    "access_token":"b6c249e5-f942-405c-b152-d23ce336a947",
    "token_type":"bearer",
    "refresh_token":"416868bc-0ecc-4d87-b77d-a37e37bcbf51",
    "expires_in":86399,
    "scope":"x:devices:* w:devices:* r:devices:*",
    "installed_app_id":"e906cd16-b899-44d6-874a-e9d01b16e5b9",
    "access_tier":0
}

So that is a start. If you want to have SmartThings send you stuff then you need to have an app on a publicly available IP address and you have further hoops to jump through.

If you just want a PAT replacement then you are actually most of the way there as the access token does the same job (hopefully). If you have a script or app that uses the PAT then use the access token instead, but just be prepared to refresh the tokens first if they are getting too close to a day old.

5 Likes

Amazing. Thank you so much for such a detailed reply and walkthrough. Using the steps above I got it to work. I’m not sure where you manged to get the endpoints from but they actually worked, unlike the ones I found…

https://api.smartthings.com/oauth/token
https://api.smartthings.com/oauth/authorize

As the documentation only mentions a handful of URLs and mainly “https://auth-global.api.smartthings.com

For anyone finding this in the future, this is the kind of documentation that should be published on the site (for non devs!)

Thank you again!

1 Like

You certainly see auth-global.api.smartthings.com a lot in examples going back many years, with the basic api.smartthings.com coming to the fore more recently. I suspect that the /oauth endpoint was something of a retrofit to the public API as it seemed a bit incongruous when it was using a different URL.

The CLI uses oauthin-regional.api.smartthings.com for the authorization code and and auth-global... for refreshing the tokens. I was in a right two and eight on Friday trying to make this stuff work and I tried both of those hostnames. One of them, I think probably auth-global..., was redirecting to something on stinternal.net which is usually a sign that someone dropped one.

Anyone wanting to create an OAuth-In app may wonder whether they also have lifecycle requests, as so comprehensively documented for Webhook SmartApps but not mentioned at all for OAuth-In apps (which are known as API Access apps in older docs and example code). The answer is yes they do:

  • Instead of starting with e.g. "lifecycle": "CONFIRMATION" they start with e.g. "messageType": "CONFIRMATION".
  • Obviously some lifecycles aren’t applicable, such as CONFIGURATION, INSTALL and UPDATE.
  • Clearly some of the lifecycle data is Webhook specific so that isn’t there.
  • Events don’t come with a five minute access token as they do for Webhooks.
  • The business end of the requests is otherwise completely compatible between the two so if you’ve ever created a Webhook SmartApp the code will still be useful.

Thanks for this info. Is there a way to use “client_credentials” flow ?
I have a client_id and client_secret and want to integrate without using Browsers.

Eg:- a simple, list devices from a script
i.e. a headless script using just the client_id and client_secret.

Regards

Not that I’ve seen, though I don’t know what goes on with various internally generated tools.

You do only need one browser authorization to bootstrap you though. Once you’ve got your temporary code you can run headless from then on.

1 Like

Thanks. I am able to get the bearer tokens using your instructions.
But I understand from your post that the refresh code is only valid for 30days so then manual intervention (to get the Auth code via browser) is required right or does using the refresh_token grant type also give a new refresh token for another 30days ?

P.S. I think the auth code needs to be added In the curl command you mentioned for the tokens. i.e. like below

curl -u "0817f4d5-d764-4d09-a741-d5da52889b6c:9da0e5f8-80c9-4f35-a59f-16ba88774f62" https://api.smartthings.com/oauth/token -d "grant_type=authorization_code&client_id=0817f4d5-d764-4d09-a741-d5da52889b6c&code=ZHUJGd&redirect_uri=https://httpbin.org/get&code=ZHUJGd"

The refresh_token grant type does indeed return both a new 24 hour access token and a new 30 day refresh token.

It is there between the client ID and the redirect URI but it is very easy to miss it.

1 Like

To automatically get at new 24 hour valid token, you can create a small python script that uses your refresh token and the resent access token to pull a new valid access token.
You can then set this up to run automatically every 23 hours.
Store the output in a file or variable.
This way you always have a valid access token that can be used to interact with the smarthings api.