Truzzt

Preparing your verification workspace…

Docs

Network Identity Verification API

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

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”) — new accounts get 1 year free with unlimited apps & auth.
  3. Set the project webhook URL (your backend, or the demo inbox while testing).
  4. Create an API key (trz_live_…).
  5. After year 1, subscribe to a plan when required.

Runtime flow (mobile app)

  1. Host app shows Login / Register / Forgot (password optional); user enters phone.
  2. Your backend calls POST /secure-api/v1/verifications with Bearer API key, projectId, phone, countryCode, purpose (login | register | forgot_password), returnUrl, cancelUrl, optional theme.
  3. API returns sessionId and verifyUrl (pairUrl is the same URL — legacy alias). Primary UX is not QR scanning.
  4. App calls configure(apiKey, projectId[, theme]) then Truzzt SDK openVerify({ url: verifyUrl }) — themed verify WebView on-device.
  5. SDK reads device lines (Android SIM + Contacts; iOS Contacts Me / owner lines), then POST /secure-api/identity/verify.
  6. Server matches the session phone against any reported line. No OTP. Plain browsers show an agent-style shell (Try again) and cannot complete match.
  7. Success → redirect to returnUrl?sessionId=&status=completed&matched=true.
  8. Your project webhook receives identity.verified. Demo: agent/app · Agent APK.

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 (free year ended, no plan).

Complete verification (SDK → server)

POST /secure-api/identity/verify

{
  "sessionId": "sess_…",
  "consent": true,
  "simPhone": "9647721421709",
  "sim2Phone": "9647831265942",
  "simPhones": [
    { "slot": "sim1", "phone": "9647721421709", "source": "device_info_api", "imei": "863541078890927", "iccid": "8996405005939060423" },
    { "slot": "sim2", "phone": "9647831265942", "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 + first-year free or active 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",
  "countryCode": "964",
  "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",
  "theme": {
    "primary": "#0B1F3A",
    "accent": "#FFC83D",
    "background": "#071525",
    "text": "#F7F4EE",
    "muted": "#94A3B8",
    "appName": "My App",
    "logoUrl": "https://example.com/logo.png"
  }
}

theme (optional) tints the verify WebView (preloader uses accent). You can also pass the same keys via SDK configure(…, theme) or query params on verifyUrl.

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_…",
    "returnUrl": "myapp://nif/result",
    "expiresAt": "…"
  }
}

Some legacy integrations may still receive optional qrUrl / qrValue fields; the recommended path is openVerify(verifyUrl) in the mobile SDK — no QR step in your UX.

📱
Pass verifyUrl to openVerify in the Truzzt SDK (Flutter, Capacitor, Cordova, React Native, Expo Dev Client, or native Android/iOS). See SDK docs and try agent/app.

2 · Poll (optional)

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

Useful if the user stays in your app UI while the SDK completes matching. 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, Expo (Dev Client), Android, or iOS — themed openVerify(verifyUrl), multi-source line read, webhook match.

SDK install & methods GitHub

Billing

New accounts get 1 year free with unlimited apps and unlimited verifications. After year 1, subscribe by project count (3 / 7 / 15 / Enterprise). Wallet is for buying plans — not per-verify charges during the free year or an active plan.