# Zoom Phone Smart Embed guide
Zoom Phone Smart Embed is a fast and flexible solution that enables developers to quickly embed a softphone for Zoom Phone Services in their third-party Web application.
- Developers can embed this app with a code snippet in third-party web applications.
- Administrators can allow third-party applications to use the app when they install it and configure approved domains.
- End users can sign in to the Zoom Phone Smart Embed in their third-party app with their Zoom credentials.
Zoom Phone Smart Embed offers these features for users:
- Sign in or sign out option in the softphone layout for third-party app users.
- Click numbers in third-party web apps or enter them in the softphone.
- Third-party apps that receive calls.
- Call control to mute, record, or hang up the call in the softphone.
- Call history to access recordings and voicemails.
You can access the Zoom Phone Smart Embed app in the [Zoom App Marketplace](https://marketplace.zoom.us/apps/jnMbv3s2TaCBYMFz5yvzkA).
## Prepare your environment
Before you can use Zoom Phone Smart Embed, you must have:
- [Zoom Phone license](https://zoom.us/pricing/zoom-phone).
- [Zoom Phone configured](https://support.zoom.us/hc/en-us/articles/360001297663).
- Zoom client version 5.9.0 or higher.
- Automatic calling from third-party application.
- To use Zoom SMS, you must add [10DLC compliance for conversational messaging](https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0058283).
Administrators must be able to:
- Access Zoom to install or uninstall the Zoom Phone Smart Embed app.
- Enable automatic calling for their users from their third-party application.
To turn on this setting:
- Sign in to the Zoom web portal as an administrator with the privilege to edit account settings.
- In the navigation menu, select **Account Management**, then **Account Settings**.
- Choose the **Zoom Phone** tab.
- Enable the toggle for **Automatically Call From Third Party Apps**.
## Confirm platform support
We support these platforms:
- Browser-based apps
- Browser-based webapps: Edge, Chrome, Safari, Firefox
- SAAS CRM's with CTI frameworks
## Integrate Zoom Phone Smart Embed
In this section, we show you how to add Zoom Phone Smart Embed app in your web applications and widgets that control the Smart Embed, such as click-to-call, receive calls, notifications for inbound and outbound calls, auto call logging, and support for custom notes pages.
### Add a Zoom Phone Smart Embed app to a web application
Developers can add Zoom Phone Smart Embed with a code snippet in third-party web applications.
Choose one of the following to embed the Zoom Phone Smart Embed into your third-party app:
- Embed the app using an Iframe:
```html
```
**Note**: Minimum pixels : 350(width) \* 580(height)
- Embed the app using a script
```html
```
The app floats on your page, and you can drag or minimize it.
**Note**: To embed the Zoom Phone Smart Embed app in a chrome-extension, pass your domain through the `originDomain` parameter. Then inform the admin to add this domain to the approved domain list.
### Examples
iframe:
```html
```
script:
```html
```
## Use API and events to control the Smart Embed
Zoom Phone Smart Embed provides APIs and events that enable developers to features such as:
- Widget initialization
- Click-to-call
- Receive a call
- Inbound and outbound call notifications
- Auto call logging
- Support to add a custom notes page to a softphone
## APIs
- [Initialize the widget](#initialize-the-widget)
- `onZoomPhoneIframeApiReady` – Triggers when the Zoom Phone iframe finishes loading.
- `zp-init-config` – Use this `postMessage` type to initialize the widget with configuration options.
- [Make a call from a third-party app](#make-a-call-from-a-third-party-app)
- `zp-make-call` – Use this `postMessage` type to make a call from a third-party app.
- [Send an SMS from a third-party app](#send-an-sms-from-a-third-party-app)
- `zp-input-sms` – Use this `postMessage` type to send an SMS from a third-party app.
- [Receive events from the Smart Embed](#receive-events-from-the-smart-embed)
- `zp-call-ringing-event` – Triggers when a call starts ringing.
### Initialize the widget
To initialize the widget, use these configurations.
```javascript
function onZoomPhoneIframeApiReady(a) {
document.querySelector('iframe#zoom-embeddable-phone-iframe').contentWindow.postMessage({
type: 'zp-init-config',
data: {
enableSavingLog: false,
enableAutoLog: false,
enableContactSearching: false,
enableContactMatching: false,
enableAISummary: true,
notePageConfiguration:
// Optional. Build your note page with the fields listed in "Add Notes" section
disableInactiveTabCallEvent: true
// Events will only be sent out in the last active tab
}
}, 'https://applications.zoom.us');
};
```
**Note**: `onZoomPhoneIframeApiReady` triggers when the iframe finishes loading. Call all widget APIs only after this function runs.
#### Make a call from a third-party app
You can use this API to enable the click-to-dial option from a third-party app.
```javascript
document.querySelector('iframe#zoom-embeddable-phone-iframe').contentWindow.postMessage({
type: 'zp-make-call',
data: {
number: ,
callerId: ,
autoDial:
}
}, 'https://applications.zoom.us');
```
#### Send an SMS from a third-party app
You can use this API to send SMS from a third-party app.
```javascript
document.querySelector('iframe#zoom-embeddable-phone-iframe').contentWindow.postMessage({
type: 'zp-input-sms',
data: {
number:
message:
}
}, 'https://applications.zoom.us');
```
#### Receive events from the Smart Embed
The Zoom Phone Smart Embed provides some events based on the postMessage API.
Use this code to receive events:
```javascript
window.addEventListener("message", (e) => {
const data = e.data;
if (data) {
switch (data.type) {
case "zp-call-ringing-event": // listen to all the event types that you need
console.log(data.data);
break;
}
}
});
```
## Events
**Call events**
- [`zp-call-ringing-event`](#zp-call-ringing-event) – Fires when a call starts to ring.
- [`zp-call-connected-event`](#zp-call-connected-event) – Fires when a call connects.
- [`zp-call-ended-event`](#zp-call-ended-event) – Fires when a call ends.
- [`zp-call-log-completed-event`](#zp-call-log-completed-event) – Fires when a call log is completed in Zoom.
- [`zp-call-recording-completed-event`](#zp-call-recording-completed-event) – Fires when a call recording completes.
- [`zp-call-voicemail-received-event`](#zp-call-voicemail-received-event) – Fires when the system receives a voicemail.
**AI event**
- [`zp-ai-call-summary-event`](#zp-ai-call-summary-event) – Fires when the AI-generated call summary is created, updated, or deleted.
**SMS event**
- [`zp-sms-log-event`](#zp-sms-log-event) – Fires when the system sends or receives an SMS.
**Call logging event**
- [`zp-save-log-event`](#zp-save-log-event) – Fires when a user manually saves a call log (Save Log button).
**Contact integration events**
- [`zp-contact-search-event`](#zp-contact-search-event) – Fires when a user searches for a contact by typing in the input area.
- [`zp-contact-match-event`](#zp-contact-match-event) – Fires when the system attempts to match contacts by phone number on Incoming, Outgoing, History, and Voicemail pages.
**Notes event**
- [`zp-notes-save-event`](#zp-notes-save-event) – Fires when a user saves notes in the note page.
### Call events
#### zp-call-ringing-event
This event fires when a call starts to ring. At this stage, there is only a call ID, which is not a unique id for a call log.
```json
{
"id": ,
"type": "zp-call-ringing-event",
"data": {
"callId": ,
"direction": "inbound" | "outbound",
"caller": {
"name": ,
"phoneNumber": ,
"extensionNumber": ,
"extensionId": ,
"extensionType":
},
"callee": {
"name": ,
"phoneNumber": ,
"extensionNumber": ,
"extensionId": ,
"extensionType":
},
"dateTime": ,
"forwardedBy": {
"name": ,
"extensionNumber": ,
"extensionType": //Enum: //"user" "callQueue" "autoReceptionist" "commonAreaPhone" "sharedLineGroup" //"zoomRoom" "ciscoRoom/PolycomRoom" "contactCenter"
}
}
}
```
#### zp-call-connected-event
This event fires when a call connects.
```json
{
"id": ,
"type": "zp-call-connected-event",
"data": {
"callId": ,
"direction": "inbound" | "outbound",
"caller": {
"name": ,
"phoneNumber": ,
"extensionNumber": ,
"extensionId": ,
"extensionType":
},
"callee": {
"name": ,
"phoneNumber": ,
"extensionNumber": ,
"extensionId": ,
"extensionType":
},
"dateTime": ,
"forwardedBy": {
"name": ,
"extensionNumber": ,
"extensionType":
}
}
}
```
#### zp-call-ended-event
This event fires when a call ends.
```json
{
"id":
"type": "zp-call-ended-event",
"data": {
"callId": ,
"direction": "inbound" | "outbound",
"caller": {
"name": ,
"phoneNumber": ,
"extensionNumber": ,
"extensionId": ,
"extensionType":
},
"callee": {
"name": ,
"phoneNumber": ,
"extensionNumber": ,
"extensionId": ,
"extensionType":
},
"dateTime": ,
"forwardedBy": {
"name": ,
"extensionNumber": ,
"extensionType":
},
"result": // Enum: "missed" | "rejected" | "ended"
}
}
```
#### zp-call-log-completed-event
This event fires when a call log completes in Zoom. `callLogId` is a unique ID for a call log.
```json
{
"id": ,
"type": "zp-call-log-completed-event",
"data": {
"callId": ,
"callLogId": ,
"caller": {
"name": ,
"number": ,
"numberType": // 1 — extension number. 2 — phone number. 3 — Customized emergency number.
},
"callee": {
"name": ,
"number": ,
"numberType": // 1 — extension number. 2 — phone number. 3 — Customized emergency number.
"result": ,
"direction": "inbound" | "outbound",
"duration": ,
"dateTime":
}
}
```
**Result**
- Answered by other member: Returns if you enable the simultaneous distribution option for a call queue, and if a member of the queue answers the call.
- Busy: Returns if the phone line of the callee is busy.
- Call Cancel: Returns if the call is canceled.
- No Answer: Returns if the callee did not answer the call.
- Park: Returns if the call is parked.
- Rejected: Returns if the callee declines the call.
- Blocked
- Voicemail
- Wrong Number
- International Disabled
- Internal Error
- Restricted Number
- Call Connected
#### zp-call-recording-completed-event
This event fires when the recording of a call completes.
```json
{
"id": ,
"type": "zp-call-recording-completed-event",
"data": {
"callId": ,
"callLogId": ,
"caller": {
"name": ,
"number": ,
"numberType": // 1 - internal 2 - external
},
"callee": {
"name": ,
"number": ,
"numberType": // 1 - internal 2 - external
},
"direction": "inbound" or "outbound",
"recordingUrl": ,
"dateTime":
}
}
```
#### zp-call-voicemail-received-event
This event fires when a call's voicemail arrives.
```json
{
"id": ,
"type": "zp-call-voicemail-received-event",
"data": {
"callId": ,
"callLogId": ,
"caller": {
"name": ,
"number": ,
"numberType": // 1 - internal 2 - external
},
"callee": {
"name": ,
"number": ,
"numberType": // 1 - internal 2 - external
},
"voicemailUrl": ,
"dateTime":
}
}
```
### AI events
#### zp-ai-call-summary-event
This event fires when the system generates, updates, or deletes a call's AI summary.
```json
{
"type": "zp-ai-call-summary-event",
"data": {
"callId": ,
"deleted": ,
"edited": ,
"callSummary": ,
"nextSteps": ,
"detailedSummary": ,
"modifiedTime":
}
}
```
### SMS event
#### zp-sms-log-event
This event fires when you send or receive an SMS message.
```json
{
"id": ,
"type": "zp-sms-log-event",
"data": {
"sessionId": ,
"messageId": ,
"dateTime": ,
"sender": {
"phoneNumber":
},
"receivers": [
{
"phoneNumber":
}
],
"message": ,
"attachments": [
{
"type": , // Enum: OTHER, PNG, GIF, JPG, AUDIO, VIDEO
"fileUrl": ,
}
],
"status": // Enum: Delivered/Not delivered/Received
"direction": "inbound" or "outbound"
}
}
```
### Log calls to a third-party app
### Enable the call logging service
Send a message to the Smart Embed to enable call logging.
- `enableSavingLog`: when this value is true, it displays the **Save Log** button on each call log item in the **History** tab.
- `enableAutoLog`: when this value is true, it displays the auto log calls setting in the **Settings** page.
### Save a call log
When the `enableSavingLog` is set to true, **zp-save-log-event** fires when the user chooses the **Save Log** on the **History** page.
#### zp-save-log-event
```json
{
"type": "zp-save-log-event",
"data": {
"callId": ,
"callLogId": ,
"caller": {
"name": ,
"number": ,
"numberType": // 1 — extension number. 2 — phone number.
},
"callee": {
"name": ,
"number": ,
"numberType": // 1 — extension number. 2 — phone number. 3 — Customized emergency number.
},
"result": ,
"direction": "inbound" or "outbound"
"duration": ,
"dateTime": ,
"recordingUrl": ,
"voicemailUrl": ,
"callSummary": ,
"nextSteps": ,
"detailedSummary":
}
}
```
### Enable automatic call logging
When the user enables auto logging in **Settings**, it adds the parameter `enableAutoLog: true` in all the following call events:
[`zp-call-ringing-event`](#zp-call-ringing-event),
[`zp-call-connected-event`](#zp-call-connected-event),
[`zp-call-ended-event`](#zp-call-ended-event),
[`zp-call-log-completed-event`](#zp-call-log-completed-event),
[`zp-call-recording-completed-event`](#zp-call-recording-completed-event), and
[`zp-call-voicemail-received-event`](#zp-call-voicemail-received-event).
### Integrate contacts from a third-party app
### Search contacts
When `enableContactSearching` is true, the widget supports searching contacts through the number or name on both Keypad and SMS.
#### zp-contact-search-event
This event fires when user types in the input area.
```json
{
"type": "zp-contact-search-event",
"data": {
"requestId": ,
"searchString":
}
}
```
Search the contacts by the `searchString` in your application. Then post the search result with the following response message:
```javascript
document.querySelector('iframe#zoom-embeddable-phone-iframe').contentWindow.postMessage({
type: 'zp-contact-search-response',
data: {
responseId:
contacts: [{
number: ,
displayName:
}];
}
}, 'https://applications.zoom.us');
```
### Match contacts
When `enableContactMatching` is true, the widget matches contacts by phone number on **Incoming**, **Outgoing**, **History**, and **Voicemail** pages.
#### zp-contact-match-event
This event fires on the above pages.
```json
{
"type": "zp-contact-match-event",
"data": {
"requestId": ,
"phoneNumbers": []
}
}
```
Match contacts with phone numbers in third-party applications and post the match result through the following response message.
```javascript
document.querySelector('iframe#zoom-embeddable-phone-iframe').contentWindow.postMessage({
type: 'zp-contact-match-response',
data: {
responseId:
contacts: {
:{
id: ,
name:
}
};
}
}, 'https://applications.zoom.us');
```
### Add notes
Build your note page with the structure below and add the note configuration JSON string to the `notePageConfiguration` parameter in the widget initialization message.

#### Build the JSON notes structure
The widget displays text and select fields.
**Text**
```json
{
"fieldName": , // String, Required
"fieldType": "text", // Required
"placeholder": , // String, Optional
}
```
**Select**
```json
{
"fieldName": , // String, Required
"fieldType": "select", // Required
"placeholder": , // String, Optional
"selectOptions": [ // Array(Object), Required
{
"label":