# otpauth URI

> Source: https://docs.barcoder.ai/docs/standards/otpauth-uri
> research date 2026-06-03 · extracted at 2026-10-03
> Publisher: Barcoder — encyclopedia of QR, barcode and payment-code standards

Specifications:
- [Key Uri Format — google/google-authenticator Wiki](https://github.com/google/google-authenticator/wiki/Key-Uri-Format)
- [draft-linuxgemini-otpauth-uri — Usage specification of the otpauth URI format](https://datatracker.ietf.org/doc/draft-linuxgemini-otpauth-uri/)

## Overview

The **otpauth URI** is a URI payload format that carries the provisioning data for a one-time-password (OTP) authenticator credential — the shared secret plus its parameters — so that a 2FA app can enrol an account by scanning a single [QR Code](https://docs.barcoder.ai/docs/standards/qr-code). The format originates from Google's Google Authenticator project, whose "Key Uri Format" wiki page is the de facto specification.<sup>[1][1]</sup> The basic structure is `otpauth://TYPE/LABEL?PARAMETERS`, where `TYPE` is either `totp` (time-based) or `hotp` (counter-based), distinguishing the two OTP algorithm families.<sup>[1][1]</sup> An expired IETF individual Internet-Draft, *Usage specification of the otpauth URI format for TOTP and HOTP token generators*, exists to document the de facto schema, but carries no formal IETF standing.<sup>[2][2]</sup>

## History

The otpauth URI was introduced by Google's Google Authenticator app; the canonical description lives in the project's GitHub wiki "Key Uri Format" page, and the source repository was archived (made read-only) in April 2021.<sup>[1][1]</sup> The two underlying OTP algorithms predate the URI: HOTP (HMAC-based counter OTP) and TOTP (time-based OTP) are the IETF standards that the `hotp` and `totp` types implement.<sup>[1][1]</sup> The Key Uri Format document references RFC 3548 (Base32), RFC 3986 (URI/percent-encoding) and RFC 5234 (ABNF), and describes the HOTP/TOTP algorithm implementations rather than re-specifying them.<sup>[1][1]</sup> In 2024–2025 İlteriş Yağıztegin Eroğlu authored an IETF Internet-Draft (`draft-linuxgemini-otpauth-uri`) to formalise the schema for TOTP/HOTP token generators; it expired (last updated 17 February 2025) and is not endorsed by the IETF.<sup>[2][2]</sup>

## Technical specification

The grammar is `otpauth://TYPE/LABEL?PARAMETERS`.<sup>[1][1]</sup>

- **Scheme**: `otpauth://`.<sup>[1][1]</sup>
- **Type**: `totp` or `hotp`.<sup>[1][1]</sup>
- **Label**: identifies the account; format `issuer (":" / "%3A") *"%20" accountname`, e.g. `Example:alice@google.com` or `Provider1:Alice%20Smith`. The issuer prefix is optional but recommended.<sup>[1][1]</sup>

Parameters:<sup>[1][1]</sup>

| Parameter | Required | Values / default | Notes |
|-----------|----------|------------------|-------|
| `secret` | Yes | Base32 key per RFC 3548 | RFC 3548 §2.2 padding "is not required and should be omitted" |
| `issuer` | Strongly recommended | URL-encoded string (RFC 3986) | Should match the label's issuer prefix when both are present |
| `algorithm` | No | `SHA1` (default), `SHA256`, `SHA512` | Currently ignored by Google Authenticator |
| `digits` | No | `6` (default) or `8` | Ignored on Android/BlackBerry implementations |
| `counter` | HOTP only | integer | Required for `hotp`; sets initial counter value |
| `period` | No | integer seconds, default `30` | TOTP only; currently ignored by Google Authenticator |

Example TOTP URI:<sup>[1][1]</sup>

```
otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example
```

Comprehensive example:<sup>[1][1]</sup>

```
otpauth://totp/ACME%20Co:john.doe@email.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&issuer=ACME%20Co&algorithm=SHA1&digits=6&period=30
```

The whole string is embedded in a standard [QR Code](https://docs.barcoder.ai/docs/standards/qr-code) for enrolment scanning.

## Use cases

- **2FA enrolment**: a service displays a [QR Code](https://docs.barcoder.ai/docs/standards/qr-code) containing the otpauth URI; the user scans it with an authenticator app, which derives the rolling 6/8-digit codes thereafter.<sup>[1][1]</sup>
- **Cross-vendor interoperability**: because the format is shared, the same enrolment QR works across Google Authenticator and third-party apps; libraries such as PyOTP and the YubiKey OATH application parse the same `otpauth://` string.<sup>[3][3]</sup><sup>[6][6]</sup>

## Implementations

- **PyOTP** — Python; implements server-side HOTP and TOTP and the otpauth provisioning URI; ~3.3k stars, active 2026.<sup>[3][3]</sup>
- **otpauth (hectorm)** — JavaScript/TypeScript; OTP library with a dedicated `URI` class for parsing/serialising `otpauth://`; ~1.5k stars, active 2026.<sup>[1][1]</sup><sup>[4][4]</sup>
- **speakeasy** — Node.js HOTP/TOTP generator with Google Authenticator support; ~2.8k stars, last active 2023, marked not maintained.<sup>[5][5]</sup>
- **YubiKey OATH (YubiKey SDK)** — documents parsing the otpauth URI string to load OATH credentials onto hardware tokens.<sup>[6][6]</sup>

## Comparison

- **TOTP vs HOTP**: `totp` codes roll on a time interval (`period`, default 30 s) and need no shared counter; `hotp` codes advance on an event counter and therefore require the `counter` parameter at provisioning so client and server start in sync.<sup>[1][1]</sup>
- **otpauth URI vs raw secret entry**: the URI bundles secret, issuer, algorithm, digit count and period into one scannable string, removing the error-prone manual Base32 key entry; legacy apps that ignore `algorithm`/`digits`/`period` simply fall back to the SHA1/6-digit/30-second defaults.<sup>[1][1]</sup>

## Fun facts

- Google Authenticator famously *ignores* the `algorithm`, `digits` and `period` parameters, silently assuming SHA1 / 6 digits / 30 seconds — so a SHA256 or 8-digit enrolment can break on it even though the parameters are part of the format.<sup>[1][1]</sup>
- The secret deliberately omits Base32 padding: RFC 3548 §2.2 padding "is not required and should be omitted" in otpauth URIs.<sup>[1][1]</sup>

## Status

The otpauth URI is the de facto active standard for 2FA enrolment QR codes, anchored by the Google Authenticator Key Uri Format wiki and supported across the major authenticator apps and OTP libraries.<sup>[1][1]</sup><sup>[3][3]</sup> There is no ratified RFC; the closest formalisation effort, the linuxgemini IETF draft, has expired without IETF endorsement.<sup>[2][2]</sup>

## Sources

[1]: https://github.com/google/google-authenticator/wiki/Key-Uri-Format
[2]: https://datatracker.ietf.org/doc/draft-linuxgemini-otpauth-uri/
[3]: https://github.com/pyauth/pyotp
[4]: https://github.com/hectorm/otpauth
[5]: https://github.com/speakeasyjs/speakeasy
[6]: https://docs.yubico.com/yesdk/users-manual/application-oath/uri-string-format.html

[1] [Key Uri Format — google/google-authenticator Wiki](https://github.com/google/google-authenticator/wiki/Key-Uri-Format) — GitHub, 2021
[2] [draft-linuxgemini-otpauth-uri — Usage specification of the otpauth URI format](https://datatracker.ietf.org/doc/draft-linuxgemini-otpauth-uri/) — IETF Datatracker, 2025
[3] [PyOTP — Python One-Time Password Library](https://github.com/pyauth/pyotp) — GitHub, 2026
[4] [otpauth (hectorm)](https://github.com/hectorm/otpauth) — GitHub, 2026
[5] [speakeasy](https://github.com/speakeasyjs/speakeasy) — GitHub, 2023
[6] [URI string format — YubiKey OATH](https://docs.yubico.com/yesdk/users-manual/application-oath/uri-string-format.html) — Yubico, 2025

## Deployments

_No country reports mention this standard by name._

## Regions / aggregations not mapped to a single country

- Universal
