Skip to main content

Embedding CloudTalk Phone in a Web Application

Embed the CloudTalk Phone via iframe and handle events like ringing and hangup.

V
Written by Valeriia Volobrinskaia
Updated over a week ago

This guide explains how to embed the CloudTalk Phone interface into your own web application using an iframe.

User level:

  • Admin


Install the iFrame

Initialization

To embed and initialize CloudTalk Phone:

  • Use an iframe with the following source format:
    https://phone.cloudtalk.io?partner=yourappname

  • Replace yourappname with your system’s identifier in the partner query parameter.

Example:

<iframe src="https://phone.cloudtalk.io?partner=mycrm" allow="microphone *" height="700px" width="420px"></iframe>

Requirements

  • Minimum dimensions: 700px height × 420px width

  • The CloudTalk Phone must be embedded in a Single Page Application (SPA). It should not be reloaded when navigating between views within your app.

Notifications are not supported in the embedded version. In some cases, users may see a warning like "Notifications are not enabled" - this is a known visual issue and does not impact functionality.

Listening to Events

You can register for CloudTalk Phone events using window.onmessage. This allows your system to respond to events such as incoming calls or call hangups (e.g., by showing a contact detail panel or bringing the phone into focus).

The embedded CloudTalk Phone communicates with the parent application using window.postMessage. You can listen using window.onmessage or window.addEventListener("message", ...).

Supported Events

  • ringing – triggered when an incoming call notification appears (call starts ringing in the embedded phone)

  • dialing – triggered when a user initiates an outbound call (clicks dial)

  • calling – triggered when the call is answered (the other party picks up)

  • hangup – triggered when the user clicks the red end-call button (user action)

  • ended – triggered when the call session is fully terminated

  • contact_info – triggered when contact data related to the call is available or updated

Important Event Behavior

If a user manually ends a call:

  • hangup fires first (user action)

  • ended fires afterward (session teardown)

However, ended can also fire without a preceding hangup (for example, when the call is rejected, fails, or ends due to an error).

Recommended usage:

  • Listen to hangup if you need to react specifically to a user manually ending a call.

  • Listen to ended if you need to detect that the call is fully completed, regardless of how it ended.

You might want to maximize a minimized phone window when there's an incoming call, or automatically open the caller's contact detail page in your system.

Example:

window.addEventListener("message", function (e) {
try {
const eventData = JSON.parse(e.data);
console.log(eventData);

switch (eventData.event) {
case "ringing":
console.log("Incoming call from:", eventData.properties.external_number);
break;

case "dialing":
console.log("Outbound call started");
break;

case "calling":
console.log("Call answered");
break;

case "hangup":
console.log("User ended the call");
break;

case "ended":
console.log("Call fully terminated");
break;

case "contact_info":
console.log("Contact data received:", eventData.properties.contact);
break;
}
} catch (error) {
console.error("Invalid event data:", error);
}
});

Sample Payload

{
"event": "ringing",
"properties": {
"call_uuid": "12345678-1234-1234-123a-012345a6789b",
"external_number": "+44 20 3868 0167",
"internal_number": "+1 888 487 1675",
"contact": {
"id": 1234,
"name": "John Doe",
"company": "Company Inc.",
"contact_emails": [
"[email protected]",
"[email protected]"
],
"contact_numbers": [
"+44 20 3868 0167",
"+44123123123"
],
"external_urls": [
{
"external_system": "mycrm",
"external_url": "https://mycrm.io/contact/123"
}
],
"tags": ["VIP", "Europe"]
}
}
}

All events follow this same structure: event + properties containing call_uuid, external_number, internal_number, and contact (if available).


If you need further assistance or have any questions, you can contact our Support team. We are always here to help you!

Did this answer your question?