OAuth 2.0 Device Flow for IoT Integration
To integrate apps that run on devices with limited input or display capabilities, such as Smart TVs, appliances, and other IoT devices, use the OAuth 2.0 device flow. Command-line apps can also use this flow. Users can connect these apps to Salesforce by accessing a browser on a device with more advanced input capabilities, such as a desktop or mobile device.
Required Editions
| Available in: both Salesforce Classic and Lightning Experience |
| Available in: All Editions |
For example, a customer uses a bluetooth device to control their house lights while they’re away for the evening. You can create an external client app for the bluetooth device to enable this flow.
- The user opens the bluetooth app on their mobile device and clicks Turn On Lights.
- The external client app posts a request to the Salesforce token endpoint.
- Salesforce verifies the request and returns a human-readable user code, verification URL, and device code.
- The bluetooth app displays the device code and instructs the user to enter it at the specified verification URL. The app also begins polling the Salesforce token endpoint for authorization.
- The user clicks the link to the verification URL and enters the code.
- The user then authorizes the app to access their protected data, in this case their home’s location.
- Salesforce sends an access and refresh token to the external client app.
- The bluetooth app can access the user’s home location and turn on the lights.
Let’s walk through the steps in this authorization flow.
- Device Requests Authorization
- Salesforce Returns Verification Codes
- User Authenticates and Authorizes While Device Polls the Token Endpoint
- Salesforce Grants Access Token
Device Requests Authorization
To initiate the authorization flow, the device—via an external client app—posts an authorization request to the Salesforce token endpoint.
For example:
POST /services/oauth2/token HTTP/1.1
Host: login.salesforce.com
Content-Type: application/x-www-form-urlencoded
response_type=device_code&
client_id=3MVG9PhR6g6B7ps7TTI4cP7Mppg3l7tu.MRAYULyVqcmA9hGLpHiiS.Q7rO9yjlmffiBUM6tFpYAlXEkRjHb9&scope=apiInclude these parameters in the request.
| Parameter | Description |
|---|---|
Request Header
|
The request header contains this information:
|
response_type
|
The OAuth 2.0 grant type that the external client app requests. The value for this flow must be device_code. |
client_id
|
The consumer key of the external client app. To access the consumer key, from the External Client App Manager, find the external client app and select Edit Settings from the dropdown. Then expand the OAuth Settings section, and click Consumer Key and Secret. You're sometimes prompted to verify your identity before you can view the consumer key. |
scope
|
Optional. Permissions that define the type of protected resources an external client app can access. You assign scopes to an external client app when you build it, and they’re included with the OAuth tokens during the authorization flow. If you don’t include this parameter, all scopes assigned to the external client app are requested. The scopes passed in this parameter must be a subset of the registered scopes. For valid parameters, see OAuth Scopes. |
Salesforce Returns Verification Codes
After verifying the request, Salesforce returns a human-readable user code, verification URL, and device code.
This sample response returns these values with a 200 success status code.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"device_code":"M01WRzlQaFI2ZzZCN3BzN1RUSTRjUDdNcHBnM2w3dHUuTVJBWVVMeVZxY21BOWhHTHBIaWlTLlE3ck85eWpsbWZmaUJVTTZ0RnBZQWxYRWtSakhiOTsxMC4yMi4zNC45MjsxNDc3Njc0NDg3NTA1O1gxRDlTRUVU",
"user_code":"X1D9SEET",
"verification_uri":"https://acme.my.salesforce.com/setup/connect",
"interval":5
}
The following parameters are included in the response.
| Parameter | Description |
|---|---|
Response Header
|
The response header contains this information:
|
device_code
|
A verification code for the device. This code is valid for 10 minutes. The code can include uppercase letters, lowercase letters, and numbers. Salesforce can change how we format device codes at any time. When you develop integrations that use this flow, don’t make assumptions about the device code format and length. |
user_code
|
A verification code for the end user, sent as an 8-digit alphanumeric code. The user must enter this code at the verification URL. This code is valid for 10 minutes. |
verification_uri
|
The end-user verification URL on the authorization server. The user must enter the user code at this verification URL. With verification through a My Domain login URL or Experience Cloud site URL, the verification_uri reflects the URL that initiated the flow. For example, if the device sends a token request to https://acme.my.salesforce.com/services/oauth2/token, the verification_uri is https://acme.my.salesforce.com/setup/connect. Optionally,
you can add the |
interval
|
The minimum number of seconds that we recommend waiting between polling requests to the token endpoint. |
User Authenticates and Authorizes While Device Polls the Token Endpoint
The client app on the device instructs the user to visit the verification URL on a computer or mobile device and enter the user code. The user opens a browser, navigates to the verification URL, and enters the code displayed on the device. If the code is valid, the user logs in, as needed. After successful login, the user allows the device to access Salesforce account data.
Meanwhile, after displaying the user code and verification URL, the client application on the device polls the token endpoint repeatedly. Polling checks whether the user has authorized access and whether the authorization server has issued the access token.
Here’s an example of a polling request:
POST /services/oauth2/token HTTP/1.1
Host: login.salesforce.com
Content-Type: application/x-www-form-urlencoded
grant_type=device&
client_id=3MVG9PhR6g6B7ps7TTI4cP7Mppg3l7tu.MRAYULyVqcmA9hGLpHiiS.Q7rO9yjlmffiBUM6tFpYAlXEkRjHb9&code=M01WRzlQaFI2ZzZCN3BzN1RUSTRjUDdNcHBnM2w3dHUuTVJBWVVMeVZxY21BOWhHTHBIaWlTLlE3ck85eWpsbWZmaUJVTTZ0RnBZQWxYRWtSakhiOTsxMC4yMi4zNC45MjsxNDc3Njc0NDg3NTA1O1gxRDlTRUVUThe polling request contains these parameters, in addition to the header.
| Parameter | Description |
|---|---|
grant_type
|
The value must be device for this flow. |
client_id
|
The consumer key of the external client app. To access the consumer key, from the External Client App Manager, find the external client app and select Edit Settings from the dropdown. Then expand the OAuth Settings section, and click Consumer Key and Secret. You're sometimes prompted to verify your identity before you can view the consumer key. |
code
|
The authorization server creates an authorization code, which is a short-lived token, and passes it to the client after successful authentication. The client sends the authorization code to the authorization server to obtain an access token and, optionally, a refresh token. |
Salesforce Grants Access Token
If the user has authorized access, the Salesforce responds with a success message and the access token along with other values. For example:
{
"access_token": "00DD00000008Uw2!ARkAQGppKf6n.VwG.EnFSvi731qWh.7vKfaJjL7h49yutIC84gAsxMrqcE81GjpTjQbDLkytl2ZwosNbIJwUS0X8ahiILj3e"
"refresh_token": "your token here"
"signature": "hJuYICd2IHsjyTcFqTYiOr8THmgDmrcjgWaMp13X6dY="
"scope": "api"
"instance_url": "https://yourInstance.salesforce.com"
"id": "https://login.salesforce.com/id/00DD00000008Uw2MAE/005D0000001cAGmIAM"
"token_type": "Bearer"
"issued_at": "1477674717112"
}These parameters are included in the example response.
| Parameter | Description |
|---|---|
access_token
|
OAuth token that an external client app uses to request access to a protected resource on behalf of the client application. Additional permissions in the form of scopes can accompany the access token. |
refresh_token
|
Token obtained from the web server, user-agent, or hybrid app token flow. This
value is a secret. Take appropriate measures to protect it. This parameter is
returned only if your external client app is set up with a
refresh_token scope. |
signature
|
Base64-encoded HMAC-SHA256 signature signed with the client_secret. The signature can include the
concatenated ID and issued_at value, which you
can use to verify that the identity URL hasn’t changed since the server sent
it. |
scope
|
The scopes associated with the access token. Scopes further define the type of protected resources that the client can access. You assign scopes to an external client app when you build it, and they’re included with the OAuth tokens during the authorization flow. For valid parameters, see OAuth Scopes. |
instance_url
|
A URL indicating the instance of the user’s org. For example: https://yourInstance.salesforce.com/. |
id
|
An identity URL that can be used to identify the user and to query for more information about the user. See Identity URLs. |
token_type
|
A Bearer token type, which is used for all
responses that include an access token. |
issued_at
|
Time stamp of when the signature was created in milliseconds. |

