On this page · 10 sections
Summary. In its July 15, 2026 policy announcement, Google Play said its SMS and Call Log Permissions policy will no longer allow account verification by phone call as a use case for the READ_CALL_LOG permission. Developers get at least 30 days to comply. That ends the flash-call and missed-call login pattern that reads the call log to confirm a code, a pattern that spread in India partly because transactional OTP SMS costs roughly ₹0.10 to ₹0.18 per message on DLT routes. Google names two replacements: the Digital Credentials API, which verifies a number silently through a carrier-issued TS.43 token, and the SMS Retriever API, which auto-reads a one-time code without any SMS permission. Both need Google Play services, neither needs READ_CALL_LOG or READ_SMS. This guide covers who is affected, both APIs with code, and how to choose.
What Google actually banned
The change is narrow but real. Under the SMS and Call Log Permissions policy, "account verification via phone call" is no longer an accepted reason to request READ_CALL_LOG. Apps that place or trigger a call and then read the device call log to confirm the verification code can no longer do that on Google Play. The compliance window is at least 30 days from July 15, 2026.
This is separate from Google Play's yearly target API level requirement, which is due by August 31, 2026, and from the wider July 2026 Play policy pack on user data. They are close enough in time that most teams should plan a single release that bumps the target SDK, removes the call-log permission, and swaps in a supported verification path.
| Verification pattern | Status after the policy | Recommended fix |
|---|---|---|
| Flash-call or missed-call that reads the call log | Not allowed for verification | Digital Credentials API or SMS Retriever |
| SMS one-time code read via READ_SMS | Discouraged permission | SMS Retriever API |
| Manual one-time code entry | Allowed | Optionally add SMS Retriever for UX |
| Silent carrier verification | Allowed | Digital Credentials API |
Who is affected
If your Android app verifies a phone number by watching the call log, you are in scope. That covers flash-call verification, where a short call is placed and the app matches the caller number from the log, and missed-call verification built the same way. These flows are common across Indian consumer and fintech apps because they avoid the per-message SMS cost and the DLT template friction that Indian A2P routes carry. Apps that auto-read SMS codes with READ_SMS are not directly named in this change, but they should move to the SMS Retriever API anyway, since it needs no SMS permission and Google steers apps away from READ_SMS.
Option A: SMS Retriever API
The SMS Retriever API keeps your existing one-time code over SMS but removes the permission. It reads exactly one matching message for up to five minutes, without READ_SMS or RECEIVE_SMS. Your minSdkVersion must be 19 or higher and compileSdkVersion 28 or higher.
Add the Google Play services dependencies:
dependencies {
implementation 'com.google.android.gms:play-services-auth:21.6.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:18.3.1'
}
Start the retriever when you are ready to verify, then send the number to your server so it can deliver the SMS:
val client = SmsRetriever.getClient(context)
val task = client.startSmsRetriever() // listens for one message, up to 5 minutes
task.addOnSuccessListener { /* expect the broadcast next */ }
task.addOnFailureListener { e -> /* inspect and retry */ }
Receive the message through a BroadcastReceiver filtered on the SMS Retriever action, pull the code out, and verify it on your server:
class SmsBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) {
val extras = intent.extras ?: return
val status = extras.get(SmsRetriever.EXTRA_STATUS) as Status
if (status.statusCode == CommonStatusCodes.SUCCESS) {
val message = extras.getString(SmsRetriever.EXTRA_SMS_MESSAGE)
// extract the one-time code, then POST it to your server to confirm
}
}
}
}
Register the receiver with the intent action com.google.android.gms.auth.api.phone.SMS_RETRIEVED and the com.google.android.gms.auth.api.phone.permission.SEND permission on the receiver, so only Play services can trigger it. Google's guidance is firm on one point: verify the one-time code on your server, not in the client.
Option B: Digital Credentials API
The Digital Credentials API for phone number verification removes the SMS entirely. It requests a carrier-issued TS.43 token, then your backend exchanges that token with an aggregator for the verified number. It runs on Android 10 (API level 29) and higher, and it needs an aggregator account, which is usually a billable cloud API endpoint; Firebase Phone Number Verification is one such option noted in Google's docs.
Add the Credential Manager dependencies:
dependencies {
implementation "androidx.credentials:credentials:1.7.0-alpha02"
implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha02"
}
Your backend requests Digital Credential Query Language (DCQL) parameters from the aggregator with a nonce and request ID, then builds an OpenID4VP request. The client passes that request to the Credential Manager API:
val requestJson = generateTs43RequestFromServer() // OpenID4VP, protocol openid4vp-v1-unsigned
val option = GetDigitalCredentialOption(requestJson = requestJson)
val response = credentialManager.getCredential(
context = activityContext,
request = GetCredentialRequest(listOf(option))
)
(response.credential as? DigitalCredential)?.let { cred ->
validateOnServer(cred.credentialJson) // send TS.43 credential to your backend
}
The returned TS.43 Digital Credential is encrypted for the aggregator. Your backend validates the OpenID4VP response as an SD-JWT verifiable credential, checks the nonce matches, then calls the aggregator to receive the verified phone number. A cancelled prompt or an unsupported SIM surfaces a GetCredentialException, so handle that path with an SMS fallback.
Which one should you choose?
For most teams the honest trade is change size against long-term cost. SMS Retriever is a small edit to an existing flow. Digital Credentials is a larger backend project that removes SMS spend and is harder to intercept, because a carrier confirms the number directly rather than sending a code that can be forwarded or read off another device.
| Factor | SMS Retriever API | Digital Credentials API (TS.43) |
|---|---|---|
| Change size | Small; keep your SMS codes | Larger; new backend and an aggregator |
| User experience | Auto-reads the code in seconds | Silent, no code shown |
| Ongoing cost | Per-SMS, about ₹0.10 to ₹0.18 in India | Aggregator API fees, no SMS |
| Coverage | Any device that receives SMS | Android 10 or higher with carrier support |
| Permissions | None; no READ_SMS | None; no READ_SMS |
| Interception risk | Higher; depends on SMS delivery | Lower; carrier-confirmed |
A practical path for a consumer app: ship SMS Retriever first to clear the deadline, keep it as the fallback, and add Digital Credentials verification for the carriers and devices that support it. The phone number hint API can pre-fill the number in both flows so users never type it.
Migration checklist and testing
Remove READ_CALL_LOG (and READ_SMS if present) from the manifest and audit any SDK that pulls them in transitively. Wire in the new flow behind a feature flag, then test on real devices across at least two carriers, because carrier support drives the Digital Credentials path. Confirm the five-minute SMS Retriever window and your code-extraction regex against your live message template. Update the Play Data safety form to drop the removed permissions, and register the release in Play Console alongside the developer verification checklist. Keep an SMS or manual-entry fallback so users on unsupported devices can still sign in.
India-specific considerations
India is where this bites hardest. Phone-number login is the default rather than the exception, and transactional OTP SMS runs about ₹0.10 to ₹0.18 per message on compliant DLT routes, with TRAI requiring DLT registration and pre-registered templates for every sender. Those costs and that friction are why flash-call and missed-call verification spread here in the first place. Dropping call-log access also lines up with the DPDP Act's data-minimisation principle, so the migration improves privacy posture, not just Play compliance. For regulated apps, keep the change consistent with the RBI's digital payment authentication directions, which treat the verified phone number as one factor in a login, not the whole of it. This lands in the same month as Google's separate move to open the Play catalog to third-party US app stores, so 2026 is a heavy year for Android distribution and identity changes at once.
FAQ
How eCorpIT can help
eCorpIT is a Gurugram-based, senior-led engineering organisation that ships and maintains Android apps for consumer and fintech teams in India and abroad. We can audit where your login flow depends on READ_CALL_LOG or READ_SMS, migrate it to the SMS Retriever or Digital Credentials API behind a feature flag, and keep it aligned with Google Play's 2026 policy and the DPDP Act. If you want a verification migration handled before the deadline, talk to us or see our fintech app development service.
References
_Last updated: July 26, 2026._