Using OAuth 2.0 for TV and Limited Input Device Applications

We expose standards-based OAuth 2.0 endpoints to support applications on devices that don't have access to a browser and/or are constrained with limited input capabilities, such as TVs, game consoles and printers. Such apps are distributed to individual devices, and as such it is assumed they cannot keep secrets. They may access user data APIs while the user is present, or when running in the background.

If you are writing an app for a platform that has access to the browser and full input capabilities, such as Android, iOS, macOS, Linux, and Windows (including the Universal Windows Platform), even if your app is a command line tool without a graphical interface, you should use the methods described in OAuth 2.0 for Mobile and Desktop Applications.

Important Note: The TV and Limited Input Device OAuth endpoints described herein only support a limited set of scopes.


Applications that run on devices with limited input capabilities (such as TVs, game consoles, video cameras, and printers) can access a Google API on behalf of a user, but the user must have separate access to a computer or device with richer input capabilities. The flow is as follows:

  • Your application begins this flow with a request to a Google URL with a set of parameters. The response includes a device code, a user code, a URL, an expiration, and a suggested polling interval.
  • After receipt of this response, your application shows the user the URL and the user code, and instructs the user to open a browser, navigate to the URL, and enter the code.
  • The user switches to a device or computer with richer input capabilities, launches a browser, navigates to the URL specified on the limited-input device, logs in, and enters the code.
  • In the background, your application polls a Google endpoint for an access token and a refresh token. These tokens will only be returned to your application after the user has logged in and approved the request.

You can access only a limited set of scopes with this flow.

The user logs in on a separate device that has a browser.

Given the variety in capabilities and runtime environments of these devices, the examples shown in this document use the curl command line utility. It should be a trivial exercise to port the curl commands to various languages and runtimes.

Obtaining a user code

As in all OAuth 2.0 scenarios, you first need to set up a project in the Google API Console and obtain a client ID and client secret.

After you have the client ID and client secret, you send an HTTP POST to the OAuth 2.0 device endpoint at with your client_id and a list of scopes. Unlike the other OAuth 2.0 flows, response_type and redirect_uri are not needed in the device flow. The following is an example request for a user code:

POST /o/oauth2/device/code HTTP/1.1
Content-Type: application/x-www-form-urlencoded

or using curl:

curl -d " profile"

The response is returned in a JSON object:

  "device_code" : "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",
  "user_code" : "GQVQ-JKEC",
  "verification_url" : "",
  "expires_in" : 1800,
  "interval" : 5

The user_code and verification_url from the JSON object should be shown to your user. The idea is to ask the user to go to a browser, navigate to the verification_url URL, and enter the user_code. The user_code is case sensitive, so the user will need to enter the code exactly as it appears in the response. The device_code, expires_in, and interval fields will be used in the Obtaining access tokens and refresh tokens section.

Displaying the user code

The values of the verification_url and user_code are subject to change. Design your UI in a way that can handle the following limits:

  • user_code must be displayed in a field that can handle 15 'W' size characters. In other words, if you can display the code WWWWWWWWWWWWWWW correctly, your UI is valid.
  • verification_url should be wide enough to handle a URL string that is 40 characters long.

Both strings may contain any printable character from the US-ASCII character set. Don't make assumptions beyond this as to the content of the strings. Specifically, do not modify the user_code string in any way (such as changing the case or inserting other formatting characters), as your app may break when we change the code in the future. Don't modify the verification_url, except to optionally remove the scheme for display. If you do plan to strip off the scheme (e.g. "http://") from the URL for display reasons, be sure your app can handle both "http" and "https" variants.

Reminder: to avoid your application breaking in the future, test your application with a 15-character 'W' user code, and don't alter the string when displaying.

When the user navigates to verification_url URL, they will see a page similar to the following:

After the user enters the user_code, they will be asked to login to Google, and will see a consent screen (shown below).

If the user clicks "Allow", then your application can obtain an access and refresh token that will grant your application access to one or more Google APIs. As in all OAuth 2.0 scenarios, the scope parameter controls the access your application has to a Google API.

Obtaining access tokens and refresh tokens

After your application has shown the user the user_code and the verification_url, your application may begin polling a Google endpoint with the device_code that was returned with the user_code and verification_url. The URL of the endpoint to poll is, and the interval between requests is specified as the interval in seconds. Such a request is shown below:

POST /oauth2/v4/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

or using curl:

curl -d "
-H "Content-Type: application/x-www-form-urlencoded"

If the user has not yet approved the request, the response will appear as follows:

  "error" : "authorization_pending"

Your application should repeat these requests at the rate that does not exceed the value of interval field. If your application polls too quickly, then the response will appear as follows:

  "error" : "slow_down"

Once the user logs in and grants your application access to a Google API, the next polling request will result in an access and refresh token (shown below).

  "access_token" : "ya29.AHES6ZSuY8f6WFLswSv0HELP2J4cCvFSj-8GiZM0Pr6cgXU",
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "refresh_token" : "1/551G1yXUqgkDGnkfFk6ZbjMLMDIMxo3JFc8lY8CAR-Q"

Upon receipt of this response, your application may use the access token in Google API requests. Access tokens have a limited lifetime. If your application needs access to an API over a long period of time, then it can use the refresh token to obtain a new access token (see Using a refresh token). If your application needs this type of access, then it should store the refresh token for later use.

Calling a Google API

After your application obtains an access token, you can use the token to make calls to a Google API on behalf of a given user account or service account. To do this, include the access token in a request to the API by including either an access_token query parameter or an Authorization: Bearer HTTP header. When possible, the HTTP header is preferable, because query strings tend to be visible in server logs. In most cases you can use a client library to set up your calls to Google APIs (for example, when calling the Drive API).

You can try out all the Google APIs and view their scopes at the OAuth 2.0 Playground.

HTTP GET examples

A call to the drive.files endpoint (the Drive API) using the Authorization: Bearer HTTP header might look like the following, though you'll need to specify your own access token:

GET /drive/v2/files HTTP/1.1
Authorization: Bearer 1/fFBGRNJru1FQd44AzqT3Zg

Here is a call to the same API for the authenticated user (me) using the access_token query string parameter:


curl examples

You can test these commands with the curl command-line application. Here's an example that uses the HTTP header option (preferred):

curl -H "Authorization: Bearer 1/fFBGRNJru1FQd44AzqT3Zg"

Or, alternatively, the query string parameter option:


Using a refresh token

Access tokens expire. An API will indicate that an access token has expired when it returns a 401 status code. To obtain a new access token, make a request to the token endpoint and include the client_id, client_secret, refresh_token, and grant_type parameters (shown below).

POST /oauth2/v4/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

Note that there are limits on the number of refresh tokens that will be issued; one limit per client/user combination, and another per user across all clients. You should save refresh tokens in long-term storage and continue to use them as long as they remain valid. If your application requests too many refresh tokens, it may run into these limits, in which case older refresh tokens will stop working.

Allowed scopes

When you use the OAuth 2.0 flow for devices, you can access only the following scopes:

OpenID Connect, Google Sign-In
Analytics Configuration and Reporting APIs
Calendar API
Contacts API
Cloud Print API
Cloud Storage API
Fitness REST API
Fusion Tables API
YouTube Data and Live Streaming APIs