NIV2FA

Preparing your verification workspace…

Mobile SDK & plugins

Install Truzzt in Flutter, Ionic, Capacitor, Cordova, React Native, Java/Kotlin, or Swift. Call configure(apiKey, projectId) first. Android reads SIM chip, device info (*#06#), SIM settings, and Contacts; iOS reads Contacts Me card + saved owner lines (Settings → Phone / Cellular equivalent).

Platform matrix

No manual number entry. The SDK collects lines in the background after the user Allows access. Any matching line → success. Server never accepts the session phone without a device-reported line.

StackPathDevicesLine sources
Java / Kotlinandroid/AndroidSIM chip, device info API, *#06#, SIM settings, Contacts
Swiftios/iOSContacts Me, Cellular-equivalent lines, saved owner contacts
Capacitor / Ionicpackages/capacitorAndroid + iOSNative SDK per OS
Cordova / Ionic Cordovapackages/cordovaAndroid + iOSNative SDK per OS
Flutterpackages/flutterAndroid + iOSNative SDK per OS
React Nativepackages/react-nativeAndroid + iOSNative SDK per OS

How it works

  1. Your backend calls POST /secure-api/v1/verifications with the claimed phone + projectId.
  2. API returns verifyUrl (and QR).
  3. Your app calls openVerify({ url }) (SDK WebView / Agent).
  4. User Allows permission — SDK reads all available lines in background.
  5. Verify page POSTs lines → server matches registered phone against any reported line.
  6. Match → matched: true + webhook identity.verified (includes matchedSlot, matchedSource).
  7. SDK returns success to your app UI.

Shared methods & result

MethodPurpose
configure(apiKey, projectId)Required before any SDK call; validates trial/plan via /sdk/access
requestPermissions()Phone + Contacts (Android); Contacts (iOS)
getSimPhones() / getDeviceIdentity()All collected lines (phone + optional IMEI/ICCID)
checkAuthentication(expectedPhone)Background check — does any line match? Returns sources used
captureDeviceInfoDialog()Android only — trigger *#06# for accessibility capture
openVerify({ url })Permission → read → match → { matched, matchedSlot, sessionId }
{
  "matched": true,
  "status": "completed",
  "matchedSlot": "sim1",
  "matchedSource": "device_info_api",
  "sessionId": "sess_…",
  "platform": "android" | "ios"
}

Always treat the webhook as the source of truth for your backend.

Line sources (Android & iOS)

Android merges these automatically (each line tagged with source):

  • sim_chip — SIM1/SIM2 MSISDN from telephony APIs
  • device_info_api — MSISDN, IMEI, ICCID per slot (same as *#06#)
  • sim_settings — number from subscription / SIM settings
  • dialer_star06 — *#06# dialog via accessibility service (optional)
  • contacts_saved:… — owner contacts (My number / رقمي)

iOS (Apple does not expose SIM chip MSISDN):

  • settings_phone_my_number — Settings → Phone → My Number (via Contacts Me)
  • settings_cellular_sim1 / sim2 — Settings → Cellular → each SIM line
  • contacts_me — Phone → Contacts → My Card
  • contacts_saved:… — saved owner contacts

Authentication & matching

Before verify, call checkAuthentication(expectedPhone) to see if any collected line matches (returns authenticated, matches[], sources[]). During verify, the server compares the session phone to every reported line — exact or suffix match (country-code variants). IMEI/ICCID are audit metadata only.

Trial + active plan = unlimited verifications. Wallet is for buying subscription plans only.

Permissions

Android: READ_PHONE_STATE, READ_PHONE_NUMBERS, READ_CONTACTS, INTERNET. Optional: enable Truzzt Device Info accessibility for *#06# capture.

iOS: Contacts permission + NSContactsUsageDescription. User must have their number on Me card or saved owner contacts.

Plain browsers cannot read device lines — open verifyUrl inside SDK or Agent only.

Android (Java / Kotlin)

Docs: ANDROID.md · Module: android/

git clone https://github.com/kreatedeviq/truzzt-sdk.git

# settings.gradle
include ':truzzt-sdk'
project(':truzzt-sdk').projectDir = new File('path/to/truzzt-sdk/android')

# app/build.gradle
implementation project(':truzzt-sdk')
TruzztSdk.requestPermissions(this)
startActivityForResult(TruzztSdk.verifyIntent(this, sessionUrl), 9101)
// onActivityResult → TruzztSdk.parseResult(data)

iOS (Swift)

Docs: IOS.md · Package: ios/ (SPM)

.package(url: "https://github.com/kreatedeviq/truzzt-sdk.git", from: "1.0.0")
// product: TruzztSdk

TruzztSdk.openVerify(from: self, sessionUrl: url) { result in
  // result.matched — no manual SIM typing
}

Same product rule: SDK bridge only. For dual-SIM chip MSISDN, Android SDK / Agent is the reliable path (Apple limits silent MSISDN).

Capacitor / Ionic Capacitor

Docs: CAPACITOR.md · Android + iOS

npm i https://github.com/kreatedeviq/truzzt-sdk/packages/capacitor
npx cap sync

import Truzzt from '@truzzt/capacitor'
await Truzzt.requestPermissions()
const r = await Truzzt.openVerify({ url: verifyUrl }) // SDK reads SIMs → match

Cordova / Ionic Cordova

Docs: CORDOVA.md · Android + iOS

cordova plugin add https://github.com/kreatedeviq/truzzt-sdk.git#main:packages/cordova

Truzzt.requestPermissions(console.log, console.error)
Truzzt.openVerify({ url: verifyUrl }, console.log, console.error)

Flutter

Docs: FLUTTER.md · Android + iOS

dependencies:
  truzzt_flutter:
    git:
      url: https://github.com/kreatedeviq/truzzt-sdk.git
      path: packages/flutter

await TruzztFlutter.requestPermissions();
final r = await TruzztFlutter.openVerify(verifyUrl);

React Native

Docs: REACT_NATIVE.md · Android + iOS

import { openVerify, requestPermissions } from '@truzzt/react-native'
await requestPermissions()
const r = await openVerify(verifyUrl)

Adjustment & making it work

  1. Set project webhook_url in the dashboard.
  2. Create session with the exact phone the user claims (E.164).
  3. Open verifyUrl via openVerify in the SDK (not Chrome).
  4. User Allows Phone + Contacts — SDK reads all sources automatically.
  5. Match → success + webhook. Check matchedSource to see which source matched.

Common issues

SymptomFix
SDK_REQUIREDOpen verify inside SDK / Agent — browsers cannot read SIMs
Permission deniedUser must Allow Phone; call requestPermissions again
Empty line list (Android)Enable accessibility for *#06#; save number as contact "رقمي"; check carrier exposes MSISDN
Empty line list (iOS)Add number to Contacts → My Card; or save contact named "My number"
MismatchSDK-read number ≠ registered session phone — expected fail
Gradle / plugin missingFix path / cap sync / clean rebuild

Clone

git clone https://github.com/kreatedeviq/truzzt-sdk.git
cd truzzt-sdk
# Guides: docs/ANDROID.md · IOS.md · CAPACITOR.md · CORDOVA.md · FLUTTER.md · REACT_NATIVE.md