OAuth URL Redirecting to Invalid Domain oauth-direct.stinternal.net

am encountering an issue with the OAuth flow for my SmartThings Developer Workspace app.

When I try to initiate the OAuth authorization, the URL redirects to an invalid domain:

oauth-direct.stinternal.net/login

This causes an error: “The requested URL could not be retrieved — Invalid URL”.


How I constructed the OAuth URL:

I manually created the OAuth authorization URL using the following components:

The OAuth URL I generated looks like this:

https://auth-global.api.smartthings.com/oauth/authorize?client_id=[App ID]&response_type=code&scope=i:deviceprofiles%20r:customcapability%20r:devices%20r:locations%20r:rules%20r:scenes%20w:devices%20x:devices&redirect_uri=[URL-encoded Google Apps Script URL]&state=12345


Issue:

Despite using the official authorization URL as above, the OAuth flow redirects to the invalid domain oauth-direct.stinternal.net, which is not publicly accessible and causes the invalid URL error.


Request:

Could you please help clarify:

Thank you for your assistance!

Best regards,

Arun

Account : ntaarunb@gmail.com

What sort of app are you creating? The Developer Workspace is now only used to create Webhook or Lambda SmartApps and handles the entire flow itself.

You normally only use the OAuth authorize URL manually if you are building an OAuth app (known as an API_ONLY app in the API).

In any case the client_id in the authorize query string should be the client ID, not the app ID.

Hi, @arunb_97

As @orangebucket mentioned, it’s always useful to know what you’re trying to achieve to know you’re on the right track.

It’s a common mistake that users create Webhook SmartApps in the Developer Workspace to use it as API_ONLY apps, but following the OAuth flow with this type of app will cause the reaction you mention since Webhook SmartApps are expected to be installed through the SmartThings app and follow certain lifecycles.

That being said, if what you look for is to have access to users’ devices (for example, sending commands to them, getting their current status, getting subscription events from changes in status, health, etc.) from a third-party source like an external app, you need an API_ONLY app type which is the one described in the documentation as OAuth Integration.

These are the instructions to create an app of this type:

  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

    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. You can also use the JSON in this sample as the input for the command.
    https://github.com/SmartThingsCommunity/api-app-subscription-example-js?tab=readme-ov-file#2-register-your-smartthings-app

  4. Then, you need to start the OAuth 2.0 process, which consists of:

  5. 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

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

  7. 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"

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

  9. 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:

    1. > 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: https://community.smartthings.com/t/smartthings-cli-apps-update-type-error-reading-url/303628/5?u=nayelyz

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.

3 Likes

Hi @nayelyz, thanks for clarifying. Let me explain what I’m actually trying to do:

My end goal is to log device status changes (on/off, open/closed, online/offline, etc.) into a Google Spreadsheet so I can track device history. For example, whenever a device is turned on/off or a contact sensor opens/closes, I want the event timestamp and status written into my spreadsheet in real time.

At first, I tried doing this by creating a Personal Access Token (PAT) and then using a Google Apps Script to poll the SmartThings API every 5 minutes. The Apps Script would request all device statuses and log them to the spreadsheet. This worked temporarily, but I faced two big issues:

1. PATs keep expiring after 1–2 days, so I had to constantly regenerate them.

2. Polling every 5 minutes means I don’t get the exact moment a device changes (only snapshots).

That’s why I was looking into creating a SmartApp with OAuth, so that I could:

Authorize my Google Apps Script once,

Subscribe to device events (on/off, open/close, online/offline),

And then push those events directly into my spreadsheet in real time.

From your reply, I now understand that I should be using an OAuth Integration (API_ONLY app) instead of a Webhook SmartApp, since my goal is external access + subscriptions.

Does that sound like the correct approach for my use case? Basically, I just want to receive device events in real time and forward them to my Google Spreadsheet.

Thanks again for guiding me — I really appreciate the help!

Hi, @arunb_97

Correct, SmartApps are mostly used for advanced automations that require external input, but they are only used as self-published. This means that, in order to have access to data from another user’s account, you would need to create a SmartApp project as well.

With OAuth Integration (API_ONLY app), you need to authorize access for each location but users can access it using your Authorization URL.

Once you get the Access Token, you’ll see an structure similar to:

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

And you’ll need to use the installed_app_id to create the subscription.

1 Like

Hi @nayelyz,

Thank you—that helps me understand things much more clearly.

