Developer Reference
Authentication Dev — Integration Guide
This document describes the Authentication Dev module in kasookoo-sdk-backend: what it does, how it is implemented, and how to integrate it from client apps.
It is based on the Kasookoo Authentication Dev Technical Brief (June 2026, v1.0) and maps each recommended architecture option to concrete services and SIP/WhatsApp integration hooks in this repository.
Non-technical overview: AUTHENTICATION USE CASE
API details: Authentication API Reference
Table of contents
- Overview
- Verification options
- Architecture in this backend
- Authentication
- Configuration
- Prerequisites
- End-to-end flows
- SIP / WhatsApp integration
- Security
- Testing checklist
- Limitations
Overview
Authentication Dev uses a phone call as the verification signal instead of SMS OTP.
Under Nigerian telco rules, outbound calls use a fixed CLI (a single DID). Kasookoo cannot encode a per-session OTP in the caller ID. This module supports multiple verification architectures:
| Option | Method value | Summary |
|---|---|---|
| 1 — PSTN Call-back (recommended) | callback | User on a mobile dials Kasookoo's fixed DID over GSM/PSTN; verification uses the mobile's MSISDN |
| 2 — WhatsApp Call-back | callback_whatsapp | User on a mobile with WhatsApp places an inbound WhatsApp voice call; verification uses the WhatsApp caller ID mapped to MSISDN |
| 3 — Flashcall | missed_outbound_call | Brief outbound ring from fixed CLI; SDK detects missed call and verifies with device_fingerprint + session_id binding |
| 4 — Enhanced OTP Call | voice_otp | Outbound call + IVR reads OTP; OTP also delivered to App via push; user consents and verifies with one button |
| 5 — InApp | push_otp | Push delivers verification code to SDK; App shows OTP on screen with consent; user verifies with one button |
Verification options
Option 1 — PSTN Call-back (callback)
callback)Requirement: The user must complete verification from a mobile phone capable of placing a GSM/PSTN call via the native dialler (cellular network). Desktop, tablet-only, or in-app VoIP dialling are not supported for this option.
- App starts verification via SDK; SDK creates a session tied to the user's MSISDN (60 s TTL by default).
- SDK returns
session_id,did_number, andexpires_atto App. - App instructs the user to dial
did_numberfrom their mobile using the GSM/PSTN phone app (not from the integrating app). - The SIP server receives the inbound PSTN call from the mobile and forwards call metadata to the verification agent.
- The verification agent checks caller ID (ANI/MSISDN) and validates an active
pendingsession for the same org and MSISDN. - If checks pass, the agent marks the session
verifiedand tears down the call before full connect completes. - SDK/App receives verification status via push notification.
Option 2 — WhatsApp Call-back (callback_whatsapp)
callback_whatsapp)Requirement: The user must complete verification from a mobile phone with WhatsApp installed and able to place an inbound WhatsApp voice call. WhatsApp Web/desktop-only clients are not supported for this option.
- App starts verification via SDK; SDK creates a session with
method=callback_whatsapp. - SDK returns
session_id,whatsapp_number, andexpires_atto App. - App instructs the user to call
whatsapp_numberfrom their mobile WhatsApp app (voice call, not chat message). - WhatsApp Business API receives the inbound voice call from the mobile and forwards caller metadata to the verification agent.
- The verification agent maps WhatsApp caller ID (
wa_id) to normalized MSISDN and validates an activependingsession for the same org and MSISDN. - If checks pass, the agent marks the session
verifiedand tears down the call before full connect completes. - SDK/App receives verification status via push notification.
Option 3 — Flashcall (missed_outbound_call)
missed_outbound_call)Note: The API accepts
method: hybridandmethod: outbound_missed_callas legacy aliases formissed_outbound_call.
- App starts verification via SDK; SDK creates a session with
method=missed_outbound_callanddevice_fingerprint. - SDK returns
session_id,fixed_cli, andexpires_atto App. - SDK calls
POST /sessions/{id}/trigger-outbound— SIP server rings the user fromfixed_cli, then disconnects after the configured ring duration. - SDK detects the missed call from
fixed_clion the user's handset. - SDK calls
POST /sessions/{id}/verifywith matchingdevice_fingerprint. - SDK returns verification status to App.
Option 4 — Enhanced OTP Call (voice_otp)
voice_otp)- App starts verification via SDK; SDK creates a session with
method=voice_otp. - SDK returns
session_id,fixed_cli, andexpires_atto App. - SDK calls
POST /sessions/{id}/trigger-outbound— SIP server places an outbound call and sends the same OTP to SDK via push notification. - User answers the call; the voice agent reads OTP digits via IVR/TTS
- Push notification service delivers OTP to SDK; App shows consent screen (user agrees to hear audio and view OTP on screen).
- User taps a single Verify button; SDK auto-submits the OTP from the push payload via
POST /sessions/{id}/verify-otp. - SDK returns verification status to App.
Option 5 — InApp (push_otp)
push_otp)-
App starts verification via SDK; SDK creates a session with
method=push_otpanddevice_fingerprint. -
SDK returns
session_idandexpires_atto App. -
SDK calls
POST /sessions/{id}/trigger-outbound— backend sends a push notification with the verification code to SDK. -
Push notification service delivers OTP to SDK; App shows consent screen with OTP on screen.
-
User taps a single Verify button; SDK auto-submits the code from the push payload via
POST /sessions/{id}/verify. -
SDK returns verification status to App.
>
Architecture in this backend
| Layer | File | Responsibility |
|---|---|---|
| Config | app/config.py | SILENT_AUTH_CALL_* environment settings |
| Models | app/models/silent_auth_call_models.py | Request/response Pydantic models |
| Service | app/services/silent_auth_call_service.py | Session lifecycle, validation, SIP outbound, webhooks |
| API | app/api/silent_auth_call.py | REST endpoints under /api/v1/silent-auth-call |
| SIP hook | app/services/redis/webhook_pipeline.py | Inbound SIP/PSTN callback on participant_joined |
| Wiring | app/main.py | Router mounted at /api/v1 |
| Singleton | app/services/__init__.py | silent_auth_call_service instance |
All public routes:
/api/v1/silent-auth-call/...flowchart TB
subgraph Client
App[Mobile / Web App]
SDK[Kasookoo SDK]
end
subgraph Backend["kasookoo-sdk-backend"]
API[silent_auth_call.py]
SVC[SilentAuthCallService]
DB[(silent_auth_call_sessions)]
WH[webhook_pipeline.py]
PN[Push Notification Service]
end
subgraph Telephony
SIP[SIP server]
WA[WhatsApp Business API]
DID[Fixed DID - inbound]
CLI[Fixed CLI - outbound]
end
App --> SDK
SDK -->|Bearer SDK JWT| API
API --> SVC
SVC --> DB
SVC --> SIP
SVC --> PN
SIP --> WH
WA --> WH
WH --> SVC
PN --> SDK
SDK --> App
UserCall[User MSISDN] --> DID --> SIP
SIP --> CLI --> UserCall
UserCall --> WA
Authentication
All Authentication Dev endpoints require a valid SDK JWT (Authorization: Bearer <sdk_access_token>).
See AUTHENTICATION_DEV_API.md for token minting, tenant scope, request/response schemas, and HTTP error codes.
Configuration
Set these in .env.local or Docker .env:
| Variable | Default | Description |
|---|---|---|
SILENT_AUTH_CALL_DID_NUMBER | (empty) | Inbound DID fallback for Option 1 (PSTN) |
SILENT_AUTH_CALL_FIXED_CLI | CALLER_ID fallback | Outbound caller ID fallback for Options 3 & 4 |
SILENT_AUTH_CALL_SESSION_TTL_SECONDS | 60 | Session lifetime |
SILENT_AUTH_CALL_RATE_LIMIT_ATTEMPTS | 5 | Max session creations per MSISDN per window |
SILENT_AUTH_CALL_RATE_LIMIT_WINDOW_MINUTES | 10 | Rate-limit window |
SILENT_AUTH_CALL_OUTBOUND_RING_SECONDS | 3 | Flashcall ring duration before hangup |
SILENT_AUTH_CALL_VOICE_OTP_LENGTH | 4 | OTP digit length (clamped 4–6) |
MASTER_ORGANIZATION_ID | (empty) | Fallback org when JWT org resolution is unavailable internally |
Line resolution order: org's primary associated number (is_primary=true) → env vars above.
Example:
SILENT_AUTH_CALL_DID_NUMBER=+2348012345678
SILENT_AUTH_CALL_FIXED_CLI=+2348012345678
SILENT_AUTH_CALL_SESSION_TTL_SECONDS=60
SILENT_AUTH_CALL_OUTBOUND_RING_SECONDS=3Prerequisites
- SDK JWT — run Authentication → Create Client Session in Postman or your app auth flow.
- Primary associated number — create via
POST /api/v1/associated-numberswith"is_primary": truefor the org's inbound/outbound line. - SIP webhooks — must reach the SDK backend ingest path for Option 1 (PSTN) inbound callback.
- User mobile (Option 1) — GSM/PSTN-capable handset; user dials
did_numberfrom the native phone app. - WhatsApp Business API — inbound call webhooks configured for Option 2 (WhatsApp call-back).
- User mobile (Option 2) — WhatsApp installed; user places a voice call from the WhatsApp mobile app.
- Outbound SIP trunk — org trunk or
SDK_SIP_OUTBOUND_TRUNK_IDfor Options 3 & 4. - Push notification service — configured for Options 1, 2, 4, and 5 (verification status or OTP delivery).
End-to-end flows
Option 1 — PSTN Call-back
sequenceDiagram
participant App
participant SDK
participant API as Authentication Dev API
participant DB as DB
participant PN as Push Notification Service
participant Mobile as User mobile (GSM)
participant SIP as SIP server
participant WH as webhook_pipeline
App->>SDK: Start callback verification
SDK->>API: POST /sessions (Bearer JWT, method=callback)
API->>DB: insert pending session
API-->>SDK: session_id, did_number, expires_at
SDK-->>App: session_id, did_number, expires_at
App->>Mobile: "Dial {did_number} from your mobile"
Mobile->>SIP: Inbound GSM/PSTN call from MSISDN
SIP->>WH: participant_joined (SIP metadata)
WH->>API: handle_inbound_callback
API->>DB: resolve pending session by org + MSISDN
API->>DB: validate session is pending and unexpired
API->>DB: set status=verified
API->>SIP: hang up room
API->>PN: send verification status
PN-->>SDK: push notification (session verified)
SDK-->>App: verification status=verified
Steps:
- App asks SDK to start callback verification.
- SDK calls
POST /sessionswithmethod=callbackand creates a pending session in DB. - SDK returns
session_id,did_number, andexpires_atto App. - User mobile places an inbound GSM/PSTN call to
did_numberfrom the native dialler. - SIP server sends
participant_joinedmetadata towebhook_pipeline. - API resolves the pending session by org + MSISDN, validates TTL/status, and marks it
verified. - API hangs up the SIP call.
- Push notification service sends verified status to SDK.
- SDK notifies App that verification is complete.
Option 2 — WhatsApp Call-back
sequenceDiagram
participant App
participant SDK
participant API as Authentication Dev API
participant DB as DB
participant WA as WhatsApp Business API
participant PN as Push Notification Service
participant Mobile as User mobile (WhatsApp)
participant WH as webhook_pipeline
App->>SDK: Start WhatsApp callback verification
SDK->>API: POST /sessions (Bearer JWT, method=callback_whatsapp)
API->>DB: insert pending session
API-->>SDK: session_id, whatsapp_number, expires_at
SDK-->>App: session_id, whatsapp_number, expires_at
App->>Mobile: "Call {whatsapp_number} on WhatsApp"
Mobile->>WA: Inbound WhatsApp voice call from same number
WA->>WH: inbound_call webhook (wa_id metadata)
WH->>API: handle_whatsapp_callback
API->>DB: resolve pending session by org + mapped wa_id/MSISDN
API->>DB: validate session is pending and unexpired
API->>DB: set status=verified
API->>WA: hang up call
API->>PN: send verification status
PN-->>SDK: push notification (session verified)
SDK-->>App: verification status=verified
Steps:
- App asks SDK to start WhatsApp callback verification.
- SDK calls
POST /sessionswithmethod=callback_whatsappand creates a pending session in DB. - SDK returns
session_id,whatsapp_number, andexpires_atto App. - User mobile places an inbound WhatsApp voice call to
whatsapp_number. - WhatsApp Business API sends
inbound_callwebhook (wa_idmetadata) towebhook_pipeline. - API maps
wa_idto MSISDN, resolves pending session, validates TTL/status, and marks itverified. - API hangs up the WhatsApp call.
- Push notification service sends verified status to SDK.
- SDK notifies App that verification is complete.
Option 3 — Flashcall
sequenceDiagram
participant App
participant SDK
participant API as Authentication Dev API
participant DB as DB
participant SIP as SIP server
participant User
App->>SDK: Start Flashcall verification
SDK->>API: POST /sessions (Bearer JWT, method=missed_outbound_call, device_fingerprint)
API->>DB: insert pending session
API-->>SDK: session_id, fixed_cli, expires_at
SDK-->>App: session_id, fixed_cli, expires_at
SDK->>API: POST /sessions/{id}/trigger-outbound
API->>DB: store outbound_room_name
API->>SIP: outbound call to MSISDN (caller ID = fixed_cli)
SIP->>User: ring from fixed_cli (~3s)
API->>SIP: hang up after ring duration
User->>SDK: missed call detected (fixed_cli match)
SDK->>API: POST /sessions/{id}/verify (device_fingerprint)
API->>DB: validate pending session + device_fingerprint
API->>DB: set status=verified
API-->>SDK: verified=true, msisdn
SDK-->>App: verification status=verified
Steps:
- App asks SDK to start Flashcall verification.
- SDK calls
POST /sessionswithmethod=missed_outbound_callanddevice_fingerprint; API inserts pending session in DB. - SDK returns
session_id,fixed_cli, andexpires_atto App. - SDK calls
POST /sessions/{id}/trigger-outbound. - API stores
outbound_room_nameand places outbound call via SIP server (caller ID =fixed_cli). - User handset rings briefly (~3s); API hangs up to create a missed-call signal.
- SDK detects missed call from
fixed_clion the device. - SDK calls
POST /sessions/{id}/verifywith matchingdevice_fingerprint. - API validates session + fingerprint, sets
verified, and returns result to SDK. - SDK notifies App that verification is complete.
Option 4 — Enhanced OTP Call
sequenceDiagram
participant App
participant SDK
participant API as Authentication Dev API
participant DB as DB
participant SIP as SIP server
participant Agent as Voice Agent
participant PN as Push Notification Service
participant User
App->>SDK: Start Enhanced OTP Call verification
SDK->>API: POST /sessions (Bearer JWT, method=voice_otp)
API->>DB: insert pending session + generate otp_code
API-->>SDK: session_id, fixed_cli, expires_at
SDK-->>App: session_id, fixed_cli, expires_at
SDK->>API: POST /sessions/{id}/trigger-outbound
API->>DB: store outbound_room_name
API->>SIP: outbound call to MSISDN (caller ID = fixed_cli)
API->>PN: send OTP to SDK (session_id + otp)
SIP->>User: ring from fixed_cli
User->>SIP: answer call
SIP->>Agent: connect answered call
Agent->>User: IVR/TTS reads OTP digits
PN-->>SDK: push notification (OTP for on-screen display)
SDK-->>App: show consent UI (listen audio + OTP on screen)
User->>App: tap Verify (one button)
App->>SDK: confirm verification
SDK->>API: POST /sessions/{id}/verify-otp (otp from push payload)
API->>DB: validate pending session + otp_code
API->>DB: set status=verified
API->>SIP: hang up call
API-->>SDK: verified=true, msisdn
SDK-->>App: verification status=verified
Steps:
- App asks SDK to start Enhanced OTP Call verification.
- SDK calls
POST /sessionswithmethod=voice_otp; API inserts pending session and generatesotp_codein DB. - SDK returns
session_id,fixed_cli, andexpires_atto App. - SDK calls
POST /sessions/{id}/trigger-outbound. - API places outbound call via SIP server and sends OTP to SDK through the push notification service.
- User answers; voice agent reads OTP digits via IVR/TTS on the call.
- SDK receives push with OTP; App shows consent UI (user agrees to hear audio and view OTP on screen).
- User taps Verify once; SDK auto-submits OTP from push payload via
POST /sessions/{id}/verify-otp. - API validates session + OTP, sets
verified, and hangs up the call. - SDK notifies App that verification is complete.
Option 5 — InApp
sequenceDiagram
participant App
participant SDK
participant API as Authentication Dev API
participant DB as DB
participant PN as Push Notification Service
participant User
App->>SDK: Start InApp verification
SDK->>API: POST /sessions (Bearer JWT, method=push_otp, device_fingerprint)
API->>DB: insert pending session + generate push_code
API-->>SDK: session_id, expires_at
SDK-->>App: session_id, expires_at
SDK->>API: POST /sessions/{id}/trigger-outbound
API->>DB: resolve user by msisdn + org
API->>DB: read active push tokens
API->>PN: send push (session_id + verification code)
PN-->>SDK: push notification (OTP for on-screen display)
SDK-->>App: show consent UI (OTP on screen)
User->>App: tap Verify (one button)
App->>SDK: confirm verification
SDK->>API: POST /sessions/{id}/verify (device_fingerprint, code from push payload)
API->>DB: validate pending session + fingerprint + push_code
API->>DB: set status=verified
API-->>SDK: verified=true, msisdn
SDK-->>App: verification status=verified
Steps:
- App asks SDK to start InApp verification.
- SDK calls
POST /sessionswithmethod=push_otpanddevice_fingerprint; API inserts pending session and generatespush_codein DB. - SDK returns
session_idandexpires_atto App. - SDK calls
POST /sessions/{id}/trigger-outbound. - API resolves user by MSISDN + org, reads active push tokens, and sends push with verification code.
- Push notification service delivers OTP to SDK; App shows consent UI with OTP on screen.
- User taps Verify once; SDK auto-submits code from push payload via
POST /sessions/{id}/verify. - API validates session + fingerprint + code, sets
verified, and returns result to SDK. - SDK notifies App that verification is complete.
SIP / WhatsApp integration
Inbound PSTN callback (Option 1)
Hook: app/services/redis/webhook_pipeline.py → handle_silent_auth_call_inbound_from_webhook
Runs on SIP participant_joined webhook events when the participant is SIP and the called DID matches the org's primary associated number (or env fallback). The user must originate the call from a GSM/PSTN mobile via the native dialler. For PSTN inbound calls, verification is handled in the agent path: caller ID is extracted from SIP metadata, matched to a pending session, and only then the session is marked verified. This runs before normal SIP inbound user mapping so Authentication Dev takes precedence on the auth DID.
WhatsApp callback (Option 2)
Inbound WhatsApp voice call webhook events should provide caller metadata (wa_id) from the user's WhatsApp mobile app. WhatsApp Web/desktop clients are not valid origins. Verification logic should resolve a matching pending session, mark it verified, tear down the call, then notify SDK/App via push.
Flashcall (Option 3)
SilentAuthCallService.trigger_outbound() creates an outbound session room and places the call through the SIP server using the org trunk (or SDK_SIP_OUTBOUND_TRUNK_ID fallback). The call rings briefly from fixed_cli, then the SIP server disconnects to produce a missed-call signal on the user's handset. The SDK then calls POST /sessions/{id}/verify with device_fingerprint.
Enhanced OTP Call (Option 4)
Uses the same SIP outbound path as Option 3, but the user answers the call. A voice agent reads the server-generated OTP via IVR/TTS. In parallel, the backend sends the same OTP to SDK through the push notification service so App can display it on screen. App shows a consent prompt (listen to audio + view OTP), then the user confirms with a single Verify button; SDK auto-submits POST /sessions/{id}/verify-otp with the OTP from the push payload.
InApp (Option 5)
POST /sessions/{id}/trigger-outbound resolves the user by MSISDN, reads active push tokens, and sends a verification code via the push notification service to SDK. App displays the OTP on a consent screen; the user confirms with a single Verify button and SDK auto-submits POST /sessions/{id}/verify with the code from the push payload. No SIP call is placed.
Security
| Control | Implementation |
|---|---|
| Authentication | SDK JWT on all endpoints |
| Tenant isolation | Org from JWT; session routes return 404 for wrong org |
| Session TTL | Default 60 s; expired pending sessions auto-marked expired |
| Rate limiting | Max session creations per MSISDN per window |
| Flashcall replay protection | device_fingerprint required at create for missed_outbound_call; mismatch → 403 |
| InApp replay protection | device_fingerprint + code required for push_otp; mismatch → 403 |
| OTP secrecy | otp_code never returned; compared with secrets.compare_digest |
| HTTPS only | webhook_url must start with https:// |
Testing checklist
Use the Authentication Dev folder in Kasookoo_SDK_Backend_Complete.postman_collection.json.
- Run Authentication → Create Client Session (SDK JWT).
- Create an associated number with
"is_primary": true. GET /silent-auth-call/health→configured: true.- Option 1: Create
callbacksession → user dials DID from mobile GSM/PSTN dialler → verify via push notification. - Option 2: Create
callback_whatsappsession → user places WhatsApp voice call from mobile → verify via push notification. - Option 3: Create
missed_outbound_callsession → trigger outbound → SDK detects missed call → verify with fingerprint. - Option 4: Create
voice_otpsession → trigger outbound → receive OTP push → consent screen → one-button verify. - Option 5: Create
push_otpsession → trigger outbound → receive OTP push → consent screen → one-button verify.
Limitations
| Item | Status |
|---|---|
| Option 1 PSTN inbound callback via SIP webhook (GSM mobile dialler) | Implemented |
| Option 2 WhatsApp callback via inbound voice call webhook (WhatsApp mobile app) | Design documented — implementation pending |
| VoIP / in-app dialler origination on Option 1 | Not supported — GSM/PSTN mobile dialler required |
| WhatsApp Web / desktop origination on Option 2 | Not supported — WhatsApp mobile voice call required |
| Option 3 Flashcall + SDK verify | Implemented |
| Option 4 Enhanced OTP Call + one-button verify | Design documented — push OTP delivery and consent UI pending |
| Option 4 IVR/TTS OTP read-out on answered call | Not implemented — requires voice agent integration |
| Option 5 InApp + one-button verify | Design documented — consent UI pending; code submit via push payload |
| VoIP origination detection on inbound MSISDN | Not implemented — prefix validation only |
Related documentation
- AUTHENTICATION_USE_CASE.md — plain-language guide for product and business stakeholders
- AUTHENTICATION_DEV_API.md — REST API reference (endpoints, schemas, errors)
- AUTHENTICATION_DEV_MISSED_OUTBOUND_CALL.md — Flashcall option (
method: missed_outbound_call, Option 3) deep dive - AUTHENTICATION_DEV_PUSH_OTP.md — InApp option (
method: push_otp, Option 5) deep dive - POSTMAN_COLLECTION_README.md — SDK JWT setup
- ARCHITECTURE.md — system topology
- Kasookoo Authentication Dev Technical Brief (June 2026, v1.0)
Kasookoo Communications Ltd · Kasookoo SDK Backend
Updated 15 days ago
