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 and your username, 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 password
client = GLocalAuthenticationTokens(
    username="<YOUR_GOOGLE_USERNAME>", 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 with your username, then get the master token and store it:
client = GLocalAuthenticationTokens(
    username="<YOUR_GOOGLE_USERNAME>", oauth_token="<YOUR_OAUTH_TOKEN_COOKIE>"
)
master_token = client.get_master_token()

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() asks Google and returns the account's verified email address, or None if Google doesn't give one:

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.9.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.9.0
File Size Uploaded
glocaltokens-0.9.0.tar.gz 91.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for glocaltokens 0.9.0
File Interpreter ABI Platform
glocaltokens-0.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 108.8 kB

Release files / glocaltokens-0.9.0.tar.gz

Download URL glocaltokens-0.9.0.tar.gz
Size 91.0 kB
Tags Source
SHA-256 checksum
How to use checksums
375bd745039c18beaf57403b454f2dc086787fb2af3c13bf6e6711eacffcc2a4
BLAKE2b-256 checksum
How to use checksums
57fd65cd2a0c0b2b081c4e4dd604ee98faafd647e790318e199d8ed5c174b941
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.9.0-py3-none-any.whl

Download URL glocaltokens-0.9.0-py3-none-any.whl
Size 17.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
76ab643b465f7c1d80bf84a7fc2003f4f63139ddd2754e39ed201b5649cc047e
BLAKE2b-256 checksum
How to use checksums
da11509c0e6c4390ed03e9b532b9cd00a73c843b831796a58bcccfb04a9ef354
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

0.10.0

2 release files

This release

0.9.0 This release

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