# Smartthings Api WEBHOOK\_SMART\_APP authorize

**URL:** <https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010>\
**Category:** Writing SmartApps\
**Tags:** developers\
**Created:** [March 13, 2025, 10:36am UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010 "2025-03-13T10:36:34Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![andreadegiovine](https://yyz2.discourse-cdn.com/smartthings/user_avatar/community.smartthings.com/andreadegiovine/32/212239_2.png) [@andreadegiovine](https://community.smartthings.com/u/andreadegiovine)\
**Post date:** [March 13, 2025, 10:36am UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010/1 "2025-03-13T10:36:34Z")

</div>

I am writing (in python) a custom integration of SmartThings for HomeAssitant.

I need to receive events from SmartThings for this I want to use “WEBHOOK\_SMART\_APP” as appType.

My app is created and confirmed (I tried both via PING and via CONFIGURATION flow) but when I create the authorization url and authorize the location I am redirected to the “redirect\_uri” url without authorization code “code” but with errors in query string “error=invalid\_request&error\_description=The request is malformed.”.

APP ID: 3dadda29-5bc2-4858-ac00-4715617460cc

---

<div class="post-metadata">

**Author:** ![orangebucket](https://yyz2.discourse-cdn.com/smartthings/user_avatar/community.smartthings.com/orangebucket/32/81590_2.png) [@orangebucket](https://community.smartthings.com/u/orangebucket)\
**Post date:** [March 13, 2025, 11:06am UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010/2 "2025-03-13T11:06:55Z")

</div>

Installing a WEBHOOK\_SMART\_APP doesn’t involve an authorization code. You create/register, verify and publish the app via the Developer Workspace and install instances of the app via the mobile apps. Renewable access and refresh tokens are delivered via the INSTALL and UPGRADE lifecycles, and five minute access tokens via the EVENT lifecycle. _There are ways of bypassing the Developer Workspace and apps but they aren’t publicly documented._

The authorization code is involved in the OAuth-In app flow (with the API\_ONLY app type).

---

<div class="post-metadata">

**Author:** ![andreadegiovine](https://yyz2.discourse-cdn.com/smartthings/user_avatar/community.smartthings.com/andreadegiovine/32/212239_2.png) [@andreadegiovine](https://community.smartthings.com/u/andreadegiovine)\
**Post date:** [March 13, 2025, 11:09am UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010/3 "2025-03-13T11:09:46Z")

</div>

> [@orangebucket](#):
>
> There are ways of bypassing the Developer Workspace and apps but they aren’t publicly documented.

How can i get this workaround?

API\_ONLY is not a solution, i need to get updates from devices when exist.

---

<div class="post-metadata">

**Author:** ![orangebucket](https://yyz2.discourse-cdn.com/smartthings/user_avatar/community.smartthings.com/orangebucket/32/81590_2.png) [@orangebucket](https://community.smartthings.com/u/orangebucket)\
**Post date:** [March 13, 2025, 11:40am UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010/4 "2025-03-13T11:40:39Z")

</div>

> [@andreadegiovine](#):
>
> API\_ONLY is not a solution, i need to get updates from devices when exist.

The OAuth-In (API\_ONLY) apps have a Webhook just like the WEBHOOK\_SMART\_APP. Instead of ‘lifecycle’ messages they receive ‘messageType’ messages, in particular the CONFIRMATION message for verification and the EVENT for status messages from SmartThings. The structure is identical where relevant.

You subscribe to the events in the same way you would with the Webhook SmartApps, you just don’t have the CONFIGURATION stuff to contend with.

---

<div class="post-metadata">

**Author:** ![Itati](https://avatars.discourse-cdn.com/v4/letter/i/df705f/32.png) [@Itati](https://community.smartthings.com/u/Itati)\
**Post date:** [March 13, 2025, 5:04pm UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010/5 "2025-03-13T17:04:31Z")

</div>

Hi @andreadegiovine

Adding to what @orangebucket mentioned, SmartApps are not the same as OAuth (API) Access Apps, they cannot be created through the Developer Workspace.  
These are the instructions to create an API Access app:

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](https://github.com/SmartThingsCommunity/api-app-subscription-example-js?tab=readme-ov-file#2-register-your-smartthings-app)
2. Then, you need to start the OAuth 2.0 process which consists on:

> [@](#):
>
> 1. 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}](https://api.smartthings.com/oauth/authorize?client_id=$%7BclientId_from_app%7D&response_type=code&redirect_uri=$%7Bredirect_uri_from_app%7D&scope=$%7Bscopes_from_whitelisted_inApp%7D)
> 2. Once the user authorizes access to your app, it’ll redirect you to the “Redirect URI” you configured with the Authorization Code.
> 3. 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”](https://api.smartthings.com/oauth/token%E2%80%9D) -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}”

1. The Access Token you get expires in 24 hours.
2. 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**](https://developer.smartthings.com/docs/connected-services/oauth-integrations#install-limits) **. 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”](https://api.smartthings.com/oauth/token%E2%80%9D) -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}”

SmartApps don’t have the field of “redirect\_uri”, only “target\_url” so, maybe the redirect URI is set by default to the URL we saw to continue with the normal SmartApp lifecycle events and the engineering team saw that in the logs.

---

<div class="post-metadata">

**Author:** ![andreadegiovine](https://yyz2.discourse-cdn.com/smartthings/user_avatar/community.smartthings.com/andreadegiovine/32/212239_2.png) [@andreadegiovine](https://community.smartthings.com/u/andreadegiovine)\
**Post date:** [March 19, 2025, 7:54am UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010/6 "2025-03-19T07:54:20Z")

</div>

The goal is that every installation of HomeAssistant integration will create a SmartApp using http request (no command line) using personal access token and oauth flow.

On the documentation i cant find a section to subscribe for devices update using API\_ONLY, but only for installed apps

---

<div class="post-metadata">

**Author:** ![orangebucket](https://yyz2.discourse-cdn.com/smartthings/user_avatar/community.smartthings.com/orangebucket/32/81590_2.png) [@orangebucket](https://community.smartthings.com/u/orangebucket)\
**Post date:** [March 19, 2025, 9:08am UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010/7 "2025-03-19T09:08:32Z")

</div>

> [@andreadegiovine](#):
>
> On the documentation i cant find a section to subscribe for devices update using API\_ONLY, but only for installed apps

The documentation is indeed rather incomplete.

The subscription method is the same. You receive the `installedAppId` along with your access and refresh tokens.

The device events will be POSTed to your app’s target URL in a similar fashion to the documented `EVENT` lifecycle for Webhook and Lambda apps. You will see that they will have a `messageType` rather than a `lifecycle` and they don’t include a temporary access token.

---

<div class="post-metadata">

**Author:** ![andreadegiovine](https://yyz2.discourse-cdn.com/smartthings/user_avatar/community.smartthings.com/andreadegiovine/32/212239_2.png) [@andreadegiovine](https://community.smartthings.com/u/andreadegiovine)\
**Post date:** [March 19, 2025, 10:03am UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010/8 "2025-03-19T10:03:04Z")

</div>

On the APY\_ONLY app creation request i dont send any target\_url (as for WEBHOOK), than how the server say where send events?

Im confused, please add some example (request, response, flow)

---

<div class="post-metadata">

**Author:** ![orangebucket](https://yyz2.discourse-cdn.com/smartthings/user_avatar/community.smartthings.com/orangebucket/32/81590_2.png) [@orangebucket](https://community.smartthings.com/u/orangebucket)\
**Post date:** [March 19, 2025, 11:14am UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010/9 "2025-03-19T11:14:50Z")

</div>

I would recommend installing the CLI, setting it to debug mode, and then creating the app as Itati described above. It will show you the API calls it is making.

However I believe the following, which Itati also pointed you towards, illustrates the JSON to create an app with the target URL:

> <https://github.com/SmartThingsCommunity/api-app-subscription-example-js/blob/master/doc/apps/app.json>

---

<div class="post-metadata">

**Author:** ![nayelyz](https://avatars.discourse-cdn.com/v4/letter/n/59ef9b/32.png) [@nayelyz](https://community.smartthings.com/u/nayelyz)\
**Post date:** [March 19, 2025, 2:31pm UTC](https://community.smartthings.com/t/smartthings-api-webhook-smart-app-authorize/297010/10 "2025-03-19T14:31:31Z")

</div>

> [@andreadegiovine](#):
>
> The goal is that every installation of HomeAssistant integration will create a SmartApp using http request (no command line) using personal access token and oauth flow

I’m curious about this, are you trying to achieve something with Home Assistant? Because there’s already an official integration about this that the HA and ST teams worked on and was announced here: [New Integration Between Home Assistant and SmartThings](https://community.smartthings.com/t/new-integration-between-home-assistant-and-smartthings/296251)

This is to avoid duplicated efforts, but as mentioned above, if your flow of the API\_ONLY app is successful, then, you’ll get an installedAppId in the same access token object, for example:

```auto
{
   "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-..."
}

```

If you haven’t registered a targetURL, you should edit the app to do so.  
Remember this will also trigger a CONFIRMATION request (similar to a SmartApp) which means you need to verify the app to start receiving the events. This means you don’t need the an API\_ONLY app to create another SmartApp for the subscriptions.
