Google Home local authentication token extraction
Python package to extract Google Home devices local authentication tokens from Google servers. These local authentication tokens are needed to control Google Home devices (See @rithvikvibhu's Google Home (2.0) API).
How it works
glocaltokens gets three kinds of tokens, each from the one before:
- Master token: starts with
aas_et/and is long lived. You get it once with your Google username and password, or with a browser sign-in (see "If logging in with a password fails" below). - Access token: lives 1 hour. glocaltokens gets a new one from the master token when it expires.
- Local authentication tokens: one per device, used to send requests to that device. They only live about 1 day, so you will need to get new ones regularly.
Store the master token, not your password: with the master token alone, glocaltokens can get the other tokens whenever you need them.
Installation
glocaltokens requires Python 3.12 or newer.
Using uv:
$ uv add glocaltokens
Using pip:
$ pip install glocaltokens
Quickstart
from glocaltokens.client import GLocalAuthenticationTokens
client = GLocalAuthenticationTokens(
username="<YOUR_GOOGLE_USERNAME>", password="<YOUR_GOOGLE_PASSWORD>"
)
# Get master token, then store it (see "Authentication" below)
print("[*] Master token", client.get_master_token())
# Get Google device local authentication tokens (live about 1 day)
print(client.get_google_devices_json())
See example/get_tokens.py for a complete script that reads your credentials from environment variables.
Authentication
Logging in with a password
Log in with the password only once, then store the master token and use it instead. If you log in too often, Google will disconnect your Android devices and other weird things will happen.
If your Google account uses 2-Step Verification, create an app password and use it instead of your regular password.
Reusing the master token
Never store the user's password nor username in plain text, if storage is necessary, generate a master token and store it. The master token gives access to the Google account, so protect it like a password.
from glocaltokens.client import GLocalAuthenticationTokens
# Using Google username and password first, and only once
client = GLocalAuthenticationTokens(
username="<YOUR_GOOGLE_USERNAME>", password="<YOUR_GOOGLE_PASSWORD>"
)
master_token = client.get_master_token()
"""Now store master_token somewhere"""
# Later, use the stored master token instead of the username and password
client = GLocalAuthenticationTokens(master_token=master_token)
If logging in with a password fails
Logging in with a password does not work for every account. If get_master_token() returns None,
or your account uses a passkey, sign in with a browser instead and let glocaltokens exchange that sign-in for a master token.
This uses gpsoauth's alternative flow:
- Open https://accounts.google.com/EmbeddedSetup and sign in to your Google account.
- Click "I agree" when asked. The page may keep loading forever; you can ignore that.
- Copy the value of the
oauth_tokencookie, for example from the cookies list in your browser's developer tools. - Pass it to the client, then get the master token and store it:
client = GLocalAuthenticationTokens(oauth_token="<YOUR_OAUTH_TOKEN_COOKIE>")
master_token = client.get_master_token()
email = client.get_email()
Treat the oauth_token cookie like a password. If the exchange fails, sign in again to get a new cookie.
After that, use the stored master token as shown above.
Finding the account of a master token
A master token doesn't say which Google account it belongs to. get_email() returns the account's email address,
or None if Google doesn't give one. If the client got the master token itself, get_email() returns the address Google sent with it.
Otherwise it asks Google, and returns the address only if Google has verified it:
client = GLocalAuthenticationTokens(master_token="<YOUR_MASTER_TOKEN>")
print(client.get_email())
Getting device tokens
get_google_devices() returns a list of Device objects, and get_google_devices_json() returns the same list as a JSON string:
[
{
"device_id": "...",
"device_name": "Living Room speaker",
"network_device": {
"ip": "192.168.1.10",
"port": 8009
},
"hardware": "Google Nest Mini",
"local_auth_token": "..."
}
]
The client caches the tokens it gets from Google for 24 hours. Pass force_homegraph_reload=True to fetch new ones sooner.
Selecting models
By default you get all devices with valid local authentication tokens, without filtering by model. To get only some models, pass a list of model names as models_list.
The names are the hardware values in the output above.
GOOGLE_HOME_MODELS in const.py lists some common models:
- Google Home
- Google Home Mini
- Google Nest Mini
- Lenovo Smart Clock
from glocaltokens.const import GOOGLE_HOME_MODELS
google_devices = client.get_google_devices_json(GOOGLE_HOME_MODELS)
# Or your own list
google_devices = client.get_google_devices_json(["Google Home", "Google Nest Mini"])
The list is not complete. If your model is missing, use your own list, or add it to GOOGLE_HOME_MODELS with a pull request.
Finding devices on your network
To fill in ip and port, glocaltokens looks for devices on your local network with mDNS (zeroconf),
so it must run on the same network as your devices. Devices it does not find have null for both.
If discovery does not work on your network, turn it off and give the IPv4 address of each device, using its name in the Google Home app:
google_devices = client.get_google_devices_json(
disable_discovery=True,
addresses={"Living Room speaker": "192.168.1.10"},
)
Only IPv4 addresses are supported. If any entry is not a valid IPv4 address, glocaltokens logs an error and returns no devices at all.
Options
Both get_google_devices() and get_google_devices_json() accept these arguments:
| Argument | Default | Description |
|---|---|---|
models_list |
None |
Only return these models. None returns all devices with valid local authentication tokens. |
disable_discovery |
False |
Do not search the local network for device IP addresses and ports. |
addresses |
None |
{"device name": "IPv4 address"}, used when discovery is disabled or finds nothing. |
zeroconf_instance |
None |
An existing zeroconf.Zeroconf instance to use for discovery. glocaltokens leaves it open. |
force_homegraph_reload |
False |
Fetch new tokens from Google even if the cached ones are less than 24 hours old. |
discovery_timeout |
2 |
How long to search the local network, in seconds. |
get_google_devices_json() also accepts indent for the JSON output (default 2).
Troubleshooting
If you get no devices or no tokens, create the client with verbose=True to print debug logs that show each step.
Without verbose=True, glocaltokens follows the level your application sets for the glocaltokens logger.
The logs mask your password and tokens, but they also include Google's responses to failed requests, so check them before you share them, for example in an issue.
Errors
Most failures are logged and return None from the token methods, or no devices from the device methods:
an empty list from get_google_devices() and "[]" from get_google_devices_json().
Check the result before you use it.
Some errors are raised instead, and your code should handle them:
requests.RequestExceptionwhen glocaltokens cannot get a master or access token from Google, for example without an internet connection or when Google does not reply within 10 seconds. The device methods raise it too when they need a new access token first, and so doesget_email().OSErrorwhen network discovery cannot start, for example because no network interface is available. Passdisable_discovery=Trueif you do not need IP addresses and ports.
If Google does not reply within 10 seconds when the device methods fetch the device list itself, they log the error and return no devices.
Contributing
See Contributing guidelines. This is an open-source project and all contributions are highly welcomed.
Credits
Much credit goes to @rithvikvibhu for doing most of the heavy work like finding a way to extract master and access tokens (See the gist here).
Also, thank you very much to the guys at pychromecast which provided the code required to scan devices in the network.
Metadata
Release files for glocaltokens 0.10.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| glocaltokens-0.10.0.tar.gz | 91.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| glocaltokens-0.10.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 109.3 kB
Release files / glocaltokens-0.10.0.tar.gz
| Download URL | glocaltokens-0.10.0.tar.gz |
|---|---|
| Size | 91.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7b542ad8e83fe6b2655f0bda261a83cf904721db727930dd1200abdc722ca52a
|
|
BLAKE2b-256 checksum How to use checksums |
7aa20a183c71aa46b14ed55eb889328d3b478e9160a1960066d6184c85d87b33
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / glocaltokens-0.10.0-py3-none-any.whl
| Download URL | glocaltokens-0.10.0-py3-none-any.whl |
|---|---|
| Size | 18.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c52d0020b5d2b0a01978f137418fd8c1b15e159c7e5a3cd72a2521aa599915e8
|
|
BLAKE2b-256 checksum How to use checksums |
f896885a4e40dbab6086e8e1e466666155aa892f3690014ca0f98ee77902fbe9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency log