NIV2FA

Preparing your verification workspace…

Docs

Network Identity Verification API

Drop-in phone proof for register, login, forgot password, and confirm order — SDK multi-source line match, webhook to your app. No OTP codes.

What this is for

Your mobile / web app (a Truzzt project) needs to prove a user really controls a phone number. Use Truzzt instead of SMS OTP for:

  • register — new account signup
  • login — passwordless or step-up login
  • forgot_password — reset only after identity match
  • confirm_order — high-risk checkout / COD confirm
  • Any other flow — pass your own purpose string
🔐
End users never see agent tokens. Agent tokens are admin gateway secrets only. Customers only open /verify/{sessionId}.

Activate (one-time setup)

  1. Create an account → open Dashboard.
  2. Create a Project (e.g. “Ecommerce Shop”, “Agent App”) — each project gets a 7-day trial.
  3. Set the project webhook URL (your backend, or the demo inbox while testing).
  4. Create an API key (niv_live_…).
  5. Top up wallet / subscribe to a plan after trial when required.

Runtime flow (mobile app)

  1. User enters phone in your app (register / login / forgot / order).
  2. Your backend calls POST /secure-api/v1/verifications with that phone + purpose + returnUrl.
  3. API returns sessionId, verifyUrl (same as pairUrl), and qrUrl / qrValue.
  4. Same device: open verifyUrl in WebView / Custom Tabs / SFSafariViewController / in-app browser.
  5. SIM on another phone: show qrUrl (or encode qrValue) so the other phone’s camera opens the link.
  6. Verify page opens in the SDK or Agent — reads device lines from multiple sources, then calls POST /secure-api/identity/verify.
  7. Server matches the registered phone against any reported line (SIM1, SIM2, device info, Contacts). No re-typing, no codes.
  8. Browser redirects to your returnUrl?sessionId=&status=completed&matched=true.
  9. Your project webhook receives identity.verified — use that to activate the user / unlock login / confirm the order.

Matching process (how lines are read & compared)

After the user opens verifyUrl inside the SDK / Agent and grants consent, the native bridge collects phone lines in the background. The verify page POSTs them to the server. Matching is phone-number only — we never accept the session phone as proof without a device-reported line.

Android sources (merged automatically)

