Implement the OAuth 2.0 Flow
Your app uses the standard OAuth 2.0 specification's authorization code flow to connect to a user's SmartThings account.
This is a three-step process:
- Initiate Authorization: Redirect the user to SmartThings to authorize.
- Handle the Callback: Receive a callback with an authorization code.
- Exchange Code for Tokens: Exchange your authorization code for access and refresh tokens.
Step 1: Initiate Authorization​
When a user wants to connect their SmartThings account, redirect their browser to the SmartThings authorization URL:
https://api.smartthings.com/v1/oauth/authorize?client_id={clientId}&scope={scopes}&response_type=code&redirect_uri={redirectUri}&state={state}
| Parameter | Description |
|---|---|
client_id | Your app's Client ID, received during app registration. |
scope | URL-encoded, space-separated list of requested permissions (e.g., r:locations:*%20r:devices:*%20x:devices:*). |
response_type | Must be code. |
redirect_uri | Your app's callback URL, which must match one of the redirect URIs registered with your app. |
state | A random, unguessable string that your app generates and stores in the user's session. Used to prevent CSRF attacks -- you must verify this value when receiving the callback. |
The user will see the SmartThings authorization page, where they log in (if not already) and grant your app the requested permissions.
Step 2: Handle the Callback​
After the user authorizes your app, SmartThings redirects their browser to your GET /oauth/callback endpoint with two query parameters:
GET /oauth/callback?code={authorizationCode}&state={state} HTTP/1.1
| Parameter | Description |
|---|---|
code | The authorization code to exchange for tokens. This code is short-lived and single-use. |
state | The same value you provided in Step 1. |
Validate the State Parameter​
Before proceeding, verify that the state parameter matches the value you stored in the user's session during Step 1. If it does not match, reject the request - it may be a CSRF attack.
Handle Authorization Errors​
If the user clicks Deny on the SmartThings authorization page, SmartThings redirects their browser to your callback endpoint with an error parameter instead of an authorization code:
GET /oauth/callback?error=access_denied&state={state} HTTP/1.1
Before attempting to exchange a code for tokens, check for the presence of the error parameter. If error=access_denied is present, verify the state parameter, then abort the token exchange process and display an appropriate message in your application's user interface.
Step 3: Exchange Code for Tokens​
Exchange the authorization code for an access token and refresh token by making a POST request to the SmartThings token endpoint.
Request​
POST https://api.smartthings.com/v1/oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: Basic {base64(clientId:clientSecret)}
Accept: application/json
grant_type=authorization_code&code={authorizationCode}&client_id={clientId}&redirect_uri={redirectUri}
The Authorization header uses HTTP Basic authentication with your Client ID as the username and Client Secret as the password, Base64-encoded. For example, if your Client ID is my-client-id and Client Secret is my-client-secret, the header value is Basic followed by the Base64 encoding of my-client-id:my-client-secret.
The request body is form-encoded with the following parameters:
| Parameter | Description |
|---|---|
grant_type | Must be authorization_code. |
code | The authorization code received in the callback. |
client_id | Your app's Client ID. |
redirect_uri | The same redirect URI used in the authorization request. |
Response​
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"access_token": "68e5657b-2892-4aa2-902b-3461116e6ea6",
"token_type": "bearer",
"refresh_token": "55a3a216-dffd-4478-91d0-ca0b5767606b",
"expires_in": 86001,
"scope": "r:devices:*",
"access_tier": 0,
"developer_account_id": "bcf8648b-b94b-43bf-aed8-8eac51fd866e",
"installed_app_id": "11b9ea69-1399-43c4-bd4b-3166449ff8fb",
"iot_account_id": "bcf8648b-b94b-43bf-aed8-8eac51fd866e",
"owner_account_id": "bcf8648b-b94b-43bf-aed8-8eac51fd866e"
}
| Field | Description |
|---|---|
access_token | Bearer token for authenticating API requests to SmartThings. |
token_type | Always bearer. |
refresh_token | Token used to obtain a new access token when the current one expires. |
expires_in | Token lifetime in seconds (86399 seconds is approximately 24 hours). |
scope | The scopes that were granted, which may differ from what was requested. |
installed_app_id | The unique identifier for this app installation. You will need this for subsequent API calls such as managing subscriptions and retrieving location information. |
Token Storage​
Your app must persist the following values for each connected user:
- Access token -- Used to authenticate API requests.
- Refresh token -- Used to obtain a new access token before or after expiry.
- Installed App ID -- Used to identify this app installation in API calls.
- Token expiry time -- To know when the access token needs refreshing.
These values should be stored securely, as the tokens grant access to the user's SmartThings devices. See Token Management for details on refreshing tokens.
Up Next​
Next, learn how to manage your OAuth tokens to maintain uninterrupted access to the SmartThings API. We'll cover handling token expiration, implementing proactive and reactive refresh strategies, and best practices for secure token storage.