What I’m trying to achieve is to allow each user to authorize access to their own SmartThings location so that my external integration (hosted via Google Apps Script) can subscribe to device events and log them into their personal Google Spreadsheet in real time.

From what you’ve said:

Webhook SmartApps are meant for automations you create and run yourself—but don’t support external access to other user accounts without additional SmartApp project setup.

In contrast, the OAuth Integration (API_ONLY app) is exactly what I need:

Each user will authorize access to their location via an Authorization URL.

I’ll receive an Access Token, and likely a refresh_token, to access their device events.

These credentials will let me subscribe to device event notifications and log them instantly—without polling or short-lived tokens.

Does that properly summarize the correct flow?

Also, could you please clarify:

1. Does the Access Token response also include a refresh_token I can use to avoid reauthorizing every few days?

2. Are there any differences I should know when implementing this via SmartThings CLI versus the Developer Workspace UI?

Thanks again for your patient guidance—I’m getting closer to building a clean, secure solution!

You’ll receive an Access Token and a refresh_token as shown in my previous sample.

This is because this Access Token also expires in 24 hours, so you must use the refresh token to get a new one (if the refresh token isn’t used, it lasts for 29 days). Otherwise, it changes once you get a new Access Token, so, you need to save both new values.

Yes, you would only need a valid token when creating/editing/deleting subscriptions, but their events will come in even if the Access Token is expired

Yes, you can re-authorize when you need it, but before it expires in 29 days, if it isn’t used to get a new Access Token

This type of app cannot be created through the Developer Workspace, only using the CLI, that’s why I shared the steps above. In the Dev WS we can only create WEBHOOK_SMARTAPP type.

2 Likes

Subject: Stuck with API_ONLY OAuth-In App Authorization for Personal Account

Body:

Hi Nayelyz,

I hope you’re doing well. I am reaching out because I am currently stuck trying to authorize my API_ONLY / OAuth-In app and would appreciate your guidance.

Here’s the situation:

  • I am the primary account holder / main admin of my SmartThings account.

  • In my home location, there are five other users, but I am the main admin. My goal is to log device status changes for my location only.

  • Previously, you mentioned that if we want to access data from other users’ accounts, we would need a SmartApp project and explicit permissions from those users. Since I am the main admin, I can authorize the app once and it will cover all device changes in my location without requiring additional permissions from the other users.

  • My goal is simple: for my home location, log all device status changes (on/off, motion/no motion, open/closed, online/offline) into a Google Sheet in real-time.

Authorization Link Construction:
To start the OAuth flow, I manually created the authorization URL using the Client ID, Redirect URI, and required scopes. The Redirect URI points to a Google Apps Script Web App I deployed (set as Execute as Me and accessible to Anyone, even anonymous). For testing, I simplified the scopes to r:devices:* x:devices:* r:locations:* and encoded them correctly in the URL. The link I used is:

https://account.smartthings.com/oauth/authorize?client_id=here&response_type=code&scope=r:devices:*+x:devices:*+r:locations:*&redirect_uri=https%3A%2F%2Fscript.google.com%2Fmacros%2Fs%2FAKfycbwjC4-wQb4gbdK_Jg2_HAbyO5EHnmJuoQQUrwh9Xt_P16drCezwdOCsM3ZK-Tq6VZhW%2Fexec

I tested this URL in multiple browsers and incognito mode. Despite this, after login, I still receive an “Unexpected Error” from SmartThings, with Reference ID: d064fbad-132c-c023-b9fa-69f95d651764 (Error Time: 2025/08/22 20:17:59).

Everything on my side is configured correctly, and I am following the OAuth-In App instructions precisely.

At this point, I am completely stuck. Since this is my own location and I am the main admin, I want to confirm if there is a simpler way to enable OAuth subscriptions for live device updates without going through the multi-user SmartApp workflow.

I would greatly appreciate any guidance you can provide to resolve this issue.

Thank you for your time and support,
Arun B.

Hi, @arunb_97

Correct, since it’s a shared location, you don’t need to authorize it from the other users; it would be duplicating information.

So, the first thing I noticed is that you’re using https://account.smartthings.com when it should be https://api.smartthings.com/. I think it’s due to the way the link was converted by the editor, sorry, I didn’t notice that before.

Also, are you using the correct Client ID? I see you only put “here” I’m guessing it was only to avoid putting that value here, right?

yes that ‘Here’ was only put to avoid exposing the value.

Hi @nayelyz,

I hope this message finds you well. I wanted to extend my heartfelt thanks for your invaluable assistance in our previous discussions. Your guidance has been instrumental in advancing my project, and I truly appreciate the time and expertise you’ve shared.

