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

Device Info

Endpoints in this folder give information about the device.

Timezones

Simply returns a list of all supported timezones.

Authorizations:
cast-local-authorization-token

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.

Authorizations:
cast-local-authorization-token
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.

Authorizations:
cast-local-authorization-token

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

Authorizations:
cast-local-authorization-token
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.

Authorizations:
cast-local-authorization-token

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

Authorizations:
cast-local-authorization-token
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": {
    },
  • "name": "Bedroom Speaker",
  • "net": {
    },
  • "night_mode_params": {
    },
  • "opencast": {
    },
  • "opt_in": {
    },
  • "proxy": {
    },
  • "settings": {
    },
  • "setup": {
    },
  • "sign": {
    },
  • "user_eq": {
    },
  • "version": 10,
  • "wifi": {
    }
}

Test Internet Download Speed

Update: This seems to have been removed. Returns 404 Not Found.

This endpoint tests internet download speed. Any sample file URL can be provided.

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
url
required
string

Responses

Request samples

Content type
application/json

Response samples

Content type
application/json
{
  • "bytes_received": 31457280,
  • "response_code": 200,
  • "time_for_data_fetch": 4722,
  • "time_for_http_response": 316
}

Device Settings

This folder consists of all endpoints to modify and control the device.

Reboot and Factory Reset

This can simply reboot the device (params: "now") or factory reset the device (params: "fdr").

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
params
required
string

Responses

Request samples

Content type
application/json
{
  • "params": "now"
}

Night Mode settings

This sets night mode options.
To view currently set values, use /setup/eureka_info.
If enabled is set to false, night mode is disabled and the other values do not matter.
led_brightness and volume refer to the maximum LED Brightness and Volume that is set during night mode.
demo_to_user is always set to true so change in values will be visible in realtime (like brightness).
windows: A combination of length_hours and start_hour is used to define start and end times for night mode. In this example, night mode starts at 10 PM (22) and ends at 6 AM (8 hours later). windows.days is an array of days of week when night mode will be enabled. Example: 0->Sunday, 1-> Monday, ..., 6->Saturday.

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
enabled
required
boolean
do_not_disturb
required
boolean
led_brightness
required
number
volume
required
number
demo_to_user
required
boolean
required
Array of objects (Window)

Responses

Request samples

Content type
application/json
{
  • "enabled": false,
  • "do_not_disturb": true,
  • "led_brightness": 0.44999998807907104,
  • "volume": 0.46000000834465027,
  • "demo_to_user": true,
  • "windows": [
    ]
}

Response samples

Content type
application/json
{
  • "do_not_disturb": true,
  • "enabled": false,
  • "led_brightness": 0.44999998807907104,
  • "volume": 0.46000000834465027,
  • "windows": [
    ]
}

Set Eureka Info

This can set custom values to some options.

Only fields to be modified need to be sent, not all. The example has some modifiable fields.

TODO: List all modifiable fields.

Sending non-existant fields will still return a 200 OK, but they are not saved.

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
name
required
string
required
object (Settings1)
required
object (OptIn1)

Responses

Request samples

Content type
application/json
{
  • "name": "Living Room",
  • "settings": {
    },
  • "opt_in": {
    }
}

Assistant

This folder contains all endpoints related to Assistant's tasks like Do Not Disturb, Alarms and Timers, Accessibility and equalizer.

Get Alarms and Timers

This gives a list of all active alarms and timers.

Both alarms and timers have ids which can be used to delete them. (There is no known way of creating/deleting yet). The value of status have different meanings for alarms and timers (given below).

Alarms have date_pattern and time_pattern with day, month, year, hour, minute, second. fire_time is the same in unix time (milliseconds, not seconds).
status is 1 for set up and 2 for ringing.

Timers have original_duration is the original duration.
status is 1 for set up and 3 for ringing.

Authorizations:
cast-local-authorization-token

Responses

Response samples

Content type
application/json
{
  • "alarm": [
    ],
  • "timer": [
    ]
}

Delete Alarms and Timers

