PushMirror
1-tap sign-in challenges inside your app or browser. Approve, deny, or match an emoji or digit. No extra consumer app to install. Same API key as email and WhatsApp.
npm install @zindua/sdk@zindua/sdk v1.4.0
PushMirror. Inside your product.
PushMirror mark by default, Powered by Zindua signature, check + celebration when approved. This is the same sheet your users see.
New machine sign-in
Check your phone
Tap the same icon on your trusted device.
Your app
PushMirror · now
Allow this sign-in?
Chrome · Kinshasa · just now
WhatsApp interactive
Zero-app path. Approve, deny, or match on the WhatsApp line linked to your Zindua project.
Web Push
Native browser notifications on Chrome, Safari, Firefox, and PWAs. Trusted device without a store app.
BYO FCM / APNs
Use your Firebase or APNs keys so the challenge lands inside the app your users already installed.
Emoji match
Login screen shows one icon. The push offers a few choices. Harder to phish aloud than a spoken code.
Realtime SSE
Browser login listens for approve or deny. No heavy polling. Session continues when the phone confirms.
OTP fallback
No trusted device or timeout? Fall back to WhatsApp or email OTP on the same project and API key.
You own the app. We own the challenge.
PushMirror orchestrates the challenge. Your WhatsApp line, Web Push, or FCM/APNs delivers it.
Your user
Has your app installed, or allowed Web Push on your site. No Zindua consumer app.
Your backend
Creates the challenge with @zindua/sdk (pushMirror), shows display on login, listens for the result.
PushMirror
Orchestrates challenge state, choices, expiry, webhooks, logs, and OTP fallback. Not a marketing push ESP.
From login screen to trusted device
How PushMirror interacts with your product when a user signs in from a new browser or phone.
User signs in
On web or a new device, your app starts login. You call PushMirror from the backend only.
PushMirror creates the challenge
We mint challenge id, type (approve, emoji, or digit), display target, choices, and expiry.
Push reaches a trusted device
Delivered via WhatsApp interactive, Web Push, or your FCM / APNs app. Payload includes context: device, city, time.
User responds on the phone
Approve / deny, or tap the matching emoji or digit shown on the login screen.
Your login unlocks
SSE or webhook tells your backend. Create the session. On deny or timeout, block or fall back to OTP.
Approve, emoji, or digit
Same API. Pick the UX that fits your risk and product tone.
Approve / Deny
approveC'est moi · Ce n'est pas moi
Best for “someone is signing in from Chrome · Kinshasa”. One tap. Classic PushMirror approve flow.
Emoji match
emoji😄 🚀 🔒 🌴
Login screen shows one emoji. Push shows 3–5 options. User taps the same one. Stops simple push phishing.
Digit match
digit42 · 17 · 83 · 09
Login shows a two-digit number. User picks the same number on the trusted device.
Wire PushMirror into your project
Four steps from API key to a live challenge on login.
Create a Zindua project
Sign in, create a project, copy your znd_live_ or znd_test_ key. Same key as email and WhatsApp.
Pick a delivery path
Link WhatsApp for interactive prompts, enable Web Push, or attach your FCM / APNs credentials (BYO).
Register trusted devices
After a successful login, register the device token (FCM, APNs, or Web Push) against your user id.
Create + listen on login
pushMirror.create from the server. Show challenge.display. pushMirror.listen (SSE) or webhook to open the session.
Same key. PushMirror on every stack.
Official guides with the same icons as the Developers menu. Each card links to its page. WordPress is a plugin download, not a Composer package.
Next.js
pushMirror.create + SSE listen + webhook HMAC on the server.
npm install @zindua/sdkOpen Next.js guideFastify
Node backend with @zindua/sdk. Add Fastify as your HTTP framework.
npm install @zindua/sdkOpen Fastify guideFastAPI / Python
Async create_challenge and Depends() patterns.
pip install zindua-sdkOpen FastAPI guidePHP / Laravel
createChallenge + signed webhook helpers.
composer require zindua/sdkOpen PHP guide.NET / C#
AddZindua + CreateChallengeAsync for ASP.NET Core.
dotnet add package Zindua.SdkOpen .NET guideWordPress
Download the Zindua Connect plugin for OTP login and WooCommerce. No Composer command.
Download WordPress pluginFlutter
Register token via POST /devices. Render PushMirror UI from the FCM payload.
Firebase + Flutter stepsiOS / APNs
Upload your APNs key in Firebase, then use the same FCM path as Android.
Open iOS / APNs guideFlutter SDK is on the roadmap. Until then, call POST /api/v1/challenges from your Dart backend or BFF, and handle the FCM / APNs payload in your Flutter app with the same challenge id + respond endpoint.
import { Zindua } from "@zindua/sdk";
const zindua = new Zindua({ apiKey: process.env.ZINDUA_API_KEY! });
// Backend: start a PushMirror challenge when the user tries to sign in
const challenge = await zindua.pushMirror.create({
to: "+243832499559", // or userId / userExternalId for device lookup
type: "emoji", // "emoji" | "approve" | "digit"
purpose: "login",
channel: "auto", // auto | whatsapp | webpush | fcm | byo
context: { device: "Chrome on macOS", city: "Kinshasa" },
fallbackChannel: "whatsapp",
});
// Login UI: show challenge.display (e.g. 😄 or 42)
// Trusted device: user taps the matching choice in your app / WhatsApp / Web Push
await zindua.pushMirror.listen(challenge.challengeId, {
onApproved: () => {
// create session / redirect
},
onDenied: () => {
// block or alert
},
});Mobile integration has its own guide
Beginner → intermediate → advanced tracks: where to put znd_live_, znd_sec_, and the FCM key; Firebase Console steps; project tree; SSE vs webhooks; emoji / digit / approve with a live phone demo.
Built for real login flows
Context, webhooks, and fallback so PushMirror sits next to your existing OTP.
Realtime SSE
The login page learns the result as soon as the phone responds. Keep the UX instant without hammering HTTP.
Brandable prompts
Set app name and logo in the developer dashboard so the challenge feels like your product, not a generic alert.
Signed webhooks
Get challenge.approved, denied, or expired on your backend with HMAC verification for audit and risk rules.
Context in every prompt
Pass device, city, IP, and purpose so users recognize a home login vs a suspicious one. Clear PushMirror context every time.
Ready to try PushMirror?
Create a project, link WhatsApp or Web Push, then ship one-tap sign-in with OTP fallback.