OpenPass device grant flow
TIP: This guide is for implementing code for various functions using our API endpoints. The Trade Desk recommends using an SDK because it is the easiest option. It can do a lot of the work for you, such as managing security features and returning the user's ID token and access token.
The device grant flow, also known as the device flow grant, uses OAuth 2.0 authentication for single sign-on (SSO) and is intended for devices with limited input capabilities like a smart TV, game console, or Internet of Things (IoT) device.
Here's what the device grant flow looks like:
- The device shows the user a unique code and asks them to visit a specific authorization endpoint on another device, like a smartphone or computer, to register the device.
- The user visits the authorization endpoint on the separate device and enters the code.
- The authorization server verifies the code and prompts the user to authenticate and authorize the device.
- When the user authorizes the device, the device will exchange a device code for an access token.
NOTE: For web apps where entering an authentication code on a separate device is not needed, use the general API integration guide.
Setup and requirements
Before implementing the authentication flow, be sure to register the client application with OpenPass. See the following for more information.
API version
The current version of the OpenPass API is v1.
Open API spec
Download the OpenAPI specification using the following endpoint: GET /.well-known/jwks.
OpenPass open ID connect URLs
The following table lists the OpenPass OIDC URLs.
| Endpoints | URL |
|---|---|
| GET /v1/api/authorize | https://auth.myopenpass.com/v1/api/authorize |
| POST /v1/api/token | http://auth.myopenpass.com/v1/api/token |
Implement OpenPass device authorization
IMPORTANT: Be sure to provide a list of redirect URIs when setting up your account. This is required for the flow to work properly.
If you choose to implement OpenPass using the API instead of an SDK, you'll need to implement code to complete the various functions using the OpenPass API endpoints.
To implement device authorization, use the following steps:
- Initiate Device Authorization
- Exchange Authorization Code for Tokens
Initiate device authorization
To initiate the device grant flow, the client must send a request to the OpenPass endpoint after user confirmation. Be sure to register the client application first with OpenPass.
IMPORTANT: The registered application's client ID is required to use the device authorization APIs.
The request must have the following specifications:
- Device Authorize URL:
https://auth.myopenpass.com/v1/api/authorize-device - Content Type:
application/x-www-form-urlencoded - Http Method:
POST
Curl
This example sends a request in Curl.
curl --location 'https://auth.myopenpass.com/v1/api/authorize-device' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=a6d7cfb087a14d4fb18ac7e56b32ee77' \
--data-urlencode 'scope=openid'
JavaScript
This example sends a request to the authorize-device API in JavaScript.
const url = 'https://auth.myopenpass.com/v1/api/authorize-device';
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
const authorizeDevice = async (client_id, scope) => {
const data = new URLSearchParams({
client_id,
scope
});
try {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: data
});
const responseData = await response.json();
console.log('Response:', responseData);
} catch (error) {
console.error('Error:', error);
}
};
// The OpenPass client ID of the application registered with OpenPass.
const clientId = "a6d7cfb087a14d4fb18ac7e56b32ee77";
// The OAuth scope
const scope = "openid"
// Send the request to initiate the device authorization grant.
authorizeDevice(clientId, scope);
Successful response
This example shows a successful response.
{
"device_code": "BssE3cSE8tGw2wVp0Ah7agAAAAAAAAAA",
"user_code": "T4UGZ6RK",
"verification_uri": "https://auth.myopenpass.com/device",
"verification_uri_complete": "https://auth.myopenpass.com/device?user_code=T4UGZ6RK",
"expires_in": 500,
"interval": 5
}
Failed response
If there is an error, the following response is returned.
{
"error": "invalid_scope",
"error_description": "Invalid scope, expecting openid"
}
Exchange authorization code for tokens
After the device has initiated the device authorization process, it needs to exchange the device code for the OpenPass authorization tokens.To achieve this, the client device must poll the device token endpoint. The polling should continue while the OpenPass authorization server indicates that the device authorization is in a pending state. The polling is necessary because the device authorization process is asynchronous, and it depends on the user completing the device registration process on a secondary device.
The polling interval is specified by the interval parameter returned by the device authorization endpoint. If the client device polls too frequently, the OpenPass authorization server might return a response with the slow_down error code. In this case, the device should adjust the polling interval accordingly.
The client must send a request to the device authorization token endpoint with the following specifications:
- Device Authorize URL:
https://auth.myopenpass.com/v1/api/device-token - Content Type:
application/x-www-form-urlencoded - HTTP Method:
POST
Curl
This example sends a request in Curl.
curl --location 'https://auth.myopenpass.com/v1/api/device-token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: __openpass-session=eyJpZCI6ImY2MDBhMDc1NGEwOWNiNGVmYjAyMTFkY2M2NWE2NTQ2IiwidGltZW91dCI6MTgwMDAwMCwibGFzdEFjY2Vzc2VkIjoxNjg4NzU5NDExODg1LCJ2ZXJzaW9uIjowLCJkYXRhIjp7fX0.TJRilsO0NfvEl6q2VZ4V6JkmQqZ9xy-4JMlJZ7KxlG4' \
--data-urlencode 'client_id=a6d7cfb087a14d4fb18ac7e56b32ee77' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
--data-urlencode 'device_code=jNUoclKIhItnK7eqKzv8WgAAAAAAAAAA'
JavaScript
This example polls the device token endpoint in JavaScript.
// The OpenPass token endpoint URL
const tokenEndpoint = 'https://auth.myopenpass.com/v1/api/device-token';
// The OpenPass registered application client id
const clientId = "a6d7cfb087a14d4fb18ac7e56b32ee77";
// The OAuth Grant Type
const grantType = "urn:ietf:params:oauth:grant-type:device_code"
const pollDeviceTokenEndpoint = async (deviceCode, interval, expiryTime) => {
const startTime = Date.now();
const endTime = startTime + (expiryTime * 1000);
try {
while (Date.now() < endTime) {
const response = await fetch(tokenEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
client_id: clientId,
grant_type: grantType,
device_code: deviceCode
})
});
const responseData = await response.json();
if (response.status === 200) {
console.log('Device authorization complete!');
console.log('Access Token:', responseData.access_token);
console.log('Token Type:', responseData.token_type);
console.log('Expires In:', responseData.expires_in);
break;
} else if (response.status === 400 && responseData.error === 'authorization_pending') {
console.log('Device authorization pending... Polling will continue');
} else {
console.log('Error:', responseData.error);
break;
}
await new Promise((resolve) => setTimeout(resolve, interval * 1000));
// Check if the current time exceeds the end time
if (Date.now() >= endTime) {
console.log('Polling time expired. Device authorization incomplete.');
break;
}
}
} catch (error) {
console.error('Error:', error);
}
};
// The values of these variables are returned from the authorize-device endpoint.
const interval = 5; // polling interval in seconds
const expiryTime = 60; // expiry time in seconds
// The device code generated by the authorize device endpoint.
const deviceCode = "uridUJmSKSDQAqAduHmTOgAAAAAAAAAA";
pollDeviceTokenEndpoint(deviceCode, interval, expiryTime);
Successful response
The following shows an example of a successful response.
{
"id_token": "eyJraWQiOiJUc1F0cG5ZZmNmWm41ZVBLRWFnaDNjU1lGcWxnTG91eEVPbU5YTVFSUWVVIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJlMWU2ZTgwNC1iZDYyLTRhNGEtOTNjMy1mNDFjODg0ZTA4NDEiLCJhdWQiOiJhNmQ3Y2ZiMDg3YTE0ZDRmYjE4YWM3ZTU2YjMyZWU3NyIsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODg4OCIsImV4cCI6MTY5MTM1MjI5OSwiaWF0IjoxNjg4NzYwMjk5LCJlbWFpbCI6InRlc3RAdGVzdC5jb20ifQ.CdVFqyDtj8L-7scnzNLl8I0DjUa32hHHveYyEdMoYHm_cwBOaEQ8U4B3eU459vP86hP_sR0b62U6bGoRxSL6zlh7ZVnfjOrp6X7mZ9j4QavLd8ayTLnE2VMcPZxSfs8jhMsKrQBfaE8rnaN3Z1pRPLpp_G6CKTyTL2s3M8Y-OkkpwhLN-4vnM6_Em2C3xbkjv81Z5k9RoeYZDqSUtsXv6g53zN_TSZyg4j-fVn5Bd9xu1OwgIK93LrlVzhMQZ77I865s6xihEgw26uAytZb4WG2LX-i9Qy9y2XR8dw-uNbQcJGOQzNg-aFhOIHhwvzVu31-iF9iG5Yo347yKlYxU6A",
"access_token": "eyJraWQiOiJUc1F0cG5ZZmNmWm41ZVBLRWFnaDNjU1lGcWxnTG91eEVPbU5YTVFSUWVVIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJlMWU2ZTgwNC1iZDYyLTRhNGEtOTNjMy1mNDFjODg0ZTA4NDEiLCJhdWQiOiJhNmQ3Y2ZiMDg3YTE0ZDRmYjE4YWM3ZTU2YjMyZWU3NyIsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODg4OCIsImV4cCI6MTY4ODg0NjY5OSwiaWF0IjoxNjg4NzYwMjk5fQ.U3nTg2mtevgCXo-jRMgD3BFR_h3IxoTGY5soZHNReOG7Q_kdhzg_81GV6AjeBoZCpY2i6T_7qHXNPjVuOSfPqBNaSMIJUg--cCB9j02C5x-bG_zUa03GnagYNg_anbJDbqKCb-SWDI8_gelbnIxf8jJ0NaCXB7Fa7jf-Zq93fd1BgNi1XHQYCg6ZkdozYgooOQ5sYVaBkn9Z8-E39PIWq2n_ILNMeMYyiRn5olE1kK2_TkENJ1DkKQvYqCbetydOmWK_DcYthw9Uev2EmbgQg6PctqxjR_gmzo59efmmL-7Jo73YEmqU8Q4mBzhxS8Kip1dwQvBO7Fy4VGXh9EvxVQ",
"token_type": "Bearer",
"expires_in": 86400
}
Failed response
If there is an error, the following response is returned.
{
"error": "invalid_client",
"error_description": "Invalid clientId, clientId is required"
}
The following table summarizes the parameters sent as part of the HTTP POST request body. For details, see POST v1/api/device-token.
| Parameter | Description |
|---|---|
client_id |
Provides you the unique ID from The Trade Desk for your client. If you don't have a client_id value, ask your contact at The Trade Desk. |
grant_type |
The OAuth grant type must be urn:ietf:params:oauth:grant-type:device_code. |
device_code |
Returns the device code as part of the authorize-device response. |
Authorization complete
When the device authorization process is complete, the OpenPass authorization server returns the OpenPass authorization tokens to the client device. The following table summarizes the response returned from the device token API endpoint.
| Parameter | Description |
|---|---|
id_token |
The identity token JSON Web Token (JWT). |
access_token |
The access token JWT. |
token_type |
The type of token. For OpenPass, it is always Bearer. |
Additional resources
For more information, see the following pages:
- API reference
- Security considerations
- Authentication tokens
- Integration best practices
- Co-branding guidelines