Skip to main content

chatgpt-auth

Sign in to a ChatGPT Plus/Pro/Team account once and get OpenAI access tokens with automatic refresh — for CLIs, bots, and server jobs.

Tokens and refresh tokens are stored on the local filesystem with strict permissions. Nothing about this package talks to OpenAI except the OAuth flow itself.

Install

$ pip install chatgpt-auth

Quick start

Sign in once from a machine with a browser:

$ chatgpt-auth login

Then get an access token anywhere (expired tokens are refreshed and saved automatically):

$ TOKEN=$(chatgpt-auth print-access-token)
$ curl -sS https://api.openai.com/v1/models -H "Authorization: Bearer $TOKEN"

From Python:

from chatgpt_auth import Credentials

credentials = Credentials.load()
token = credentials.get_access_token()  # refreshes + saves if needed

Force a refresh or inspect state:

$ chatgpt-auth refresh
$ chatgpt-auth status
$ chatgpt-auth logout

CLI

  • login — run the browser sign-in (--manual pastes the URL/redirect instead; --replace replaces an existing connection; --timeout, --port, --agent-name tune the flow).
  • status — show the local connection state (offline, never prints tokens).
  • print-access-token — print the current access token (refreshing first if needed). This is the only command that prints a token.
  • refresh — force a token refresh.
  • logout — wipe local tokens and try to revoke the refresh token remotely. Local sign-out happens even if revocation cannot be confirmed; to fully sign out everywhere also revoke the session in ChatGPT Settings.

All commands take --credentials PATH to point at a credentials file.

Credentials file resolution

Credentials.load() / the CLI resolve the credentials path in this order:

  1. The explicit path argument / --credentials option.
  2. The CHATGPT_AUTH_CREDENTIALS environment variable.
  3. ${XDG_CONFIG_HOME:-~/.config}/chatgpt-auth/credentials.json (a relative XDG_CONFIG_HOME is ignored per the XDG spec).

Relative paths resolve against the current working directory; ~ is expanded. Reserved aux names (host.json, pending.json, runtime.lock, login.lock, models.json) are rejected as credentials paths.

Auto refresh and saved tokens

get_access_token() re-checks the store on every call and refreshes when the token expires within ~60 seconds, saving the new token before returning it. When a refresh's outcome is unknowable (e.g. the network died mid-request) the connection is retired rather than risking a double-submit of a single-use refresh token; the next call raises ReauthorizationRequiredError and login is required again. A write failure after a successful refresh returns no token — the object refuses further use if even retiring the connection cannot be persisted.

Sharing a store with llm-chatgpt-plan

Point --credentials/CHATGPT_AUTH_CREDENTIALS at the existing credentials.json used by llm-chatgpt-plan to share the same connection, host.json, pending.json, and both lock files — so sign-ins and token use in both tools serialize correctly. This package never touches the models.json model cache; a new connection bumps generation, which is how llm-chatgpt-plan invalidates its cached model list. Files named anything other than credentials.json get their own .<name>-suffixed aux files and share nothing with other stores.

Concurrent use

Multiple processes may hold Credentials for the same path. Refresh requests collapse onto a shared fcntl.flock runtime lock, so two processes do not double-submit a refresh. If another process signs out or signs in underneath you, the next call raises ReauthorizationRequiredError or ConnectionChangedError.

OS support

macOS and Linux (POSIX fcntl locking). Windows is not supported in this version.

Security notes

  • The credentials directory must be owned by you and not group/world readable; token files are written 0600.
  • Tokens, refresh tokens, authorization codes, and PKCE verifiers never appear in logs or exception messages.
  • logout clears local state first so an interrupted run still leaves the connection dead, then revokes the refresh token; a broken credentials file is the limit of what local sign-out can guarantee.

API summary

import chatgpt_auth

credentials = chatgpt_auth.Credentials.load()       # local file only
token = credentials.get_access_token()              # auto refresh + save
token = credentials.refresh()                       # forced refresh
credentials = chatgpt_auth.login()                  # browser sign-in
status = chatgpt_auth.status()                      # AuthStatus (local only)
result = chatgpt_auth.logout()                      # LogoutResult

Exceptions (chatgpt_auth namespace): SignInRequiredError, ReauthorizationRequiredError, ConnectionChangedError, PlanPermissionError, NetworkError, StorageError, LoginTimeoutError, AuthError, and the base ChatGPTAuthError.

Development

Run from this package directory:

$ uv sync
$ uv run pytest
$ uv run ruff check .
$ uv build

Releases

Publish a GitHub Release tagged chatgpt-auth-<version> matching project.version in pyproject.toml. The first release tag is chatgpt-auth-0.1.0. The publish-chatgpt-auth.yml workflow verifies the tag, tests Python 3.11–3.14, builds this package's wheel and sdist, and publishes them to PyPI using Trusted Publishing. Releases for other packages are skipped.

Metadata

Release files for chatgpt-auth 0.1.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 chatgpt-auth 0.1.0
File Size Uploaded Provenance Actions
chatgpt_auth-0.1.0.tar.gz 46.2 kB With provenance Details for chatgpt_auth-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for chatgpt-auth 0.1.0
File Interpreter ABI Platform Actions
chatgpt_auth-0.1.0-py3-none-any.whl Python 3 none any Details for chatgpt_auth-0.1.0-py3-none-any.whl

Total release size: 78.6 kB

Release files / chatgpt_auth-0.1.0.tar.gz

Download URL chatgpt_auth-0.1.0.tar.gz
Size 46.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d095e22c35db974f17a74ce56a0708103bc3c0d68b83507411b20364a3ca8927
BLAKE2b-256 checksum
How to use checksums
3d3ee5286739ced3bd31a9cebd6dd7ce7e9bb0408976d453a8fb874dca63efe6
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 14, 2026.

Transparency log

Release files / chatgpt_auth-0.1.0-py3-none-any.whl

Download URL chatgpt_auth-0.1.0-py3-none-any.whl
Size 32.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
18a8b836cb2e50c91200042f8a41608db871f9bc564abeaa81674b7a1f477cef
BLAKE2b-256 checksum
How to use checksums
bc7a51f4e2cfec7833d2de61d0beb1e5d4490100f60196d943c6e170d97d34f9
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 14, 2026.

Transparency log

Security for chatgpt-auth 0.1.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for chatgpt_auth-0.1.0.tar.gz

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 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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