This deletes alarms and timers by their id.

ids is a list of ids to be deleted. Sending invalid id still returns a 200 OK. The / in the ids have to be escaped like \/.

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
ids
required
Array of strings

Responses

Request samples

Content type
application/json
{
  • "ids": [
    ]
}

Response samples

Content type
application/json
{
  • "success": true
}

Do Not Disturb

This is for the Do Not Disturb option. Sending an empty-body POST returns the current value. Sending a new value changes it.

Authorizations:
cast-local-authorization-token
header Parameters
Content-Type
required
string
Example: application/json

Responses

Response samples

Content type
application/json
{
  • "notifications_enabled": true
}

Alarm Volume

This gets and sets alarms and timers volume.
Note: This is not the same as normal volume.

Volume is a float number in [0, 1] where 0 is minimum and 1 is maximum.
Sending an empty body gets the volume. Sending volume sets the volume.

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
volume
required
integer <int32>

Responses

Request samples

Content type
application/json
{
  • "volume": 1
}

Response samples

Content type
application/json
{
  • "volume": 1
}

Set Equalizer Values

This can only set new equalizer values. To get already set values, use /setup/eureka_info.

The body is mandatory. It can either contain low_shelf or high_shelf or both.

low_shelf.gain_db and high_shelf.gain_db refer to bass and treble respectively.

Default values are 0 for both.
While the slider in the Home app only ranges from -6 to +6, they can be set to any integer like 50 or -100. These changes persist.

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
required
object (LowShelf1)
required
object (HighShelf1)

Responses

Request samples

Content type
application/json
{
  • "low_shelf": {
    },
  • "high_shelf": {
    }
}

Accessibility

This controls Accessibility sounds. hotword_enabled is for 'Play start sound' and endpoint_enabled is for 'Play end sound'.
Sending an empty-body POST request returns the current values.
Either of the fields or both can be sent and new values will be saved.

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
hotword_enabled
required
boolean
endpoint_enabled
required
boolean

Responses

Request samples

Content type
application/json
{
  • "hotword_enabled": false,
  • "endpoint_enabled": false
}

Response samples

Content type
application/json
{
  • "endpoint_enabled": false,
  • "hotword_enabled": false
}

Bluetooth

This folder contains Bluetooth related endpoints.

Get Scan Results

See note for Bluetooth under /setup/bluetooth/status

For Part 2 only

This returns a list of all nearby bluetooth devices. While the Home app only shows speakers, this list contains all devices including TVs, mobiles, etc.

rssi is signal strength, name is name, mac_address is mac address.
device_class and device_type are bluetooth codes.

The Home app only lists those devices with expected_profiles > 0. Basically, the device should function as a speaker.

Authorizations:
cast-local-authorization-token

Responses

Response samples

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

Forget paired device

See note for Bluetooth under /setup/bluetooth/status

For both parts

This is to forget paired devices by mac address. Works for both kinds of devices (Part 1 and Part 2).

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
mac_address
required
string
bond
required
boolean

Responses

Request samples

Content type
application/json
{
  • "mac_address": "xx:xx:xx:xx:xx:xx",
  • "bond": false
}

Change Discoverability

See note for Bluetooth under /setup/bluetooth/status

For Part 1 only

This enables/disables Home's bluetooth discovery and other devices can pair with Home (where Home acts as a speaker).

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
enable_discovery
required
boolean

Responses

Request samples

Content type
application/json
{
  • "enable_discovery": true
}

Pair with Speaker

See note for Bluetooth under /setup/bluetooth/status

For Part 2 only

This pairs with other bluetooth speakers by mac address.

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
mac_address
required
string
connect
required
boolean
profile
required
integer <int32>

Responses

Request samples

Content type
application/json
{
  • "mac_address": "54:13:79:49:19:22",
  • "connect": true,
  • "profile": 2
}

Status

There are 2 parts of Bluetooth.

Part 1: Devices like phones connect to Home and play audio through Home.
For this, /setup/bluetooth/discovery is used to make Home discoverable. Then devices can connect to it as if Home is just another bluetooth speaker.