Thanks to your support, I’ve made significant progress. I’ve successfully navigated the OAuth authentication process, generated a personal access token, and initiated the creation of device subscriptions using the SmartThings API. This has been a major milestone for me.

However, I’ve encountered a challenge related to the regional filter during subscription creation. Despite setting my SmartThings location to India (Asia/Kolkata timezone), the subscription URLs are defaulting to the US region (e.g., us-east-2). This discrepancy is causing issues with my webhook integration, as the regional mismatch is leading to 403 Forbidden errors.

Given this situation, I have two questions:

  1. Regional Filter Configuration: Is there a way to specify or override the region in the subscription creation request to align with my actual location in India?

  2. Location Settings: Could there be a setting or configuration within the SmartThings platform that ensures my subscriptions are created in the correct region, reflecting my India-based location?

I would greatly appreciate any insights or recommendations you could provide to help resolve this issue.

Thank you once again for your continued support. Your assistance has been invaluable, and I look forward to your guidance on this matter.

Best regards,
Arun

Hi @nayelyz

I wanted to give you a quick update on the progress I’ve made:

After completing the OAuth authorization, my Google Apps Script-based SmartApp successfully caught the authorization code. I was able to retrieve the refresh token, access token, and their expiry details — everything is working perfectly on that front. So thanks to your help, that part is fully set up and functional.

Now, the challenge I’m facing is with subscriptions. Whenever I create a subscription for a specific device, the subscription ID is returned correctly. However, the registration URL that is generated seems to require manual activation for the subscription to become active.

Here’s the problem:

  • When I try to manually activate the URL, the filter region defaults to us-east-2, even though all my devices, hub, and home location are in India (Asia/Kolkata).

  • Example subscription info:

{
  "subscriptionId": "dfc7ae50-c81b-48e3-8d33-9b46e93234dc",
  "registrationUrl": "https://spigot-regional.api.smartthings.com/filters/dfc7ae50-c81b-48e3-8d33-9b46e93234dc/activate?filterRegion=us-east-2",
  "name": null,
  "version": 1,
  "subscriptionFilters": null
}

I suspect this is because the API-only app created via the CLI defaults to a US region, and I’m not sure if this can be changed to Asia South / India region.

I’m currently stuck at this point and would greatly appreciate your guidance:

  1. Is there a way to manually or programmatically change the filter region to match my India location?

  2. Or any other workaround to ensure the subscriptions are properly activated for my devices in India?

Thanks again for your help — your insights have been invaluable so far!

Best regards,
Arun

Hi, @arunb_97

Sorry for the delay. When you registered the target URL, did you get a confirmationURL in that same endpoint on your server?

To start receiving Subscription events, you need to “verify” the targetURL you registered:

I would need to check the details of the registrationUrl value you mentioned but using that has never been necessary before. So, I wanted to confirm the above first.

Hi @nayelyz

I cannot understand a couple of things you wrote.

  1. you are using SmartThings. Add a little smartness to your things. but here API | Developer Documentation | SmartThings another url is pointed out. why?
  2. in the documentation I’m not able to find the token url
  3. when I call the url suggested in the documentation I’m redirected to a not existing url

I created the SmartApp since I’ve to integrate other to systems in an automation project, so this will be a server-to-server app.

Is there a way to avoid to request the user to authorize the access maybe granting the access via smartthings portal? Using a certificate, for example. For security reasons the user will not have access to the enterprise server of the Company.

ing.Fontana

I asked the engineering team about this and also tested the URL at the time, and it seemed to work the same, but the recommended URL is https://api.smartthings.com/oauth/authorize

We provide the steps above because there’s no reference on the full instructions to work with OAuth integration. We already reported this.

Please follow the steps as I mentioned above in this post:

Also, make sure the “SmartApp” you created is of type “API_ONLY”, otherwise, it won’t work with any of the URLs.

Following the OAuth process to get an Access Token is the only way of getting authorization. Users must log in and then authorize access to their location for your App.
They will see it in the “Linked services” section of the app, where they can remove the access.
Also, remember the API_ONLY apps have a limit of 500 installations allowed by default, if you will work on a commercial tool, you should see the possibility of a Partnership. Here’s the form for this: OAuth Integrations | Developer Documentation | SmartThings

Ok. Thank you for all the clarifications, also about the number of installations. Now I can proceed with the development and I’ve to find a way to let the responsible people for this automation to authorize the access.

1 Like