# OAuth Device Authorization Grant

Learn how to log users in on TVs and other input-constrained devices with the OAuth Device Authorization grant.

> For the index of this section of the site, see [llms.txt](https://fusionauth.io/docs/llms.txt)

The [Device Authorization Grant](https://fusionauth.io/docs/apis/oauth/device.md) logs users in on devices with no browser or keyboard, such as a TV. The device shows a short code. The user enters the code on a phone or a computer and logs in there. The device then gets the tokens. The screenshots come from the [Device Grant example](https://github.com/FusionAuth/fusionauth-example-device-grant), which also works as a code reference.

## Configure the Application

On the OAuth tab of the Application, enable `Device` in **Enabled grants** and set **Device Verification URL**. For the other OAuth settings, see [Configure Application OAuth Settings](https://fusionauth.io/docs/authentication/oauth.md#configure-application-oauth-settings).

Set **Device Verification URL** to a page in your app, so your app can pass the Tenant Id through the flow. The page can host your own form. The page can also redirect to the themed FusionAuth device page at `/oauth2/device`, which requires the `client_id` and `tenantId` query parameters. After the user submits the code on the FusionAuth device page, FusionAuth logs the user in with an Authorization Code grant and redirects to the **`redirect_uri`**. FusionAuth approves the device when your app exchanges the authorization code for tokens.

To change how long the device code and user code stay valid, or how FusionAuth generates user codes, use the Advanced tab of the [Tenant](https://fusionauth.io/docs/concepts/types/tenants.md#advanced).

## Start the Flow on the Device

The device sends a request to the [Device Authorize endpoint](https://fusionauth.io/docs/apis/oauth/device.md). The [OpenID Configuration](https://fusionauth.io/docs/apis/oauth/openid-configuration.md) also lists the endpoint.

To request scopes on the tokens, send **`scope`**. To get a refresh token, add `offline_access`. FusionAuth applies the scopes when the user enters the code, as described in [Pass the User Code to FusionAuth](#pass-the-user-code-to-fusionauth). For scope policies, custom scopes, and consent, see [Scopes](https://fusionauth.io/docs/authorization/oauth-scopes.md).

![The device prompts the user to connect.](https://fusionauth.io/img/docs/lifecycle/authenticate-users/oauth/oauth-device-connect.png)

The example adds line breaks for readability.

Example HTTP Request

```plaintext
POST /oauth2/device_authorize HTTP/1.1
Host: piedpiper.fusionauth.io
Content-Type: application/x-www-form-urlencoded

client_id=06494b74-a796-4723-af44-1bdb96b48875
    &scope=offline_access
```

The response holds the values the device needs for the rest of the flow:

Example JSON Response

```json
{
  "device_code": "e6f_lF1rG_yroI0DxeQB5OrLDKU18lrDhFXeQqIKAjg",
  "expires_in": 600,
  "interval": 5,
  "user_code": "SFYNPV",
  "verification_uri": "https://piedpiper.fusionauth.io/oauth2/device",
  "verification_uri_complete": "https://piedpiper.fusionauth.io/oauth2/device?user_code=SFYNPV"
}
```

## Poll the Token Endpoint

The device sends the **`device_code`** to the [Token endpoint](https://fusionauth.io/docs/apis/oauth/token.md#complete-the-device-authorization-grant-request) every **`interval`** seconds. Until the user approves the device, FusionAuth returns an `authorization_pending` error. The example adds line breaks for readability.

Example HTTP Request

```plaintext
POST /oauth2/token HTTP/1.1
Host: piedpiper.fusionauth.io
Content-Type: application/x-www-form-urlencoded

client_id=06494b74-a796-4723-af44-1bdb96b48875
    &device_code=e6f_lF1rG_yroI0DxeQB5OrLDKU18lrDhFXeQqIKAjg
    &grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code
```

While the user hasn't approved the device, FusionAuth returns the following error:

Example Pending JSON Error Response

```json
{
  "error": "authorization_pending",
  "error_description": "The authorization request is still pending"
}
```

After the device code expires, FusionAuth returns the following error, and the device must start over:

Example Expired JSON Error Response

```json
{
  "error": "expired_token",
  "error_description": "The device_code has expired, and the device authorization session has concluded."
}
```

For an unknown device code, FusionAuth returns the following error:

Example Invalid JSON Error Response

```json
{
  "error": "invalid_request",
  "error_reason": "invalid_device_code",
  "error_description": "The request has an invalid parameter: device_code"
}
```

## Show the Code to the User

The device shows the **`user_code`** and asks the user to visit the **`verification_uri`**. To save the user from typing the code, the device can show a QR code for the **`verification_uri_complete`**, which fills in the code.

![The device shows the user code and the verification URL.](https://fusionauth.io/img/docs/lifecycle/authenticate-users/oauth/oauth-device-display-code.png)

The user visits the URL and enters the code:

![The FusionAuth device page, where the user enters the user code.](https://fusionauth.io/img/docs/screenshots/authenticate-oauth-device-user-code.png)

## Pass the User Code to FusionAuth

When your app hosts the code form, validate the code with the [Device Validate endpoint](https://fusionauth.io/docs/apis/oauth/device.md#device-validate). For a valid code, the endpoint returns a `200` response with no body.

After validating the code, log the user in with the [Authorization Code grant](https://fusionauth.io/docs/authentication/oauth/authorization-code.md). The Implicit and Password grants also work. Send the code in the **`user_code`** parameter, and FusionAuth approves the device when the login completes. See the [Authorize endpoint](https://fusionauth.io/docs/apis/oauth/authorize.md) and the [Token endpoint](https://fusionauth.io/docs/apis/oauth/token.md).

![The device confirms that the user connected.](https://fusionauth.io/img/docs/lifecycle/authenticate-users/oauth/oauth-device-success.png)

## Receive the Tokens

After the user logs in, the next poll from the device returns the tokens:

Example JSON Response

```json
{
  "access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo",
  "expires_in" : 3600,
  "refresh_token": "ze9fi6Y9sMSf3yWp3aaO2w7AMav2MFdiMIi2GObrAi-i3248oo0jTQ",
  "scope": "offline_access",
  "token_type" : "Bearer",
  "userId" : "3b6d2f70-4821-4694-ac89-60333c9c4165"
}
```

Related

[Authentication OAuth Authorization Code Grant Learn how to log users in with the OAuth Authorization Code grant and PKCE. oauthoauth2](https://fusionauth.io/docs/authentication/oauth/authorization-code.md)

[Authentication OAuth Client Credentials Grant Learn how to get an access token for machine-to-machine requests with the OAuth Client Credentials grant. oauthoauth2](https://fusionauth.io/docs/authentication/oauth/client-credentials.md)

[Authentication OAuth Learn about the OAuth 2.0 and OpenID Connect grants FusionAuth supports for login and single sign-on. oauthoauth2](https://fusionauth.io/docs/authentication/oauth.md)

[Authentication Legacy OAuth Implicit and Password Grants Learn how the legacy OAuth Implicit and Password grants work in FusionAuth, for existing integrations. oauthoauth2](https://fusionauth.io/docs/authentication/oauth/legacy-grants.md)
---

## Other pages in OAuth

> For the full index of this section, see [Authentication](https://fusionauth.io/docs/llms-authentication.txt).

- [Add FusionAuth Login to an App You Build](https://fusionauth.io/docs/authentication/oauth/add-login-to-your-app.md): Learn how to add FusionAuth login to a web, mobile, or single-page app you build with an OpenID Connect library and the OAuth Authorization Code grant.
- [OAuth Authorization Code Grant](https://fusionauth.io/docs/authentication/oauth/authorization-code.md): Learn how to log users in with the OAuth Authorization Code grant and PKCE.
- [CIMD Registration Caching And Lifecycle](https://fusionauth.io/docs/authentication/oauth/cimd-registration-lifecycle.md): Learn how long FusionAuth caches a Client ID Metadata Document, what happens when it expires, and how a CIMD client registration is refreshed or removed.
- [OAuth Client Credentials Grant](https://fusionauth.io/docs/authentication/oauth/client-credentials.md): Learn how to get an access token for machine-to-machine requests with the OAuth Client Credentials grant.
- [OAuth Client Registration | Static and CIMD](https://fusionauth.io/docs/authentication/oauth/client-registration.md): Learn how FusionAuth registers OAuth clients, either ahead of time as Applications or just-in-time from a Client ID Metadata Document.
- [Use DPoP In A Browser App](https://fusionauth.io/docs/authentication/oauth/dpop/browser-app.md): Learn how to bind tokens to the browser with DPoP using the FusionAuth React, Angular, or Vue SDK.
- [Demonstrating Proof-of-Possession (DPoP)](https://fusionauth.io/docs/authentication/oauth/dpop.md): Learn how DPoP binds FusionAuth access and refresh tokens to a key pair that only your client holds.
- [Validate DPoP Requests In Your API](https://fusionauth.io/docs/authentication/oauth/dpop/validate-requests.md): Learn how to check DPoP proofs and DPoP-bound FusionAuth access tokens in your API.
- [Host A Client ID Metadata Document (CIMD)](https://fusionauth.io/docs/authentication/oauth/host-cimd-document.md): Publish a Client ID Metadata Document so your OAuth client can log in to FusionAuth without being registered ahead of time.
- [OAuth](https://fusionauth.io/docs/authentication/oauth.md): Learn about the OAuth 2.0 and OpenID Connect grants FusionAuth supports for login and single sign-on.
- [OAuth Issuer Validation](https://fusionauth.io/docs/authentication/oauth/issuer-validation.md): Learn how to validate the authorization response issuer parameter (RFC 9207) to prevent mix-up attacks.
- [Legacy OAuth Implicit and Password Grants](https://fusionauth.io/docs/authentication/oauth/legacy-grants.md): Learn how the legacy OAuth Implicit and Password grants work in FusionAuth, for existing integrations.
- [Connect claude.ai And chatgpt.com To A FusionAuth-Protected MCP Server](https://fusionauth.io/docs/authentication/oauth/mcp-clients-claude-chatgpt.md): Learn how to connect claude.ai and chatgpt.com to an MCP server protected by FusionAuth using Client ID Metadata Documents.
- [Modes](https://fusionauth.io/docs/authentication/oauth/modes.md): Learn about the eight common ways apps use OAuth and OpenID Connect.
- [OIDC Prompt](https://fusionauth.io/docs/authentication/oauth/prompt.md): Learn about OpenID Connect prompt and example use cases.
- [OAuth Refresh Token Grant](https://fusionauth.io/docs/authentication/oauth/refresh-token.md): Learn how to exchange a refresh token for a new access token with the OAuth Refresh Token grant.
- [OAuth Response Modes](https://fusionauth.io/docs/authentication/oauth/response-modes.md): Learn about OAuth 2.0 response modes (query, fragment, form_post) and when to use each one.
- [Manage Software Tokens](https://fusionauth.io/docs/authentication/oauth/tokens.md): Learn about OAuth2 and OpenID Connect Tokens and how they are used.
- [URL Validation](https://fusionauth.io/docs/authentication/oauth/url-validation.md): Learn about OAuth URL validation policies in FusionAuth.