Part 2: Bluetooth speakers connect to Home and Home plays audio through the speakers. For this, /setup/bluetooth/scan and /setup/bluetooth/scan_results are used to connect to other speakers.

The other endpoints are common for both parts.

For both parts

This gives the status of all bluetooth things.

  • Not sure what audio_mode is.
  • discovery_enabled states whether Home is discoverable. (Part 1)
  • connecting_devices is a list of all media sources (like phones) connected to Home. (Part 1)
  • scanning_enabled states whether Home scanning for other bluetooth speakers/devices. (Part 2)
  • connected_devices is a list of all speakers connected to Home. (Part 2)
Authorizations:
cast-local-authorization-token

Responses

Response samples

Content type
application/json
{
  • "audio_mode": 0,
  • "connecting_devices": [ ],
  • "connected_devices": [
    ],
  • "remote_sink": {
    },
  • "discovery_enabled": false,
  • "scanning_enabled": false
}

Scan for devices

See note for Bluetooth under /setup/bluetooth/status

For Part 2 only

This initiates scan for other bluetooth speakers/devices. Scan results will be updated continuously for timeout seconds.
To get the scan results, see /setup/bluetooth/scan_results.

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
enable
required
boolean
clear_results
required
boolean
timeout
required
integer <int32>

Responses

Request samples

Content type
application/json
{
  • "enable": true,
  • "clear_results": true,
  • "timeout": 60
}

Get Paired Devices

See note for Bluetooth under /setup/bluetooth/status

For both parts

This gives a list of all paired or 'bonded' devices. The response field names are self-descriptive.

Authorizations:
cast-local-authorization-token

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Wifi

This folder contains Wi-Fi related endpoints.

Connect to Wi-Fi Network

Note: Not sure how the password is encrypted. Might be using the public certificate from /setup/eureka_info. So this cannot be used as of now. If someone figures it out, please create a new issue here.

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
bssid
required
string
signal_level
required
integer <int32>
ssid
required
string
wpa_auth
required
integer <int32>
wpa_cipher
required
integer <int32>
enc_passwd
required
string

Responses

Request samples

Content type
application/json
{
  • "bssid": "5c:0a:xx:xx:xx:xx",
  • "signal_level": -42,
  • "ssid": "myotherssid",
  • "wpa_auth": 7,
  • "wpa_cipher": 4,
  • "enc_passwd": "xxxxxfPY="
}

Scan for Networks

This initiates scanning for Wi-Fi networks.

The results can be obtained with /setup/scan_results after triggering the scan with this request.

Authorizations:
cast-local-authorization-token

Responses

Get Saved Networks

This gets a list of all saved Wi-Fi networks.

Each network has ssid, wpa_auth, wpa_cipher and wpa_id.
wpa_id is an incrementing number used to identify a saved network.
#TODO: Add values for wpa_auth and wpa_cipher.

Authorizations:
cast-local-authorization-token

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Forget Wi-Fi Network

This is to forget a saved network by wpa_id. Get the wpa_id from /setup/configured_networks

Authorizations:
cast-local-authorization-token
Request Body schema: application/json
wpa_id
required
integer <int32>

Responses

Request samples

Content type
application/json
{
  • "wpa_id": 0
}

Get Wi-Fi Scan Results

This gets a list of all nearby Wi-Fi access points.

The list only has the connected AP by default. Once a scan is triggered by /setup/scan_wifi, the whole list is cached for ~3 minutes. Then it will revert to returning only the connected AP again.

Authorizations:
cast-local-authorization-token

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Static Files

This folder contains a list of static files stored in Home.

Legal Notice

All licenses of programs used by Home.

Authorizations:
cast-local-authorization-token

Responses

Response samples

Content type
text/plain
<html><!-- a long page --></html>

Chromecast Icon

Update: This no longer exists. It's not useful, anyway.

A redirect to http://www.gstatic.com/eureka/images/eureka_device.png

Authorizations:
cast-local-authorization-token

Responses