CreateBlogSupport
Log inSign up
Home
Webex Calling
  • Guides
  • Webex Calling Beta
  • Webex Cloud Calling
  • Broadworks Calling
  • UCM Calling
  • AI Assistant for Developers
  • Beta Program
  • Webex Status API

Webex Calling

Incoming Calls

This article describes how to handle incoming Webex Calling based calls.

The Webex calling system integrates incoming call handling via webhooks within the SDK environment. Developers register a webhook by specifying a URL for their server backend to receive notifications. These notifications are typically relayed to mobile apps through APNS (Apple Push Notification Service) or FCM (Firebase Cloud Messaging). This setup enables the app to manage incoming calls regardless of its state—whether in the foreground, background, or even when terminated.

The diagram illustrates how incoming call notifications are delivered.

Incoming call notification flow.

anchorWebhook Configuration for Incoming Calls

anchor

To configure a webhook for incoming calls:

  1. An organization administrator creates a firehose webhook, which listens for telephony_push events and notifies a specified server URL when such events occur:

    {
        "name": "Webex Calling XYZ Firehose",
        "targetUrl": "https://example.com/message-events", // Server url of backend server that can receive the webhook notification
        "resource": "telephony_push",
        "event": "updated"
    }
    
  2. Upon successful login, the mobile app sends the user's Person ID and push token (APNS or FCM) to the backend server, where they are stored. The Person ID identifies the Webex user when the backend receives a webhook notification, and the push token is used for sending notifications to the user's device:

    webex.people.getMe() { result ->
        val person = result.data
        person?.let {
            // Person id
            val personId = it.encodedId
        }
    }
    

    Instructions for setting up Firebase Cloud Messaging for Android apps can be found here.

  3. Upon receiving a webhook notification containing a JSON payload that signals an incoming call, the backend server identifies the user through the "actorId" field. It then sends the corresponding payload—apnsPayload for iOS and fcmPayload for Android—to the user's device, ensuring the content remains unaltered.

  4. When the mobile app receives the FCM or APNS payload, it should pass it to the SDK method processPushMessageInternal() for further processing.

anchorProcessing the Incoming Call Payload

anchor

Here's how an app processes the incoming call notification:

  1. Receive the Notification Payload: The notification payload is received by the FirebaseMessagingService class's onMessageReceived method. The app checks if the Webex SDK is initialized and authorized and sets an incoming call listener before processing the message:

        val authorized = webex.authenticator?.isAuthorized()
        if (authorized == true) { // SDK is initialized and authorized.
            processPushMessageInternal(fcmDataPayload) {
                if (it.isSuccessful && it.data == PushNotificationResult.NoError) {
                    // Successfully sent the payload to the SDK.
                }
            }
        } else { // SDK is not initialized. Application might have killed.
            webex.initialize {
                if (webex.authenticator?.isAuthorized() == true) {
                    processPushMessageInternal(fcmDataPayload) {
                        if (it.isSuccessful && it.data == PushNotificationResult.NoError) {
                            // Successfully sent the payload to the SDK.
                        }
                    }
                }
            }
        }
    
  2. Set Incoming Call Listener and Process the Message: The app sets an incoming call listener and processes the push notification message using the webex.phone.processPushNotification() method:

        private fun processPushMessageInternal(msg :String, handler: CompletionHandler<PushNotificationResult>) {
            // SDK Methods
            if(!notRegistered){
                webex.phone.setIncomingCallListener(object : Phone.IncomingCallListener {
                    override fun onIncomingCall(call: Call?) {
                        // Using this call object, the call can be answered.
                    }
                })
            }
    
            // SDK method to process the push message.
            webex.phone.processPushNotification(msg) {
                if (it.isSuccessful) {
                    // Successfully sent the payload to the SDK.
                    if (it.data == PushNotificationResult.NoError) {
                        handler.onComplete(ResultImpl.success(PushNotificationResult.NoError))
                    }
                    else {
                        // Handle the error. 
                    }
                }
            }
        }
    

    The application receives an incoming Call object in the observer Phone.IncomingCallListener which is initialized using webex.phone.setIncomingCallListener.

  3. Answering or Rejecting a Call: The app can answer the call using the answer() method or reject it using the reject() method:

    call?.answer(MediaOption.audioOnly(), CompletionHandler {
        if (it.isSuccessful){
            // Call answered successfully.
        } else {
            // Call answer failed.
        }
    })
    
    call?.reject { result ->
        if (result.isSuccessful) {
            // Call rejected successfully.
        } else {
            // Call reject failed. 
        }
    }
    

anchorCall Observer Events

anchor

telephony_push events from webhooks indicate NewCall type notifications, signifying a new incoming call for a particular user.

The app can monitor the following key call state changes:

call?.setObserver(object : CallObserver {
    override fun onConnected(call: Call?) {
        // Indicates call is successfully established.
    }

    override fun onDisconnected(event: CallObserver.CallDisconnectedEvent?) {
        // Indicates call is disconnected.
    }

    override fun onRinging(call: Call?) {
        // Indicates call is placed and is in ringing state.
    }

    override fun onInfoChanged(call: Call?) {
        // Indicates call info is updated.
        // call.getExternalTrackingId() can be used to retrieve the tracking ID.
    }
})
Key Observer Events

Key events include:

  1. onRinging : The call is placed, and the remote participant's device is ringing.
  2. onConnected : The call is successfully established.
  3. onDisconnected : The call is disconnected; this event is also triggered when the call is answered on another device.
  4. onInfoChanged : Call details in the Call object are updated.

anchorIncoming Call Sequence Diagram

anchor

Incoming call flow.

anchorHande Multiple Incoming Calls

anchor

Here's a typical scenario for managing two incoming calls:

  1. Receive the first incoming call notification.
  2. Display the notification to the user.
  3. If the user accepts, the first call is active.
  4. When a second incoming call notification arrives, display it to the user.
  5. If the user accepts the new call:
    • The active call is put on hold.
    • The new call is answered.
  6. The user can switch between calls by toggling hold/resume states.
  7. Calls can be ended using their respective call object.
  8. CallObserver notifications should be handled to update the UI accordingly.
  9. If the user rejects the new call, the active call remains uninterrupted.
In This Article
  • Webhook Configuration for Incoming Calls
  • Processing the Incoming Call Payload
  • Call Observer Events
  • Incoming Call Sequence Diagram
  • Hande Multiple Incoming Calls

Connect

Support

Developer Community

Developer Events

Contact Sales

Handy Links

Webex Ambassadors

Webex App Hub

Resources

Open Source Bot Starter Kits

Download Webex

DevNet Learning Labs

Terms of Service

Privacy Policy

Cookie Policy

Trademarks

© 2025 Cisco and/or its affiliates. All rights reserved.