Source tagWhat it reads
sim_chipSIM1 / SIM2 MSISDN via SubscriptionManager + TelephonyManager
device_info_apiMSISDN, IMEI, ICCID per slot (same fields as *#06# device info)
sim_settingsNumber from SIM settings / subscription info
dialer_star06*#06# “Device information” dialog (accessibility capture)
contacts_saved:…Owner contacts named e.g. My number / رقمي

iOS sources

Source tagMaps to Settings path
settings_phone_my_numberSettings → Phone → My Number (via Contacts Me card)
settings_cellular_sim1 / sim2Settings → Cellular → SIMs (each line on Me card)
contacts_mePhone app → Contacts → My Card
contacts_saved:…Saved contacts labeled as your own line

Server match rules

  • Registered session phone is compared to every reported line’s phone / msisdn / number (digits only).
  • Match if equal, or if one number is a suffix of the other (country-code variants, e.g. 772… vs 964772…).
  • First matching line wins — response includes matchedSlot and matchedSource.
  • IMEI / ICCID are stored for audit when reported; they do not replace phone matching.
  • Failures: SIM_REQUIRED (no lines read), SIM_MISMATCH (lines read but none match), PLAN_REQUIRED (trial ended, no plan).

Complete verification (SDK → server)

POST /secure-api/identity/verify

{
  "sessionId": "sess_…",
  "consent": true,
  "simPhone": "9647721421709",
  "sim2Phone": "9647708344321",
  "simPhones": [
    { "slot": "sim1", "phone": "9647721421709", "source": "device_info_api", "imei": "863541078890927", "iccid": "8996405005939060423" },
    { "slot": "sim2", "phone": "9647708344321", "source": "sim_chip" }
  ],
  "network": { "platform": "android", "entryMode": "sdk_bridge_multi", "lineSources": ["device_info_api","sim_chip"] }
}

SDK access gate: GET /secure-api/v1/sdk/access?projectId=… — requires valid API key + active trial or subscription.

Base URL

https://truzzt.site

Health: GET https://truzzt.site/secure-api/health

Authentication

Authorization: Bearer niv_live_YOUR_KEY
Content-Type: application/json

1 · Start verification

POST /secure-api/v1/verifications

{
  "phone": "9647XXXXXXXXX",
  "projectId": "proj_…",
  "purpose": "register",
  "clientUserId": "user_123_in_your_db",
  "referenceId": "optional-order-or-ticket-id",
  "returnUrl": "myapp://nif/result",
  "cancelUrl": "myapp://nif/cancel",
  "currency": "IQD"
}

purpose examples: register · login · forgot_password · confirm_order

Response highlights

{
  "success": true,
  "data": {
    "sessionId": "sess_…",
    "phone": "9647XXXXXXXXX",
    "status": "waiting",
    "matched": false,
    "purpose": "register",
    "verifyUrl": "https://truzzt.site/verify/sess_…",
    "pairUrl": "https://truzzt.site/verify/sess_…",
    "qrUrl": "https://api.qrserver.com/…",
    "qrValue": "https://truzzt.site/verify/sess_…",
    "returnUrl": "myapp://nif/result",
    "expiresAt": "…"
  }
}
📱
Show qrUrl (image) or render a QR from qrValue / verifyUrl. Opening verifyUrl on the same device is enough when the SIM is already in that phone.

2 · Poll (optional)

GET /secure-api/v1/verifications/:sessionId

Useful if the user stays in your app UI while another phone scans the QR. When done: status: "completed", matched: true.

3 · Webhook (source of truth for your backend)

Configure on the project. On success we POST:

{
  "event": "identity.verified",
  "sessionId": "sess_…",
  "projectId": "proj_…",
  "phone": "9647XXXXXXXXX",
  "matched": true,
  "matchedSlot": "sim1",
  "matchedSource": "device_info_api",
  "status": "completed",
  "purpose": "register",
  "clientUserId": "user_123_in_your_db",
  "referenceId": null,
  "verifiedAt": "…",
  "session": { /* full public session object */ }
}

Your app should: verify matched === true, optionally check matchedSlot (sim1 / sim2 / line1) and matchedSource, match clientUserId / phone / purpose, then complete register / login / reset / order confirmation. No OTP field exists.

4 · returnUrl (client UX)

After success the verify page redirects like a payment gateway:

myapp://nif/result?sessionId=sess_…&status=completed&matched=true

Works with HTTPS pages, PWAs, Flutter, Ionic, Capacitor, Cordova, React Native, native iOS/Android deep links. Still treat the webhook (or a server-side poll) as authoritative before granting access.

Example · Register

curl -X POST "https://truzzt.site/secure-api/v1/verifications" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "phone":"9647XXXXXXXXX",
  "projectId":"proj_…",
  "purpose":"register",
  "clientUserId":"pending_user_88",
  "returnUrl":"myapp://auth/register/done",
  "cancelUrl":"myapp://auth/register",
  "currency":"IQD"
}'

Example · Login / Forgot password / Confirm order

# login
{ "purpose":"login", "clientUserId":"user_88", "phone":"9647…", "returnUrl":"myapp://auth/login/done" }

# forgot_password
{ "purpose":"forgot_password", "clientUserId":"user_88", "phone":"9647…", "returnUrl":"myapp://auth/reset/done" }

# confirm_order
{ "purpose":"confirm_order", "referenceId":"order_90210", "clientUserId":"user_88", "phone":"9647…", "returnUrl":"myapp://orders/90210/confirmed" }

Cancel

POST /secure-api/v1/verifications/:sessionId/cancel

Demo / testing

Return URL
https://truzzt.site/demo/result

Webhook URL
https://truzzt.site/secure-api/demo/webhook

Open webhook inbox

curl -X POST "https://truzzt.site/secure-api/v1/verifications" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "phone":"9647XXXXXXXXX",
  "projectId":"proj_…",
  "purpose":"register",
  "currency":"IQD",
  "returnUrl":"https://truzzt.site/demo/result",
  "cancelUrl":"https://truzzt.site/demo/result?status=cancelled"
}'

Not this product

  • No OTP / SMS / WhatsApp / Telegram codes
  • No agent tokens on end-user screens
  • /device/pair/… is admin gateway fleet pairing only — not for customer register/login

Mobile SDK & plugins

Embed verification inside Flutter, Ionic, Capacitor, Cordova, React Native, Android, or iOS — multi-source line read, then match against the session phone.

SDK install & methods GitHub

Billing

Projects get a 7-day trial with unlimited verifications. After trial, subscribe by project count (3 / 7 / 15 / Enterprise). Wallet is for buying plans — not per-verify charges during trial or active plan.