Google Home (2.0)

Download OpenAPI specification:Download

Google Home Local API

This is an unofficial documentation of the local API used by the Home app to communicate with GH devices. GitHub Repo

GitHub stars GitHub license

Getting Started

Requests must be made over HTTPS, port 8443, so the base URL for these endpoints is: https://<google-home-ip>:8443/setup/

Get the IP of Google Home from the Google Home app (Device Settings -> End of the list) or from your router.

GET requests are simple, in the browser kind.
POST requests need to set the header (when there's a body): content-type: application/json

Authentication

Since June 2019, most requests (with exceptions like /setup/eureka_info) need a local authorization token.

There are 3 kinds of tokens involved here:

Local Authorization Token

This token must be sent in all requests in the header cast-local-authorization-token. It is short-lived (~1 day) and may change unexpectedly (with a sync, change in homegraph, etc.)

Get this token
  • With access to an android device, get this token directly by either method.
  • Without a device, or to integrate it with a script, use an access token to get the homegraph and extract the token. To get an access token, read the next section. Check the example section for more info.

Access Token

This is a standard google oauth2 access token. It is in the form ya29.***. This gives access to the Google Home Foyer API. These expire in an hour. Use this to get the homegraph (and then the local authorization token above).

Get this token

To get this access token, either a Google account username/password or a Google Master Token is needed. More info in the gist. Use the script from this gist.

Master Token

This is in the form aas_et/*** and can be used to request access tokens.

Get this token

The same script in the gist that gets the access token can also get the master token. Needs Google account creds.

Example

Here's the whole flow from just a pair of username/password to using the local API.

Prerequisites:

1. Get an access token with the script

  • Download get_tokens.py
  • Fill in username and password
    python3 get_tokens.py
    # Note down the access token printed.

2. Use the access token and get home graph

  • This prints the json and uses jq to parse and filter out the fields deviceName and localAuthToken
  • This will give a list of all devices and their local auth tokens
    ./grpcurl -H 'authorization: Bearer ya29.a0Af****' \
      -import-path /path/to/protos \
      -proto /path/to/protos/google/internal/home/foyer/v1.proto \
      googlehomefoyer-pa.googleapis.com:443 \
      google.internal.home.foyer.v1.StructuresService/GetHomeGraph | jq '.home.devices[] | {deviceName, localAuthToken}'
    # Note down the local auth token for the device you want.

3. Make the call to the local device using the local auth token

curl -H "cast-local-authorization-token: LOCAL_AUTH_TOKEN" --verbose --insecure https://192.168.0.18:8443/setup/bluetooth/status

Authentication

cast-local-authorization-token

Local authorization token. For more details, check the Authentication section.

Security Scheme Type API Key
Header parameter name: cast-local-authorization-token

Device Info

Endpoints in this folder give information about the device.

Timezones

Simply returns a list of all supported timezones.

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    }
]

App Device ID

This gives "app device id", "certificate" and "signed data".
The app_id in the request is mandatory and refers to Chromecast backdrop/screensaver app. It has to be set to E8C28D3C.

The certificate is valid and issued by Chromecast ICA 6 (Audio Assist), Google Inc.

Not sure what the other two are.

Request Body schema: application/json
app_id
required
string

Responses

Request samples

Content type
application/json
{
  • "app_id": "E8C28D3C"
}

Response samples

Content type
application/json
{
  • "app_device_id": "...",
  • "certificate": "-----BEGIN CERTIFICATE-----\nMIID...Oeb0\n-----END CERTIFICATE-----\n",
  • "signed_data": "HAjp..."
}

Locales

Simply returns a list of all supported locales.

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    },
  • {
    }
]

Check Ready Status

Update: This seems to have changed now and is no longer possible. The error is also new.

Setting play_ready_message to true plays a welcome message on the device saying "Hi, I'm your Google Assistant. I'm here to help. To learn a few things you can do, continue in the Google Home app."

Request Body schema: application/json
play_ready_message
required
boolean
user_id
required
string

Responses

Request samples

Content type
application/json
{
  • "play_ready_message": true,
  • "user_id": "xxxxx"
}

Response samples

Content type
application/json
{
  • "can_enroll": true,
  • "enrollment_state": 0,
  • "error_code": 0,
  • "ready": false,
  • "retryable": true
}

Offer

This gives a token which is used by the Home app to get offers. The offers themselves are not stored on the device.
A new token is generated for every request.

Responses

Response samples

Content type
application/json
{
  • "token": "ADtq..."
}

Eureka Info

This gives most of the device info. The GET parameter param is a comma separated list of json keys to fetch. Currently, these params are known: version,audio,name,build_info,detail,device_info,net,wifi,setup,settings,opt_in,opencast,multizone,proxy,night_mode_params,user_eq,room_equalizer,sign,aogh,ultrasound,mesh

Nested items can also be filtered using the dot notation. Example: audio.digital

The options GET parameter is always set to detail or detail,sign. sign signs the nonce and returns some value.

The nonce GET parameter is an integer value signed with needed (see option parameter above).

query Parameters
params
required
string
Example: params=version,audio,name,build_info,detail,device_info,net,wifi,setup,settings,opt_in,opencast,multizone,proxy,night_mode_params,user_eq,room_equalizer,sign,aogh,ultrasound,mesh
options
required
string
Example: options=detail,sign
nonce
required
integer <int32>
Example: nonce=1234512345

Responses

Response samples

Content type
application/json
{
  • "aogh":
    {
    },
  • "audio":
    {
    },
  • "build_info":
    {
    },
  • "detail":
    {
    },
  • "device_info":
    {
    },
  • "multizone":
    {