Skip to main content

GitHub Workflow Status PyPI Downloads Pre-commit GitHub Activity

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:

  1. 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).
  2. Access token: lives 1 hour. glocaltokens gets a new one from the master token when it expires.
  3. 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:

  1. Open https://accounts.google.com/EmbeddedSetup and sign in to your Google account.
  2. Click "I agree" when asked. The page may keep loading forever; you can ignore that.
  3. Copy the value of the oauth_token cookie, for example from the cookies list in your browser's developer tools.
  4. 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.RequestException when 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 does get_email().
  • OSError when network discovery cannot start, for example because no network interface is available. Pass disable_discovery=True if 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)

Source distribution for glocaltokens 0.10.0
File Size Uploaded
glocaltokens-0.10.0.tar.gz 91.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for glocaltokens 0.10.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.10.0 This release

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.9

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

1 release file

0.2.4

1 release file

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page