With your Google Cloud and Device Access projects created, you
can authorize a Google account with a supported Google Nest device for the
SDM API.

## Link your account

To view structures and devices, you must link a Google account to your
Device Access project using the PCM.
PCM allows the user to grant permission to
allow developers to access their structures and device data.

In this guide, you serve as both the user and the developer.

> [!NOTE]
> **Note:** If you didn't copy your OAuth 2.0 Client ID and Client Secret values earlier, get it now from the [Google Cloud
> Credentials](https://console.developers.google.com/apis/credentials) page.

1. Open the following link in a web
   browser, 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)

   ```
   https://nestservices.google.com/partnerconnections/project-id/auth?redirect_uri=https://www.google.com&access_type=offline&prompt=consent&client_id=oauth2-client-id&response_type=code&scope=https://www.googleapis.com/auth/sdm.service
   ```
2. If you have signed into Google with multiple accounts recently, you may be presented with an initial **Choose an account** screen with a list of your Google accounts. If so, select the Google account tied to the device(s) you wish to authorize for Device Access.
3. The **Google Nest permissions** screen is PCM itself. Here you can grant structure and device permissions. Toggle on the permissions for your home (Step 1) and any devices in that home that are supported by the SDM API (Step 2), then click **Next**.
4. On the **Choose an account to continue to *Project Name*** screen, where *Project Name* is the name of your Google Cloud project, select the Google account you wish to authorize for the SDM API. Use the same Google account as before.
5. After choosing an account, you may get a warning screen that states **Google hasn't verified this app** . If so, to continue, click the **Advanced** option and then click **Go to *Project Name* (unsafe)** . See [Google hasn't verified this app](https://developers.google.com/nest/device-access/authorize#google_hasnt_verified_this_app) for more information.
6. On the **Grant *Project Name* permission** screen, click **Allow** to give the project permission to access your Google account.
7. On the **Confirm your choices** screen, make sure the permissions you wish to grant are checked and click **Allow** to confirm.
8. You should be redirected to
   https://www.google.com. The Authorization Code is returned as the `code` parameter in the URL,
   which should be in this format:

   ```
   https://www.google.com?code=authorization-code&scope=https://www.googleapis.com/auth/sdm.service
   ```
9. Copy the authorization code.

## Get an access token

<br />

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

<br />

1. Open a terminal and run
   the following `curl` command, 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

       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=https://www.google.com'

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

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

   Copy both these values. The access token is used to call the SDM API and the refresh token is used to get a new access token.

## Make a device list call

<br />

Authorization is not complete until you make
your first
[`devices.list`](https://developers.google.com/nest/device-access/reference/rest/v1/enterprises.devices/list)
call with your new access token. This
initial call finishes the authorization process and enables events if
you've already set up a Pub/Sub subscription.

> [!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.

<br />

Use `curl` to make this call for the `devices` endpoint:

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

A successful call returns a list of devices linked to your Device Access
project. Each device has its own unique list of available traits:

```
{
  "devices": [
    {
      "name": "enterprises/project-id/devices/device-id",
      "type": "sdm.devices.types.device-type",
      "traits": { ... },
      "parentRelations": [
        {
          "parent": "enterprises/project-id/structures/structure-id/rooms/room-id",
          "displayName": "device-room-name"
        }
      ]
    }
  ]
}
```

## How to use a refresh token

<br />

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.

<br />

The command is similar to the access token one, except that you use a different
`grant_type`.

1. Open a terminal and run the
   following `curl` command, 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.

       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'

2. Google OAuth returns a new access token.

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

<br />

> [!NOTE]
> **Note:** If your Device Access integration relies on Pub/Sub events and rarely makes API calls, the user's authorization will be revoked if the refresh token expires. **For continued access, you must use the refresh token to refresh the access token within 6
> months.** For further help with authorization, see [Refresh token expiration](https://developers.google.com/identity/protocols/oauth2#expiration).

<br />

## 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.

### Modify account permissions

To modify the permissions granted to a Device Access project, or disconnect it
entirely, go to PCM:

<https://nestservices.google.com/partnerconnections>

This page displays all third-party developer services (Device Access projects)
connected to your account. Select the Device Access project you wish to
change. Use the next screen to modify permissions as desired.

**To revoke only specific permissions for an authorized service**, toggle the
permissions you want to revoke and click the back arrow to save.

**To disconnect an authorized service entirely** , click **Unlink your Google
Account** to revoke all permissions and access tokens the project has been
granted for the account.

> [!NOTE]
> **Note:** The authorized service can also be entirely disconnected through your Google account permissions at <https://myaccount.google.com/permissions>.

If PCM does not show the desired service, you may need to
[make a device list call](https://developers.google.com/nest/device-access/authorize#make_a_device_list_call) first.

## 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

Open the following link in a web
browser, 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)

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

### 2 Auth Code

You should be redirected to
https://www.google.com. The Authorization Code is returned as the `code` parameter in the URL,
which should be in this format:

```
https://www.google.com?code=authorization-code&scope=https://www.googleapis.com/auth/sdm.service
```

### 3 Access Token

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

Open a terminal and run
the following `curl` command, 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

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=https://www.google.com'

### Response

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

### 4 API Call

Authorization is not complete until you make
your first
[`devices.list`](https://developers.google.com/nest/device-access/reference/rest/v1/enterprises.devices/list)
call with your new access token. This
initial call finishes the authorization process and enables events if
you've already set up a Pub/Sub subscription.

> [!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.

Open a terminal and run the
following `curl` command, 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/sdm.service",
      "token_type": "Bearer"
    }