Architecture, integration, security, and performance - everything your engineering team needs to evaluate Jingle.
Prepared by Minutes Network FZ-LLC for engineering evaluation
Jingle is a lightweight Android plug-in that enables your mobile application to function as an international voice termination endpoint within Minutes Network's carrier infrastructure. Incoming international calls are routed via SIP/VoIP through opted-in users' devices, generating wholesale voice termination revenue that is shared with you - the app partner.
This document provides the technical detail your engineering team needs to evaluate integration feasibility, architecture compatibility, and security posture.

Three-layer system from client SDK through Minutes Platform to global carrier interconnections.
| Codec | Bitrate | Quality | Use Case |
|---|---|---|---|
| Opus | 6-510 kbps |
HD
|
Primary (adaptive bitrate) |
| G.722 | 64 kbps |
Wideband
|
Fallback |
| G.711 u-law | 64 kbps |
Standard
|
Legacy compatibility |
Everything your engineering team needs to integrate the Jingle Plug-In.

| Requirement | Specification |
|---|---|
| Android API | minSdk 26 (Android 8.0 Oreo), targetSdk 35 |
| Permissions | RECORD_AUDIO, INTERNET, FOREGROUND_SERVICE, MANAGE_OWN_CALLS + more (see Step 2) |
| Dependencies | None external (self-contained) |
| SDK Size | 3-10MB (AAR) |
| Build System | Gradle (AGP 7.0+) |
| R8 / ProGuard | -keep class io.minutesnetwork.jingle.** { *; } |
// settings.gradle.kts - private Nexus repository. Credentials are // read from a gitignored properties file supplied during onboarding. maven { url = uri("https://nexus.minutesnet.work/repository/maven-releases/") credentials { username = nexusProps.getProperty("nexusUsername") password = nexusProps.getProperty("nexusPassword") } } // app/build.gradle.kts implementation("io.minutesnetwork:jingle-fullservice:5.6.0")
<!-- Core permissions - the full list ships with the SDK docs --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" /> <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- JingleService and ActiveCallService are declared by the SDK's own manifest with the correct foregroundServiceType - do not redeclare -->
// Gate on permissions, then start the foreground call service private fun startSdkIfReady() { if (!JinglePermissions.check(this).allGranted) return JingleAdapter.getInstance(this).start(JingleStartParameters( serviceTitle = getString(R.string.call_service_title), notificationIconRes = R.drawable.ic_notification )) } // After SMS verification (Step 4), activate with the verified JWT JingleAdapter.getInstance(this).activate(JingleActivationParameters(jwt))
val jingle = JingleAdapter.getInstance(context) // SMS one-time-passcode consent flow. The appId is assigned in the // Partner Portal; both calls do network IO - keep them off the main thread. val sessionJwt = jingle.sendSmsChallenge(phoneNumber, "your_app_id") val verifiedJwt = jingle.verifySmsChallenge(sessionJwt, code) // Activate the verified user, then register for push-to-call wakeups jingle.activate(JingleActivationParameters(verifiedJwt)) jingle.setFcmToken(token)
// Required vs optional (e.g. READ_CONTACTS for caller names) runtime permissions val required = JingleAdapter.getPermissionsList() val optional = JingleAdapter.getOptionalPermissionsList() // Re-check before every start - users can revoke from system Settings val check = JinglePermissions.check(this) if (!check.allGranted) launcher.launch(check.missing.map { it.id }.toTypedArray()) // The lock-screen call UI needs the full-screen-intent special access if (!JingleAdapter.canUseFullScreenIntent(this)) JingleAdapter.requestFullScreenIntentPermission(this) // Since 5.5.0, start() throws if a runtime permission was revoked mid-session try { startSdkIfReady() } catch (e: JingleMissingPermissionException) { launcher.launch(e.missing.map { it.id }.toTypedArray()) }
JingleAdapter.getInstance()
.start()
.activate()
.deactivate()
.setFcmToken()
.setCallEndedCallback()
JinglePermissions.check()
.handleFcmMessage()
// Register in Application.onCreate so the call lifecycle works even // when no Activity is bound (e.g. answers from the lock screen). // The SDK replays cached state synchronously on registration. override fun onCreate() { super.onCreate() val jingle = JingleAdapter.getInstance(this) // Fires exactly once per call, on the main thread jingle.setCallEndedCallback { event: CallEndedEvent -> recordCall(event) // carries the CallOutcome } // Auth lifecycle - drive re-verification UI from here jingle.setAuthStateCallback { state: AuthState -> onAuthChanged(state) // AuthFailureType on failures } // Push-to-call wakeup progress (WakeStage) for diagnostics jingle.setWakeStageCallback { event: WakeStageEvent -> trace(event) } }
CallEndedEvent public fields: callId, callerNumber, durationMs, startTimeMs, answered, and outcome (CallOutcome.ANSWERED / REJECTED / FAILED).
Data minimisation by design. Encrypted signalling, ephemeral audio, and continuous monitoring.
| Data Point | Purpose | Storage |
|---|---|---|
| Audio (ephemeral) | Call routing | Real-time only, never stored |
| Device network type | Route optimisation | Session only |
| Country (from verified number) | Geographic routing | Session only |
| Call quality metrics | QoS monitoring | Aggregated, 30 days |
| SDK state/errors | Diagnostics | Aggregated, 7 days |
Personal data, contacts (the optional READ_CONTACTS permission is used only to display saved names on the incoming-call screen - contacts never leave the device), messages, browsing history, precise location, device identifiers (beyond anonymous session tokens), audio recordings (audio is processed ephemerally for real-time call routing and never stored).
All SIP signalling encrypted with the latest TLS standard.
Call audio is processed in real time for routing, never recorded or stored; calls hand off to Tier 1 carrier (PSTN) networks.
Plug-in-to-network signalling runs over TLS - there is no unencrypted control channel.
At-rest data uses AES-256 encryption on all server-side storage.
Data Processing Agreement (DPA) provided. Data minimisation by design. Right to erasure supported.
Prominent disclosure templates. Accurate Data Safety form responses. Feature-justified permissions.
Real-time revenue, minutes, opted-in users and call quality. Exportable reports from day one.
Engineered for minimal impact - negligible battery, data, and CPU.
At 8 minutes per month, total Jingle data usage is approximately 0.3-0.4MB - less than loading a single modern web page, watching a few seconds of video, or displaying one full-screen interactive ad. A single video ad typically consumes 2-5MB. Jingle's data footprint is negligible compared to virtually any other SDK or in-app content.
The plug-in uses the device's familiar call experience, with no extra Jingle screens for you to build. Users are informed up front via prominent disclosure and can turn Jingle off at any time. The foreground-service notification is visible to the user and is customisable to match your app's branding.
The plug-in uses a layered delivery model. An SDK-managed foreground service with a UDP wake path is the primary, most reliable way calls reach the device - and it runs independently of Google Mobile Services. Firebase Cloud Messaging is a fallback wake path on GMS devices. Each component has a distinct role.
The foreground service keeps a lightweight UDP wake path open so calls reach the device. Firebase Cloud Messaging is a fallback on GMS devices, handed to handleFcmMessage().
WakeStageEvent
Lightweight foreground service started by start(); its notification carries your serviceTitle and notificationIconRes.
Runs only for the duration of a call; requests the phoneCall|microphone foreground service types at runtime.
Both services are declared by the SDK's own manifest (since 5.1.2) - partners never declare or manage them directly.
The most reliable delivery path is an Android foreground service with a UDP wake path: it keeps the device ready for calls and runs independently of Google Mobile Services. Firebase Cloud Messaging is a fallback on GMS devices. The plug-in activates only when a call is available, consuming near-zero battery when idle. Battery-aggressive OEMs - Xiaomi, Huawei, Oppo, Vivo and Samsung, which dominate South Asia, Sub-Saharan Africa and Southeast Asia - can suspend even a foreground service, so JingleAdapter.requestUnrestrictedBatteryPermissions(ctx) guides the user through the device's battery-optimisation screen to exempt the app, maximising call availability.
How the plug-in handles every scenario your engineering team will ask about.
If a Jingle call is routed to a device that is already handling an active call (cellular or VoIP), the plug-in returns a 503 Service Unavailable response to the carrier. The call is automatically rerouted to another available user on the network. The end user is never interrupted or aware that a routing attempt was made.
The call session ends gracefully. The SDK detects the termination and releases the SIP session. Revenue is calculated for the minutes that were successfully routed before disconnection. There is no impact on the user's device.
Android 14 requires apps to declare a specific foregroundServiceType for all foreground services. The SDK's own manifest declares its services with the correct types - the in-call service requests phoneCall|microphone at runtime to keep the mic alive across screen-lock. The manifest merger provides these declarations automatically; partners must not redeclare them.
The Jingle Plug-In's core call routing (SIP signalling and media) does not depend on Google Play Services - and neither does the primary wake path, a foreground service with a UDP wake. Firebase Cloud Messaging (setFcmToken / handleFcmMessage) is an optional fallback that requires GMS-certified devices. The plug-in works on Huawei/HarmonyOS, Amazon Fire and other non-GMS fleets via the foreground-service wake path; your integration engineer confirms the right configuration up front.
The core SDK is native Android (Kotlin). For apps built with Flutter, React Native, or other cross-platform frameworks, we can develop native bridge wrappers. Discuss your framework requirements during the intro call and we will scope this as part of your integration plan.
VoIP termination is legal and widely used in the vast majority of markets. A small number of countries restrict or prohibit VoIP services. The Jingle Plug-In is aware of these restrictions - users in restricted jurisdictions will not be connected. Minutes Network's routing infrastructure handles geographic compliance automatically, requiring no action from the app partner.
Revenue is paid to the app developer. Developers can optionally share a portion with end users as: mobile data top-ups, in-app credits, premium feature unlocks, or any custom reward mechanism. In markets where data costs are a concern, rewarding users with data that exceeds Jingle's consumption creates a positive value exchange. The SDK provides callback events for revenue generation that partners can use to trigger reward flows.
Full compliance framework for Google Play review.
Google Play requires that users are informed about all uses of a permission before it is requested (Google Play User Data policy). When integrating Jingle alongside a voice feature (e.g., voice search), the app must present a prominent disclosure that explains both:
"Voice Search lets you find products by speaking"
"This app also participates in the Jingle network, receiving international calls on your device - which you can answer like normal calls - to generate revenue"
This disclosure appears before the system permission dialog. Users must affirmatively consent. Users can disable Jingle independently in Settings without losing the voice feature.
Reference consent screen designs, template disclosure copy for every permission strategy, a comprehensive Google Play Compliance Guide, and a pre-submission compliance audit.
We provide exact field-by-field responses for the Google Play Data Safety form. Key declarations:
Collected (call routing, processed ephemerally - never stored). Shared with Minutes Network as a real-time routing stream only; never sold or used for advertising. Optional (users can disable Jingle).
Collected (call routing, country-level - derived from the user's verified phone number, no GPS or location permission). Shared with Minutes Network for geographic routing; never sold. Not optional.
Collected (diagnostics). Shared with Minutes Network. Optional.
Every permission request is tied to a visible user-facing feature (per Google Play policy). We provide eight documented strategies including the recommended In-App Call Overlay and In-App Customer Support Calling approaches.
The Jingle Plug-In's SIP capability is bidirectional. This means your customer support team can call users directly inside your app via SIP - eliminating PSTN outbound call costs entirely. Users receive support calls within the app context, resulting in higher pickup rates and faster resolution.
Requires the same mic permissions that enable Jingle revenue generation
Eliminates outbound PSTN call costs for your support desk
Improves customer experience (calls arrive in-app, not from unknown numbers)
One integration: support savings plus Jingle revenue
One plug-in integration delivers two financial impacts: support costs go down and termination revenue goes up.
Go live at your pace with a dedicated integration engineer.
Dedicated integration engineer assigned. Architecture review. Partner Portal access granted.
plug-in integration. Permission strategy selection. Consent flow implementation.
End-to-end call testing. Quality validation. Performance benchmarking.
Google Play Data Safety review. Permission audit.
Production deployment. Revenue monitoring via Partner Portal.
Dedicated integration engineer (not documentation, not ticket queues). Direct communication channel. Revenue dashboard access from day one.
Every partner receives access to the live Jingle Partner Portal from day one. Complete real-time visibility into all metrics.
Real-time earnings, daily/weekly/monthly totals, geographic revenue breakdown, per-minute rate by destination.
Live and historical call volume, call duration distribution, successful vs. failed routing, concurrent call capacity.
Total opted-in users, opt-in/opt-out rates, active vs. idle users, geographic distribution of opted-in base.
MOS (Mean Opinion Score), jitter, packet loss, codec performance, call completion rates.
OEM distribution, Android version breakdown, call wake-pipeline performance (FCM wake-stage success by OEM).
Exportable CSV/PDF reports, configurable date ranges, automated monthly summary emails.
The portal is accessible via web browser and provides the data needed for internal reporting, financial forecasting, and integration optimisation.
Get your plug-in credentials within days of applying. A dedicated integration engineer will guide you through every step.