During the authorization process, Google OAuth may return an error. Use this
guide to troubleshoot the most common errors during this process.

## Troubleshooting

To learn more about Google OAuth, see [Using OAuth 2.0 to Access Google
APIs](https://developers.google.com/identity/protocols/oauth2).

### Refresh token keeps expiring

Refresh tokens can stop working after 7 days if the client ID is not approved is
one possible cause. The 7-day token expiration is not related to Commercial
or Sandbox approvals. A service or user account needs to get their OAuth
2.0 client ID approved and put into production to get longer token lifespans.
See [Refresh token expiration](https://developers.google.com/identity/protocols/oauth2#expiration) for more
information.

### Access denied

If you've set up your [OAuth consent screen](https://console.developers.google.com/apis/credentials/consent/edit) in Google Cloud and
the **User type** is **External** , you will get an "Access denied" error if you
attempt to account link with a Google account that is not listed as a test user
for your app. Make sure to add the Google account to the **Test users** section
in your [OAuth consent screen](https://console.developers.google.com/apis/credentials/consent/edit).

### Partner Connections Manager (PCM) error

For help with any errors encountered when accessing
PCM, see
[Partner Connections Manager (PCM)
Error Reference](https://developers.google.com/nest/device-access/reference/errors/pcm).

### Google hasn't verified this app

The SDM API uses a restricted scope, which means that any
apps that use this scope during authorization will be "unverified" unless
[OAuth API Verification](https://developers.googleblog.com/2019/09/get-smart-about-preparing-your-app-for-OAuth-verfication.html) is completed. **When using Device Access for
personal use, OAuth API Verification is not required.**

You may see a "Google hasn't verified this app" screen during the authorization
process, which appears if the `sdm.service` scope is not configured on
your [OAuth consent screen](https://console.developers.google.com/apis/credentials/consent/edit) in Google Cloud. This screen can be
bypassed by clicking the **Advanced** option and then clicking **Go to *Project
Name* (unsafe)**.

See [Unverified app
screen](https://support.google.com/cloud/answer/7454865#unverified-app-screen)
for more information.

### Invalid client

When attempting to get an access or refresh token, you will get an "Invalid
client" error if you provide an incorrect OAuth 2.0 Client Secret. Make sure the
`client_secret` value you're using in access and refresh token calls is the one
for the OAuth 2.0 Client ID being used, as found in your
[Google Cloud
Credentials](https://console.developers.google.com/apis/credentials)
page.

### Invalid request, missing required scope

After granting permissions in PCM, you might run into a
"Invalid request" error of "Missing required parameter: scope". Make sure the
`scope` value you're using in authorization calls is the same as the one you set for the OAuth 2.0 Client,
as found in your [Google Cloud
Credentials](https://console.developers.google.com/apis/credentials)
page.

### Redirect uri mismatch

When going through authorization, you might run into a "Redirect uri mismatch"
error. Make sure the `redirect_uri` value you're using in authorization calls is
the same as the one you set for the OAuth 2.0 Client, as found in your
[Google Cloud
Credentials](https://console.developers.google.com/apis/credentials)
page.

## Quick reference

Use this reference to quickly implement the steps to authorize a
user and link their Google account
.

To use this quick reference, edit each placeholder variable in the code samples
with the values for your specific integration, and copy and paste as needed:

### 1 PCM

Direct the user to the PCM link in your
app, replacing:

1. <var translate="no">project-id</var> with your Device Access Project ID
2. <var translate="no">oauth2-client-id</var> with the OAuth2 Client ID from your [Google Cloud
   Credentials](https://console.developers.google.com/apis/credentials)
3. <var translate="no">redirect-uri</var> with a Redirect URI specified for the OAuth2 Client ID you are using
4. <var translate="no">scope</var> with one of your [available
   scopes](https://developers.google.com/nest/device-access/reference/errors/authorization#oauth_20_scopes)

```
https://nestservices.google.com/partnerconnections/project-id/auth?redirect_uri=redirect-uri&access_type=offline&prompt=consent&client_id=oauth2-client-id&response_type=code&scope=https://www.googleapis.com/auth/scope
```

### 2 Auth Code

After granting permissions through PCM for
your selected scope, the user should be redirected to your specified Redirect
URI. The Authorization Code is returned as the `code` parameter in the URL,
which should be in this format:

```
redirect-uri?code=authorization-code&scope=https://www.googleapis.com/auth/scope
```

### 3 Access Token

Use the authorization code to retrieve an access token, that
you can use to call the SDM API on
behalf of the user.

Make a POST call to Google's OAuth
endpoint, replacing:

1. <var translate="no">oauth2-client-id</var> and <var translate="no">oauth2-client-secret</var> with the OAuth2 Client ID and Client Secret from your [Google Cloud
   Credentials](https://console.developers.google.com/apis/credentials)
2. <var translate="no">authorization-code</var> with the code you received in the previous step
3. <var translate="no">redirect-uri</var> with a Redirect URI specified for the OAuth2 Client ID you are using

Google OAuth returns two tokens, an access token and a
refresh token.

### Request

    curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?client_id=oauth2-client-id&client_secret=oauth2-client-secret&code=authorization-code&grant_type=authorization_code&redirect_uri=redirect-uri'

### Response

    {
      "access_token": "access-token",
      "expires_in": 3599,
      "refresh_token": "refresh-token",
      "scope": "https://www.googleapis.com/auth/scope",
      "token_type": "Bearer"
    }

### 4 API Call

Authorization is not complete until you make
an API call with the user's access token. This
initial call finishes the authorization process and enables events.

> [!WARNING]
> **This call is required as part of authorization.** Until this call is made:  
>
> - The authorized project will not appear on PCM.
> - Events will not be published.

You **must** use one of the
API calls listed for the specified scope to complete authorization.

### sdm.service

### devices

See the
[`devices.list`](https://developers.google.com/nest/device-access/reference/rest/v1/enterprises.devices/list)
API reference for more information.

    curl -X GET 'https://smartdevicemanagement.googleapis.com/v1/enterprises/project-id/devices' \
        -H 'Content-Type: application/json' \
        -H 'Authorization: Bearer access-token'

### 5 Refresh Token

Access tokens for the SDM API are only
valid for 1 hour, as noted in the `expires_in` parameter returned by Google OAuth. If
your access token expires, use the refresh token to get a new one.

Make a POST call to Google's OAuth
endpoint, replacing:

1. <var translate="no">oauth2-client-id</var> and <var translate="no">oauth2-client-secret</var> with the OAuth2 Client ID and Client Secret from your [Google Cloud
   Credentials](https://console.developers.google.com/apis/credentials)
2. <var translate="no">refresh-token</var> with the code you received when initially getting the access token.

Google OAuth returns a new access token.

### Request

    curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?client_id=oauth2-client-id&client_secret=oauth2-client-secret&refresh_token=refresh-token&grant_type=refresh_token'

### Response

    {
      "access_token": "new-access-token",
      "expires_in": 3599,
      "scope": "https://www.googleapis.com/auth/scope",
      "token_type": "Bearer"
    }