Mobile & Web SDKs · v1.1.0

Web SDK

@quickauth/web — phone OTP, WhatsApp OTP, and marketing attribution for any JavaScript app. 3.6 KB gzipped, zero runtime dependencies, ESM + CJS + UMD builds.

Install

npm install @quickauth/web

Initialize

Call init once on app boot. Pass an onTokenExpirycallback that returns a short-lived QuickAuth session JWT (your backend mints this via POST /v1/sdk/session), and an onAuthEvent handler that receives the typed lifecycle events the SDK emits.

quickauth-init.js
import { QuickAuth } from '@quickauth/web'

QuickAuth.init({
  // Returns a fresh session JWT from your backend. The SDK auto-refreshes
  // ~30s before expiry, so this is called rarely.
  onTokenExpiry: async () =>
    (await fetch('/api/quickauth-token').then(r => r.json())).sessionToken,

  // Single typed event stream the SDK pushes lifecycle events into.
  onAuthEvent: (event) => {
    switch (event.type) {
      case 'OTP_SENT':      showOtpInput(); break
      case 'OTP_AUTO_READ': prefillInput(event.code); break
      case 'VERIFIED':      finishLogin(event.requestId); break  // covers OneTap silent re-auth too
      case 'OTP_FAILED':    showError(event.message); break
      case 'ERROR':         showError(event.message); break
    }
  },
})

Consent (DPDP / GDPR)

By default, the SDK refuses to send identifiable fields (phone, fingerprint, attribution params) until you call consent.set(true).

javascript
// Once the user accepts your cookie / privacy banner:
QuickAuth.consent.set(true)

// Read state any time:
const ok = QuickAuth.consent.get()        // boolean

// React to changes (e.g. revoke flow):
QuickAuth.consent.subscribe((granted) => {
  console.log('Consent now:', granted)
})

Headless flow

Two methods. initiate kicks off the auth attempt; submitOtp hands back the user-typed code. All outcomes arrive as typed events on the onAuthEvent handler you registered at init — including the OneTap silent re-auth path, where the backend recognises the trusted device and emits VERIFIED without ever sending an OTP.

javascript
// Step 1 — kick off the attempt. Returns a promise that resolves once the
// network call dispatched; lifecycle events arrive via onAuthEvent.
await QuickAuth.auth.initiate({
  phone:   '+919876543210',
  channel: 'auto',   // 'auto' | 'sms' | 'whatsapp'
})
// → onAuthEvent fires with one of:
//     { type: 'OTP_SENT',  sessionId, channel, expiresIn }   // show OTP input
//     { type: 'VERIFIED',  requestId }                       // OneTap fired
//     { type: 'ERROR',     code, message }                   // transport failure

// Step 2 — when OTP_SENT fires and the user types a code:
await QuickAuth.auth.submitOtp('123456')
// → onAuthEvent fires with:
//     { type: 'VERIFIED',   requestId, message }   // forward requestId to your backend
//     { type: 'OTP_FAILED', message }              // wrong code, retry allowed
//     { type: 'ERROR',      code, message }

// On user-initiated logout, drop the device-trust token so the next session
// behaves like a brand-new install (no OneTap):
QuickAuth.auth.reset({ forgetDevice: true })

OneTap is automatic

When OneTap is enabled for your merchant and the device has previously verified successfully, initiate emits VERIFIED directly — no SMS sent, no OTP screen needed. Your onAuthEvent handler simply jumps to the logged-in state. Switch on event type; you don't need to check any implementation-specific flag.

SMS auto-fill (WebOTP API)

On Android Chrome, an SMS that includes the WebOTP origin annotation gets auto-detected and inserted into a properly-tagged input. The SDK ships a tiny helper that wires the browser API to your callback:

javascript
// Subscribe once your OTP input is mounted.
QuickAuth.auth.observeOTP({
  onCode: (code) => {
    // Auto-fill your input and (optionally) auto-submit.
    document.querySelector('#otp').value = code
  },
})

iOS auto-fill is browser-native

Safari on iOS recognises OTP messages automatically through autocomplete="one-time-code" on the input — no JS needed. The SDK helper above is a no-op on iOS; it only activates the WebOTP API on supported Chromium browsers.

WhatsApp OTP

Skip OTP entirely for users on WhatsApp — the SDK opens a wa.me chat with a one-tap verification message, then catches the return URL.

javascript
await QuickAuth.auth.startWhatsAppLogin({
  businessNumber: '+919574980048',
  returnURL:      'https://app.example.com/wa-return',
})

// In your /wa-return route, capture the launch params:
await QuickAuth.attribution.captureLaunch()  // reads window.location

Attribution & conversions

javascript
// Call once per session — captures qa_clid / UTM / referrer / fingerprint
// (consent-gated).
await QuickAuth.attribution.captureLaunch()

// Track a conversion when the user completes value-bearing action:
await QuickAuth.attribution.trackConversion({
  event:    'signup',
  value:    0,
  currency: 'INR',
  metadata: { plan: 'free' },
})

API reference

MethodDescription
init(config)Initialize the SDK. Call once on app boot.
consent.set(granted)Set consent state. Booleans only.
consent.get()Read current consent state.
consent.subscribe(cb)Listen to consent changes. Returns an unsubscribe fn.
auth.initiate({ phone, channel })Begin an auth attempt. Emits OTP_SENT or VERIFIED via onAuthEvent.
auth.submitOtp(code)Submit the user-typed code. Emits VERIFIED or OTP_FAILED.
auth.reset({ forgetDevice })Reset the state machine. Pass forgetDevice: true on logout to drop the OneTap trust token.
auth.observeOTP({ onCode })WebOTP API hook. Also surfaces auto-read codes as OTP_AUTO_READ events.
auth.startWhatsAppLogin(params)Open wa.me login chat.
attribution.captureLaunch()Read URL params + fingerprint and POST to attribution.
attribution.trackConversion(params)Mark a conversion event.

Source & changelog

Source: github.com/quickauthin/quickauth-sdk-web. Releases: GitHub Releases. Package: @quickauth/web on npm.