Build your app

TVs, CLIs and devices

Sign users in on devices without a keyboard or browser with the device authorization grant (RFC 8628).

View .md llms.txt

Smart TVs, consoles, CLIs and other devices without a good keyboard or browser use the device authorization grant (RFC 8628): the device shows a short code, the user enters it on their phone or computer, and the device receives tokens once they approve.

#Set up the application

Applications → Create application → TV & Device. It's a public client (no secret) with the device code and refresh token grants.

#1. Ask for a code

bash
curl -X POST https://acme.9in.io/oauth/device/authorize \
  -d client_id=app_tv123 \
  -d scope="openid profile offline_access"
  # -d audience=https://api.acme.com   tokens for your API
json
{
  "device_code": "Ag5m…",
  "user_code": "BDWP-HQXZ",
  "verification_uri": "https://acme.9in.io/device",
  "verification_uri_complete": "https://acme.9in.io/device?user_code=BDWP-HQXZ",
  "expires_in": 600,
  "interval": 5
}

Show the user verification_uri and user_code (or a QR code of verification_uri_complete, which fills the code in). Codes are 8 letters without vowels, so they never spell words, and expire after 10 minutes.

#2. Poll for tokens

Every interval seconds:

bash
curl -X POST https://acme.9in.io/oauth/token \
  -d grant_type=urn:ietf:params:oauth:grant-type:device_code \
  -d device_code=Ag5m… \
  -d client_id=app_tv123
ResponseMeaningWhat to do
400 authorization_pendingThe user hasn't finished yetKeep polling
400 slow_downYou polled too fastAdd 5 seconds to the interval
400 access_deniedThe user declinedStop; offer to start over
400 expired_token10 minutes passedStart over with a new code
200 with tokensApprovedStore the tokens and stop polling

#3. Use the tokens

The response is the same as any sign-in: an access token, an ID token with openid, and a refresh token with offline_access. Refresh with grant_type=refresh_token and your client_id; refresh tokens rotate, so store the new one each time.

#What the user sees

At verification_uri the user signs in (if they aren't already), types the code, sees which app is asking and for what, and approves. The page is themed and translated like every other hosted page.