Authenticator app codes, without storing secrets yourself.
Users scan a QR into Google Authenticator or any TOTP app and type its six-digit code at sign-in. SignOps keeps the key encrypted, checks the codes, hands out backup codes and locks out guessing.
- 10,000 checks a month free
- Backup codes included
- Lock after 5 wrong codes
Three calls, all from your server.
Enrol returns the QR for your page. The first code the user types confirms it and returns their backup codes. After that, one call checks each code.
- No secret in your database, so a leaked copy of it holds no keys.
- No library on the phone: the user's own authenticator app does the work.
- The same user id as push, Approve and passkeys.
// Enrol: show the QR on your page.
const { qr_svg, secret } = await signops.totp.enroll({
user_id: "usr_8f21c4",
label: "ananya@example.in",
});
// The first code turns it on. Show the backup codes once.
const { backup_codes } = await signops.totp.confirm({
user_id: "usr_8f21c4", code: req.body.code,
});
// At sign-in: a 6-digit code or a backup code.
const { valid, method } = await signops.totp.verify({
user_id: "usr_8f21c4", code: req.body.code,
});$e = $signops->totp->enroll([
'user_id' => 'usr_8f21c4',
'label' => 'ananya@example.in',
]);
// Show $e['qr_svg'] on your page.
$c = $signops->totp->confirm('usr_8f21c4', $request->input('code'));
// Show $c['backup_codes'] once.
$r = $signops->totp->verify('usr_8f21c4', $request->input('code'));
$ok = $r['valid'];e = signops.totp.enroll(
user_id="usr_8f21c4",
label="ananya@example.in",
)
# Show e.qr_svg on your page.
c = signops.totp.confirm("usr_8f21c4", request.form["code"])
# Show c.backup_codes once.
r = signops.totp.verify("usr_8f21c4", request.form["code"])
valid = r.validcurl https://api.signops.dev/v1/totp/enroll \
-H "Authorization: Bearer $SIGNOPS_KEY" \
-d user_id=usr_8f21c4 -d label=ananya@example.in
curl https://api.signops.dev/v1/totp/confirm \
-H "Authorization: Bearer $SIGNOPS_KEY" \
-d user_id=usr_8f21c4 -d code=492039
curl https://api.signops.dev/v1/totp/verify \
-H "Authorization: Bearer $SIGNOPS_KEY" \
-d user_id=usr_8f21c4 -d code=815307Ten codes for the day the phone is lost.
Show them once when the authenticator is confirmed. Each works one time, in the same verify call as an app code, and the answer says how many are left.
A code that never travels.
No SIM to swap
The code is made on the phone from a key it already has. Nothing is sent over SMS, so there is no message to intercept or reroute.
Works offline
The app needs no signal and no data. Users abroad or on a weak network still get in.
A fifth of a paisa a sign-in
An SMS code costs about Rs 0.17 in India. Past the plan, an authenticator check is Rs 0.002: Rs 100 for 50,000 sign-ins.
Details and limits
- Standard
- TOTP (RFC 6238): SHA-1, 6 digits, a new code every 30 seconds. What Google Authenticator expects.
- Apps
- Google Authenticator, Microsoft Authenticator, Authy, 1Password, Bitwarden and any other TOTP app.
- Enrolment
- An
otpauth://link, a QR code as SVG and the key as text. Nothing works until the first code confirms it. - Clock drift
- A code is accepted 30 seconds early or late.
- Each code
- Works once. A code already used, or older than the last one used, is refused.
- Backup codes
- 10 single-use codes like
7KQM-3XPA, checked in the same call as app codes. New ones replace the old. - Lock
- 5 wrong codes in 15 minutes lock the user for 1 minute, doubling with each lock up to 1 hour. Your server can unlock early.
- Authenticators per user
- One. Remove it to enrol a new phone.
- Stored by SignOps
- The key, encrypted with AES-256-GCM, and an HMAC SHA-256 of each unused backup code. Never a backup code in clear.
- Price
- 10,000 checks a month on Free, 1 lakh on Starter, 5 lakh on Pro. Past that, Rs 100 per 50,000, billed per check. On Free, checks pause after 10% grace until the 1st.
- What counts
- Every verify that gets an answer, right or wrong. Enrolment, confirming and calls refused while a user is locked do not count.
Do my users see SignOps anywhere?
No. The authenticator app shows your app's name and the label you pass, usually the user's email. The QR is shown on your page.
What does it cost?
Free includes 10,000 checks a month, Starter 1 lakh and Pro 5 lakh. Past that it is Rs 100 per 50,000 checks, billed per check, so 10,000 more cost Rs 20. An SMS code costs about Rs 0.17; 50,000 of them cost about Rs 8,500.
What if the user loses their phone?
They sign in with one of their backup codes, or another method such as an email code or a passkey. Then your server removes the old authenticator and they enrol the new phone.
Can an attacker guess codes?
Each user gets 5 tries in 15 minutes before a lock, and each lock doubles the next one, up to an hour. Guessing a 6-digit code that way takes years. You get a user.locked webhook each time.
Does it replace SMS OTP?
For sign-ins after the first, yes. A user who has set up an authenticator types its code instead of waiting for an SMS. Sign-up still needs a way to reach a new user, like an email code.
Set it up step by step
All setup guidesGuides for this product
All guidesAdd authenticator codes this week.
10,000 checks a month on the free plan, with backup codes and lockout included.