1. Call screening
CallerAPI Documentation
  • Quickstart
  • Use cases
    • For carriers (MNOs/MVNOs)
    • CPaaS platforms
    • Cloud communications providers
    • SIP trunking providers
    • PBX/Cloud PBX
    • UCaaS vendors
  • Account
    • Balance and email
      GET
  • Spam protection
    • Daily spam reports
      • Webhook
        • Subscribe to daily reports
        • Unsubscribe from daily reports
        • List webhook subscriptions
        • Manual dispatch of reports
        • Test webhook
      • REST
        • Fetch daily spam reports
    • Spam score + HLR
      GET
    • 15 days spam CSV snapshot
      GET
  • Mobile SDK
    • Get started
    • Quickstart
      • What you get
      • Get your keys
      • Android
      • iOS
      • Flutter
      • React Native
      • Check it works
    • Call screening
      • What each platform can do
      • Android
      • iOS prerequisites
      • iOS add the extension
      • iOS test on device
  • Data partners
    • Partner tems & docs
    • Upload spam reports
      POST
    • Upload contacts
      POST
  • Fraud prevention
    • Ported date
      GET
    • Porting history
      GET
    • Online presence
      GET
    • KYC user identity
      POST
  • Schemas
    • Spam protection
      • Spam score request
      • Business info
      • Carrier info
      • Complaint (without number)
      • Daily spam reports request
      • Complaint (with phone)
  1. Call screening

Android

Android: block and name calls#

About 30 minutes. You write one permission prompt. The SDK does the rest.

Before you start#

Finish the Android quickstart first, and confirm a lookup returns a name. Everything here depends on working credentials.
Automatic blocking needs Android 10 or later. Your app can still target minSdk 24, because the SDK turns the feature off by itself on older versions.

What you get#

Two features, and each needs its own permission from the user.
FeaturePermission the user grantsWhere the user grants it
Reject known spam callsCaller ID and spam app roleA system dialog you trigger
Show a name over the call screenDisplay over other appsA Settings screen you open
The two are independent. Ask for one, the other, or both.

What you do not have to write#

The SDK already ships the call screening service and its manifest entry. Gradle merges them into your app when you add the dependency. Do not declare a CallScreeningService of your own, and do not add android.permission.BIND_SCREENING_SERVICE. Both are present already.
Android allows one screening app at a time, so your app cannot combine with another one.

Step 1: ask for the role#

Add this to your main activity. It asks for both permissions, and it skips any the user already granted.
Android shows this dialog when you launch the role intent:
Default-Caller-ID-and-Spam-App.png.webp
Do not ask on your first screen. A user who has not seen your app yet says no. Ask after you have explained the feature. A denied role cannot be asked for again on some Android versions, so the user has to go to Settings themselves.

Step 2: turn on block reporting#

The dashboard counts blocked calls only after the user agrees to share that count:
Call it after your own consent screen. Blocking works without it. Only the count is affected.

Step 3: test it#

You need a real phone. An emulator cannot receive a real call.
1.
Install your app on the phone.
2.
Grant both permissions.
3.
Look up a spam number in your app first, so the answer is cached. Ask us for a current test number.
4.
Have that number call the phone.
A cached spam number is rejected before it rings. A number with a name shows a card over the call screen.
[screenshot of an incoming call with the CallerAPI name card shown over the system call screen]

How the SDK decides, and why the first call always rings#

Android gives a screening app a very short time to answer, and no network is safe in that window. The SDK therefore answers only from its cache.
The number is cached as spam, so the SDK rejects the call.
The number is cached as clean, so the call rings.
The number is not cached, so the call rings, and the SDK fetches the answer in the background for next time.
The last case is deliberate. Blocking a real call because a lookup was slow is worse than letting one spam call ring.
Call CallerAPI.prewarmAsync(number) when you already know a number is about to call, for example from your own recent calls list. That fills the cache in advance.

Turning the name card off#

Some apps want blocking without the floating card:

Things that will confuse you#

Nothing happens on any call. The role is not held. This is the most common problem, and it is silent, because Android never asks your app. Check with:
Calls get blocked but no name appears. The overlay permission is missing. Check CallerAPI.canShowIncomingCallerIdOverlay(this).
The role dialog never appears. Either the user already granted it, or another app holds it, or the device runs Android 9 or older.
The first spam call always rings. That is by design. See the section above.
Blocking works, and the dashboard shows zero blocks. You did not call setAnalyticsConsent(true).

Next#

iOS call screening
All methods
Troubleshooting
Modified at 2026-07-29 21:22:02
Previous
What each platform can do
Next
iOS prerequisites
Built with