Skip to content
Approve

Approve a login on the phone the user already trusts.

When someone signs in on the web or a new device, SignOps sends a push to the user's trusted phone. They match a number and confirm with Face ID or a fingerprint, and your server gets the answer.

  • 100 approvals a day free
  • Rs 0.30 an approval after
  • Number matching on every request
How it works

Four steps, about four seconds.

  1. 01

    Enrol once

    After your own login, the SDK makes a key pair on the phone. The private key stays in the Keystore or Secure Enclave.

  2. 02

    Ask

    Someone signs in on the web. Your server creates a request and shows a number, like 47, on the login page.

  3. 03

    Match and confirm

    The phone shows who is signing in, from where. The user picks the same number and confirms with Face ID or a fingerprint.

  4. 04

    Signed answer

    The phone signs the request. SignOps checks the signature and your server gets approved or denied.

Security

The push rings the bell. The signature opens the door.

A push only wakes the app. The approval itself is a signature from a key that was made on that phone and cannot be copied off it. A stolen push token, or a copy of the push, approves nothing.

  • Each request is a fresh challenge, signed once and then spent.
  • The biometric unlocks the key on the phone; SignOps never sees a face or a fingerprint.
  • Denials reach your server at once, so you can lock the account or alert the user.
Your server decides

Ask, wait, sign the user in.

Create a request with a line of context, show the number on your login page, and wait for the answer or take it by webhook. The phone side is one call to enrol and a ready-made screen.

  • Logins on a new device, step-up before a sensitive action, approving a payment.
  • The context line is yours: "Withdraw Rs 25,000 to HDFC ****4821".
  • A ready-made approve screen in your colours, or headless functions for your own.
login.ts
// Someone is signing in on the web.
// Ask the user's trusted phone.
const challenge = await signops.approve.create({
  user_id: "usr_8f21c4",
  context: "Sign in from Chrome on Windows",
});

// Show challenge.match ("47") on the login page.
const result = await signops.approve.wait(challenge.id, {
  timeout: 120,
});

if (result.status === "approved") startSession(result.user_id);
When the push is late

A fallback for every phone.

Some Android phones hold pushes while an app sleeps. When the user opens your app, the SDK fetches any waiting request. If no trusted phone answers in time, your server sends an email OTP instead.

  1. 1
    PasskeyNo passkey on this laptop yet
    Skipped
  2. 2
    ApprovePush to the trusted Pixel 8, number 47
    Approved in 4 s
  3. 3
    Email OTPUsed only when no trusted phone answers
    Not needed
  4. 4
    Push"New login on Chrome in Pune" to the other devices
    Sent
Every answer, recorded

Who approved, on which phone, how fast.

Each request keeps its device, its number, its biometric and its answer. Your security team sees denials the moment they happen.

Cost

Rs 0.30 against about Rs 4.40 on Twilio.

What one lakh approvals a month cost, before GST. An SMS OTP is cheaper per message; it is also the one a caller can talk out of your user.

SignOps: Starter at Rs 499, plus 1,00,000 approvals less the 1,000 it includes, at Rs 0.30.

The numbers

Details and limits

SDKs
Android (Kotlin), iOS (Swift), React Native and Flutter.
Keys
A P-256 key pair per device, in the Android Keystore or the iOS Secure Enclave. The private key never leaves the phone.
Trusted devices per user
Up to 5.
Request expiry
2 minutes.
Number matching
Always on. The phone shows three numbers and the user picks the one on the login screen.
Confirmation
Face ID, Touch ID, a fingerprint or the device PIN, every time.
What the phone shows
The device, the city from the IP address, the time and a line of your own, like an amount for a payment.
Getting the answer
Wait on the request from your server, or receive a signed webhook.
Push not delivered
The app picks up pending requests when it opens. Your server can fall back to an email OTP.
Records
Every request and answer for 90 days, 1 year on Pro.
Price
Free plan: 100 approvals a day. Starter and Pro: 1,000 a month included, then Rs 0.30 each. An approval counts when the user approves or denies; requests that expire are free.

Approve questions

More questions? Email us and the answer goes on this page.

hello@signops.dev
Can Approve sign up a new user?

No. It works on a phone that has already signed in to your app and enrolled. New users, first logins and lost phones use email OTP or a passkey.

Why number matching on every request?

Without it, an attacker with a password can send request after request until a tired user taps yes. Picking the number shown on the login screen means only the person in front of that screen can approve.

Why pay more than an SMS OTP?

An SMS OTP costs Rs 0.13 to 0.15; an approval costs Rs 0.30. What the difference buys: nothing to read out to a caller, nothing a SIM swap can catch, no DLT templates to register, and a signature from a key that never leaves the phone. Expired requests are free.

Does it work for payments?

Yes. Send the amount and the payee as the context line, and the phone shows them on the approve screen. In-app notification approval is one of the alternatives to SMS OTP that the RBI named in its 2025 directions on authentication for digital payment transactions. Whether your flow meets those directions is for your compliance team to confirm.

What if the user loses the phone?

Remove the device from your server or the dashboard, and let the user back in with an email OTP or a passkey. They enrol the new phone after that login.

Replace your next SMS OTP with an approval.

100 approvals a day on the free plan. On Starter, 1,000 a month included, then Rs 0.30 each. Requests that expire cost nothing.