PyPI & TestPyPI Accounts & Tokens
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the Python Reference bibliography. |
Uploading needs an identity: a PyPI account with two-factor authentication, and either an API token or, better, a trusted
publisher (see Trusted Publishing & Attestations).
This page describes the account side as documented by PyPI on 2026-10-22; nothing here was run against PyPI or TestPyPI, and the
tokens shown are placeholders (pypi-AgEI…). The short version is on
Virtual Environments & Packaging.
Accounts
-
Register on pypi.org and, separately, on test.pypi.org: the two have separate databases, accounts, tokens and projects. TestPyPI is pruned now and then, accounts included.
-
Verify your email address. Registering a project and uploading a file require a verified address. Disposable addresses are rejected.
-
Two-factor authentication is mandatory for every account since 2024-01-01. Before adding a method, PyPI makes you generate recovery codes and "burn" one to prove you stored them. Then add at least two methods:
-
a security device (WebAuthn: a FIDO key or a phone), preferred because it resists phishing;
-
an authentication application (TOTP), which shares a secret with PyPI and shows six-digit codes.
-
-
Sensitive actions (adding collaborators, deleting files, creating tokens, setting up 2FA) ask for your password again after 30 minutes. PyPI checks passwords against breach databases (through Have I Been Pwned’s k-anonymity API) and refuses known ones.
API tokens
An API token replaces your password for uploads (the web login is not usable by tools):
-
create it under Account settings → API tokens (after verifying your email);
-
scope it to one project whenever possible; an account-wide token can upload to every project you maintain. The scope list only offers existing projects, so the very first upload of a new project needs an account-wide token, or a pending trusted publisher, which avoids tokens entirely;
-
use it with the username
__token__and the whole token as the password, including itspypi-prefix; -
tokens can be decoded with base64 to compare their identifier with the one PyPI shows;
-
a token found on a public website (a commit, a log) is revoked automatically and you get an email: investigate the exposure, check the account’s security history, then create a new one.
Since twine 5.0.0 (2024-02-10) only __token__ is accepted as the username for PyPI and TestPyPI, and since 6.0.0 (2024-11-29)
it is the default, so TWINE_PASSWORD alone is enough.
.pypirc
twine (and flit) read upload targets and credentials from ~/.pypirc, an INI file. twine’s built-in defaults are a [pypi] and
a [testpypi] section; a private index needs index-servers:
[distutils]
index-servers =
pypi
testpypi
birdwatch
[pypi]
username = __token__
[testpypi]
username = __token__
[birdwatch]
repository = http://localhost:8082/
username = birdwatch
Keep passwords out of it: store them in the system keyring, which twine queries by repository URL and username,
keyring set https://upload.pypi.org/legacy/ __token__
keyring set https://test.pypi.org/legacy/ __token__
keyring set http://localhost:8082/ birdwatch
or pass them through TWINE_PASSWORD in CI. If a password = line is unavoidable, make the file private (chmod 600 ~/.pypirc).
Since twine 7.0.0 the file is read as UTF-8. Poetry does not read .pypirc; it has its own repositories and credentials (see
Publishing with Poetry).
Collaborators and organizations
-
A project has owners (full control: releases, collaborators, deletion) and maintainers (can upload releases, nothing else). Owners invite by PyPI username; the invitee must accept. An owner can remove themselves only if another owner remains.
-
Transferring ownership means adding the new owner, who can then remove you. Granting ownership gives away the project: the new owner can remove you.
-
Organization accounts group users into teams with project permissions. They are paid for companies and free for community projects, with the same features.
"Invalid or non-existent authentication information"
The upload error PyPI returns for bad credentials. Its documented causes:
-
the token was revoked (by you, or automatically after a leak);
-
the token is malformed, typically with a trailing newline from a file or a secret store;
-
the username is not
__token__; -
the token belongs to the other index (a TestPyPI token used for PyPI or the reverse);
-
on Windows, pasting into a
getpassprompt with Ctrl-V or Shift+Insert silently pastes nothing; use the window menu’s Edit → Paste.