Free 2FA API for Developers
Add TOTP two-factor authentication to any app with three JSON endpoints. Free forever - Create an account, generate a key, start calling. CORS enabled.
Quick Start
0. Get your free API key
Every request needs a key so we can keep the service free and abuse-free. Creating one takes about fifteen seconds:
- Open the account page and sign in with Google (or create a vault passphrase - Either works).
- In the sidebar, click Generate key under "2FA API key".
- Send it on every call as
Authorization: Bearer pgn_live_…(X-API-Keyand?api_key=also work).
Keep it server-side. The key identifies your app, so treat it like any other credential and rotate it from the same panel if it ever leaks. Rotation takes effect immediately.
1. Create a secret for a user
curl -H "Authorization: Bearer $PGN_API_KEY" \ "https://passwordgenerator.now/api/2fa/secret?issuer=MyApp&account=user@example.com"
{
"secret": "JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXP",
"otpauth_url": "otpauth://totp/MyApp:user@example.com?secret=…&issuer=MyApp",
"qr_data_uri": "data:image/png;base64,…",
"current_code": "492039",
"period": 30, "digits": 6, "algorithm": "SHA1"
}
Show the user qr_data_uri (or
/api/2fa/qr?secret=…&issuer=MyApp&account=… as a PNG URL), have them
scan it with any authenticator app, and store secret encrypted in your
database.
2. Verify codes at login
curl -X POST https://passwordgenerator.now/api/2fa/verify \
-H "Authorization: Bearer $PGN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"secret": "JBSWY3DPEHPK3PXP…", "code": "492039"}'
# → {"valid": true}
Optional window parameter (default 1,
max 4) accepts codes from adjacent 30-second windows to tolerate clock drift.
Call this from your backend so the secret never reaches the browser.
All Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/api/2fa/secret | GET / POST | New base32 secret + otpauth URL + QR data-URI. Params: issuer, account |
/api/2fa/code | GET / POST | Current 6-digit code for a secret + seconds remaining. Params: secret |
/api/2fa/verify | POST | Verify a code. Params: secret, code, optional window |
/api/2fa/qr | GET | QR code as a PNG image. Params: secret, issuer, account |
Code Examples
JavaScript (Node or backend fetch)
// Enrolment const auth = {'Authorization': 'Bearer ' + process.env.PGN_API_KEY}; const res = await fetch('https://passwordgenerator.now/api/2fa/secret?issuer=MyApp&account=' + email, {headers: auth}); const {secret, qr_data_uri} = await res.json(); // … show qr_data_uri, save secret … // Login verification const check = await fetch('https://passwordgenerator.now/api/2fa/verify', { method: 'POST', headers: Object.assign({'Content-Type': 'application/json'}, auth), body: JSON.stringify({secret, code: userInput}) }); const {valid} = await check.json();
Python
import requests r = requests.post("https://passwordgenerator.now/api/2fa/verify", headers={"Authorization": f"Bearer {PGN_API_KEY}"}, json={"secret": secret, "code": code}) if r.json()["valid"]: login(user)
PHP
$ch = curl_init('https://passwordgenerator.now/api/2fa/verify'); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['secret' => $secret, 'code' => $code])); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Authorization: Bearer ' . $pgnApiKey]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $valid = json_decode(curl_exec($ch))->valid;
The Attribution Requirement
This API is free because attribution keeps it visible. In exchange for unlimited free calls, your site publishes one link back to this page. We verify it automatically.
- Add the link anywhere public on your site - Footer, docs page, security page or your 2FA settings screen.
- Register the page in your account under "2FA API key" and click Verify.
- Keep it live. We re-check daily. The first time a verified link disappears you get a 7-day grace window and an explanation, never a silent shutdown - Redesigns and migrations happen. After that first forgiveness, a link that disappears again pauses the key immediately, and putting the link back up re-activates it at the next daily check (or instantly if you click Verify).
Copy-paste snippet:
<a href="https://passwordgenerator.now/2fa-api"> Two-factor authentication powered by PasswordGenerator.now </a>
notice field counting down. After that, unverified keys return
402 attribution_required until the link is verified.
On link attributes: a normal followed
link is what we ask for and what we check. If your policy or Google's
link
guidelines lead you to prefer rel="sponsored" or
rel="nofollow", that still passes verification - We record which you used
and never reject a qualified link. Attribution is the requirement; PageRank is not.
Embeddable 2FA Widget
Drop-in iframe
A self-contained TOTP code generator your users can use on your own pages - Great for docs, admin panels and demos:
<iframe src="https://passwordgenerator.now/embed/2fa" width="320" height="380" style="border:1px solid #e2e8f0;border-radius:10px;" title="2FA code generator"></iframe>
Pass ?secret=BASE32… to preload a secret.
If you use the widget or API, please link back to
passwordgenerator.now/2fa-api so others can find it.
Live preview
Fair Use & Notes
- Stateless & private: secrets are never stored or logged; every request is computed in memory.
- Free account required: generate a key in the account panel - It keeps the service free by making abuse revocable.
- Fair use: keep it under ~60 requests/minute per key. Heavier? Talk to us.
- Production advice: verify on your backend, store secrets encrypted, and offer backup codes.
- Attribution: a link back to this page from your docs is appreciated and keeps the service free.
- Just need codes for yourself? Use the 2FA code generator.