All methods#
Every public function, per platform. Version 1.4.0.The two you need#
Everything else is optional. These two are the product.| Platform | Get a name | Check for spam |
|---|
| Android | CallerAPI.lookupLabel(phone) | CallerAPI.isSpam(phone) |
| iOS | try await CallerAPI.lookupLabel(phone) | try await CallerAPI.isSpam(phone) |
| Flutter | await CallerAPI.lookupLabel(phone) | await CallerAPI.isSpam(phone) |
| React Native | await CallerAPI.lookupLabel(phone) | await CallerAPI.isSpam(phone) |
Send every phone number in E.164 format, for example +18883578668.Android#
Import com.callerapi.sdk.CallerAPI.Starting up#
| Method | Returns | Notes |
|---|
register(context, featureEnabled = true, config = CallerAPIConfig()) | Unit | Call once in Application.onCreate. Safe to call twice. |
cleanup() | Unit | Shuts the native core down. Rarely needed. |
register resolves each credential in this order: the value in config, then the manifest meta-data entry, then any value compiled into the native library.Looking up#
| Method | Returns | Blocking? |
|---|
suspend lookupLabel(phone) | String? | No, runs on the IO dispatcher |
suspend lookupLabelOrNull(phone) | String? | No. Same as lookupLabel |
suspend lookupLabelCode(phone) | Int | No. 0 means success |
isSpam(phone) | Boolean | Yes. Never call on the main thread |
spamCheckCode(phone) | Int | Yes. 1 spam, 0 clean, negative is an error |
cachedSpamVerdict(phone) | SpamVerdict | No. Reads the cache only, never the network |
prewarmAsync(phone) | Unit | No. Returns at once, fetches in the background |
lookupLabel returns null both for "not a business" and for a failed lookup. Use lookupLabelCode when you need to tell those apart.SpamVerdict is SPAM, CLEAN, or UNKNOWN. UNKNOWN means the cache has no answer, so treat the call as clean.Use cachedSpamVerdict and prewarmAsync on the call path. They are the only two that never block.Permissions and settings#
| Method | Returns | Notes |
|---|
canShowIncomingCallerIdOverlay(context) | Boolean | Whether the user granted the overlay permission |
setIncomingCallerIdOverlayEnabled(enabled) | Unit | Turns the name card off. Default is on |
setFeatureEnabled(enabled) | Unit | Reported for billing. Only enabled devices are billable |
setAnalyticsConsent(consented) | Unit | Blocked call counts are reported only after this |
suspend checkIn() | Boolean | Reports usage now, instead of waiting for the schedule |
Types#
CallerAPIVersion.VALUE holds the SDK version as a string.Manifest keys#
| Key | Required for |
|---|
com.callerapi.sdk.SDK_KEY | Lookups |
com.callerapi.sdk.SDK_SECRET | Lookups |
com.callerapi.sdk.CLIENT_KEY | Device counting and billing |
com.callerapi.sdk.API_BASE | Nothing. Only to point at another endpoint |
iOS: CallerAPI#
Needs iOS 13.0 or later. import CallerAPI.| Method | Returns | Notes |
|---|
configure(_ config: CallerAPIConfig, featureEnabled: Bool = true) | Void | Supplies credentials. Call once at launch |
configure(featureEnabled: Bool = true) | Void | Only for a build with credentials compiled in |
isSpam(_ phone: String) async throws | Bool | |
lookupLabel(_ phone: String) async throws | String? | nil means not a business |
checkIn() async | Bool | Reports usage now |
If you never call configure, the SDK reads CallerAPISDKKey and CallerAPISDKSecret from your Info.plist on the first lookup. That is how the Flutter and React Native bridges get their credentials.A thrown error is a CallerAPIError with an Int32 code. See Errors.Call Directory, for iOS 13 to 17#
CallerAPI.CallDirectory, for blocking from a list downloaded in advance.| Method | Returns | Called from |
|---|
configure(_ config: Config) | Void | Your app and the extension |
sync() async throws | Void | Your app. Downloads the list |
scheduleDeferredSync(after: TimeInterval) | Void | Your app. Avoids syncing on a cold launch |
hasBlocklistBlob() throws | Bool | The extension, before load |
load(into: CXCallDirectoryExtensionContext) throws | Void | The extension |
Always check hasBlocklistBlob before load. Until your app has synced once there is no list, and reporting that as an error makes iOS stop asking your extension.Background refresh#
CallerAPI.BackgroundSync.register() registers the background task. Its identifier is CallerAPI.BackgroundSync.taskIdentifier, which is com.callerapi.checkin. Add that string to BGTaskSchedulerPermittedIdentifiers in your Info.plist.iOS: CallerAPILiveCallerID#
Needs iOS 18.0 or later. import CallerAPILiveCallerID.In your app#
| Method | Returns | Notes |
|---|
bootstrap(_ options: BootstrapOptions) | Void | Call once at launch. Does everything below |
isDisabled(forExtensionWithIdentifier:) | Bool | Whether the user switched your extension off |
openSettings() async throws | Void | Opens the Settings screen with the toggle |
prewarmIfEnabled(extensionIdentifier:reason:) async | Bool | Refreshes keys before a call arrives |
refreshPIRParameters(forExtensionWithIdentifier:) async throws | Void | Lower level than prewarmIfEnabled |
configureMetering(clientKey:extensionIdentifier:endpoint:) | Void | Included in bootstrap |
sendHeartbeat() async throws | HeartbeatResult | Included in bootstrap |
sdkVersion | String | |
Prefer bootstrap. It reports usage, registers the background refresh, and refreshes the extension at launch and on every return to the foreground.In your extension#
makeExtensionContext() returns the object iOS asks for. It is the only call your extension needs.Advanced#
| Method | Use when |
|---|
appGroupIdentifier | You give different users different data tiers |
setUserTierToken(_ token: Data) | Same. Needs an App Group on both targets |
setEndpoints(serviceURL:tokenIssuerURL:) | You point at staging, or at hosts reserved for you |
effectiveConfiguration | You want to read back what the SDK will use |
resetSharedOverrides() | You undo the two setters above |
manager | You need Apple's LiveCallerIDLookupManager directly |
Flutter#
import 'package:callerapi/callerapi.dart'; then call statics on CallerAPI.| Method | Returns | Platform |
|---|
lookupLabel(String phone) | Future<String?> | Both |
isSpam(String phone) | Future<bool> | Both |
checkIn() | Future<bool> | Both |
setFeatureEnabled(bool enabled) | Future<void> | Both |
setAnalyticsConsent(bool consented) | Future<void> | Android. Does nothing on iOS |
requestCallScreeningRole() | Future<bool> | Android |
isCallScreeningRoleGranted() | Future<bool> | Android |
requestOverlayPermission() | Future<bool> | Android |
isOverlayPermissionGranted() | Future<bool> | Android |
bootstrapFromInfoPlist() | Future<bool> | iOS |
bootstrap(CallerAPIBootstrapOptions options) | Future<bool> | iOS |
getLiveLookupStatus() | Future<LiveLookupStatus> | iOS |
openLiveLookupSettings() | Future<bool> | iOS |
prewarmLiveLookup() | Future<bool> | iOS |
syncCallDirectory() | Future<bool> | iOS |
A method for the other platform returns false, so you do not need a platform check.There is no initialize. The plugin starts the SDK and reads your credentials from the Android manifest and the iOS Info.plist.React Native#
import CallerAPI from '@callerapi/react-native';. A default import, not a named one.The method names match Flutter exactly. Two differences:| Method | Flutter | React Native |
|---|
setFeatureEnabled | Future<void> | void. Do not await it |
setAnalyticsConsent | Future<void> | void. Do not await it |
export type LiveLookupStatus = {
enabled: boolean;
extensionId?: string;
serviceURL?: string;
tokenIssuerURL?: string;
error?: string;
};
export type CallerAPIBootstrapOptions = {
liveLookupExtensionId: string;
lcidClientKey: string;
lcidHeartbeatTaskId?: string;
appGroup?: string;
callDirectoryExtensionId?: string;
keychainAccessGroup?: string;
deferCallDirectorySyncSeconds?: number;
};
Importing the package throws at once if the native module is not linked. Run pod install and rebuild.What the wrappers do not expose#
Flutter and React Native cover lookups, permissions, and iOS extension housekeeping. These native functions have no wrapper method. Write a platform channel or a native module if you need one.| Native function | Platform |
|---|
cachedSpamVerdict, prewarmAsync | Android |
spamCheckCode, lookupLabelCode | Android |
setIncomingCallerIdOverlayEnabled | Android |
CallerAPIConfig timeouts | Android and iOS |
setUserTierToken, setEndpoints | iOS |
Typed CallerAPIError codes | iOS |
Modified at 2026-07-29 23:17:55