"smartthings apps:create does't list l:devices scope?

Hi all! I’m trying to setup OAuth for my new Pebble watch app, which can turn on/off devices. I obviously needs to be able to list devices and the web page they mention for understanding what scopes I need:

mentions I need “l:devices”, however the smartthings CLI program doesn’t list this scope as one I can pick. What scopes do I need in order to:

  1. list all devices and device groups
  2. turn a device on and off

That’s all I need!

Hi!
For your use case, the scopes you’ll need are:

  • r:devices:* → allows reading/listing devices
  • x:devices:* → allows executing commands on devices (on/off, etc.)

The l:devices scope mentioned in the documentation is a more limited permission intended only for listing devices. However, r:devices:* already includes broader read access, so using it covers the device listing requirement as well.

With these two scopes you should be able to:

  • list devices
  • access device details
  • send commands like on/off

You do not need any additional scopes for basic device control.

Great! I was thinking along those lines, but was looking for something definitive. Thanks a lot!

So, once the user has finished the initial login page and my app is ready to receive the code (which will be exchanged for a token), everything I read references a URI which SmartThings accesses in order to deliver the code. Is there a more direct way to simply receive the code in a reply to the login webpage and then have that simply relay it back to my app? I’ve read references to a “grantCallbackAccess”. Maybe this is what I should be using? My app is in running in JS code executed by the Pebble app on the person’s phone and that JS code has a communication channel to the watch. There’s no way a SmartThings system can use any URI to contact the person’s watch. Maybe I’m just misunderstanding how this whole thing works, but it’s rather confusing because there’s the v1.0 version of OAuth and then there’s also the previous way to create a SmartThings Token. All of this is documented online still, so I keep seeing references to things which aren’t even relevant anymore. Sorry for being so confused!

Hi,

Here are the steps to work with an OAuth app in SmartThings:

  1. The option to create OAuth integrations cannot be found in the Developer Workspace.
  2. You need to use the SmartThings CLI to create this type of app

Command:
smartthings apps:create
---->The type you need to select is “OAuth-In App”
----> Target URL is the link where you want to receive the subscription events
----> These scopes are the permissions whitelisted from your app, if you use a scope in the “authorize URL” not included in your app’s scopes, you’ll get an error
-----> Add redirect URI because that’s where you’ll receive the authorization code once the user authorizes access to your app.3. 4.

  1. You can also use the JSON in this sample as the input for the command.
    GitHub - SmartThingsCommunity/api-app-subscription-example-js: Example API Access SmartApp that shows the state and allows control of devices

  2. Then, you need to start the OAuth 2.0 process which consists on:

  3. Show the authorization page to the user by using this URL:
    https://api.smartthings.com/oauth/authorize?client_id=clientId_from_app&response_type=code&redirect_uri=redirect_uri_from_app&scope=scopes_from_whitelisted_inApp

  4. Once the user authorizes access to your app, it’ll redirect you to the “Redirect URI” you configured with the Authorization Code.

  5. You’ll exchange this code for an Access Token. This is an example of that request:
    curl -X POST "https://api.smartthings.com/oauth/token" -u "clientId_from_app":"clientSecret_from_app" -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=authorization_code&client_id=clientId_from_app&code=codeReceived&redirect_uri=redirect_uri_from_app"

  6. The Access Token you get expires in 24 hours.

  7. The Refresh Token expires in 29 days if not used. We suggest you refresh the token before this time, otherwise, you’ll lose the Refresh token and the User will need to re-authorize.

NOTE: Remember the OAuth integration has a limit of 500 installations by default. Each time a user authorizes access to one of his/her locations, it will count as 1 installation. This means, if a user has 3 locations and authorizes access to each of them, he/she will use 3 installations.

  1. To refresh the Access Token, you need to use the same endpoint but the grant_type is different, here’s an example about this:
  2. curl -X POST “https://api.smartthings.com/oauth/token” -u “clientId_from_app”:“clientSecret_from_app” -H “Content-Type: application/x-www-form-urlencoded” -d “grant_type=refresh_token&client_id=clientId_from_app&refresh_token=latest_refresh_token”

Subscriptions in API_ONLY apps

Registering a targetURL isn’t mandatory in this type of application, but if you want to create subscriptions using its installedAppId, you need to include a value for it.

Note: If you have already created your API_ONLY app but didn’t register a value for it, take a look at this post to know how you must update your app to do so: SmartThings CLI apps:update Type Error (reading ‘url’)

Once you have finished creating the app, you will receive a POST request with a confirmation URL, which you need to copy and paste into your browser or make a GET request using it. This is to “verify” the app so it can receive requests with the subscription events.

Example of Access Token response

This applies to cases where subscriptions are created using an API_ONLY app. They only need the installedAppId and the Access Token.

{ "access_token":"41fb5735-d9af-4041-...", "token_type":"bearer", "refresh_token":"f804c515-2afa-4a49-...", "expires_in":85744, "scope":"r:locations:* x:devices:* r:devices:*", "access_tier":0, "installed_app_id":"cac8fb70-4e2c-4630-..." }

Note:
Subscriptions require having a targetURL registered in the app because that’s where you’ll receive the new events.
This will also trigger a CONFIRMATION request (similar to a SmartApp) which means you need to verify the app by making a GET request to that URL to start receiving the events.

Hi, @rajid
As my teammate shared the instructions for the OAuth Integration flow, we’re wondering if there are any issues with how you’re using it. If so, we can discuss it.
The “grantCallbackAccess” term comes from the Schema Cloud Connector, which is for a device integration. It also uses OAuth as the authentication framework, but it is completely different from the API_ONLY app type.
So, please, let us know if the steps above helped you understand the expected flow you need to follow.

SmartThings doesn’t access a URI to deliver the code. You define a Redirect URI and the eventual reply to the login page after sorting out the permissions is an HTTP Redirect to that Redirect URI with the code added to it.

If the user login is taking place in a browser window the redirect is going to be followed whether you like it or not, so you would typically choose to redirect to a URI you handle.

A conventional OAuth app would run on a web server and direct the browser to take the user to SmartThings for the login, but the Redirect URI would take the user back to your app on the server and you would continue on your way in a continuous flow.

With the examples you may have seen using the OAuth flow manually to get a PAT replacement token the idea is to be able to read the code from a visible URI on a browser address bar so the Redirect URI can be anything that will make that happen.

The CLI creates its own ‘localhost’ server on a local port which is used as the Redirect URI. It then opens a browser window to handle the login and the Redirect URI takes the browser to the server on the CLI which reads the code and then tells the user they can close the browser.

Then there are the supported link things I can never remember the term for where a phone app can handle certain URIs internally.

You just have to adapt to the flow you need.

Thanks, everyone, for all of the help! I believe I understand how the redirect URI is used now. My basic problem now is how to go about opening a URL from my Pebble watch app’s Settings page and then capture the redirect when the page is closed. Currently, I can open a page from inside the Settings just fine, but I don’t seem to be catching the close event. This has nothing to do with SmartThings, of course. It’s just basic usage of the Pebble SDK. They mention using a URI beginning with “pebblejs://close”, but currently I’m not catching any close events at all. Just need to play with it more. I think I have everything I need re. SmartThings OAuth.

Thanks again! This is all been a big help clarifying it all!