# Telephony Integration Guide

#### How It Works

```
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  Phone Callers  │────▶│  Your Voice     │────▶│  Digital Samba  │
│  (PSTN)         │     │  API Provider   │     │  Room           │
└─────────────────┘     └─────────────────┘     └─────────────────┘
                              │
                              │ SIP Connection
                              ▼
                        ┌─────────────────┐
                        │  Your Middleware│
                        │  Application    │
                        └─────────────────┘
```

The integration consists of:

1. **Voice API Provider** - Handles phone calls, IVR prompts, and PSTN conferencing (e.g., Twilio, Sinch, Vonage, Plivo)
2. **SIP Trunk** - Connects your Voice API to Digital Samba
3. **Middleware Application** - Routes calls, manages PINs, and synchronises state between your Voice API and Digital Samba
4. **Digital Samba Room** - Video conferencing room with telephony enabled

### Prerequisites

Before starting your integration:

1. **Digital Samba Account** with API access
2. **Voice API Provider Account** with:
   * A phone number for incoming calls
   * Voice/conferencing API access
   * SIP trunking capability
3. **SIP Trunk Configuration** - Contact Digital Samba support to configure IP whitelisting and authentication for your SIP trunk

> **Important**: Before proceeding with implementation, contact Digital Samba support to set up your SIP trunk. Provide your SIP provider details and we will guide you through IP whitelisting and authentication configuration.

### Architecture Overview

#### System Components

```
┌────────────────────────────────────────────────────────────────────────┐
│                        Your Integration                                │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  ┌──────────────┐      ┌──────────────────┐      ┌──────────────────┐  │
│  │  Voice API   │      │   Middleware     │      │   Digital Samba  │  │
│  │  Provider    │◀────▶│   Application    │◀────▶│   API            │  │
│  │              │      │                  │      │                  │  │
│  │ • Phone #    │      │ • Call routing   │      │ • Room creation  │  │
│  │ • IVR        │      │ • PIN validation │      │ • Phone user API │  │
│  │ • Conference │      │ • SIP control    │      │ • Webhooks       │  │
│  │ • SIP trunk  │      │ • State sync     │      │ • Mute control   │  │
│  └──────────────┘      └──────────────────┘      └──────────────────┘  │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘
```

#### Call Flow Sequence

```
Phone User              Voice Provider          Your App            Digital Samba
    │                        │                     │                     │
    │ 1. Dial phone number   │                     │                     │
    │───────────────────────▶│                     │                     │
    │                        │ 2. Webhook: ICE     │                     │
    │                        │────────────────────▶│                     │
    │                        │                     │                     │
    │ 3. IVR: "Enter PIN"    │                     │                     │
    │◀───────────────────────│◀────────────────────│                     │
    │                        │                     │                     │
    │ 4. Enter PIN (e.g. 123)│                     │                     │
    │───────────────────────▶│ 5. DTMF callback    │                     │
    │                        │────────────────────▶│                     │
    │                        │                     │ 6. Validate PIN     │
    │                        │                     │───────┐             │
    │                        │                     │       │             │
    │                        │                     │◀──────┘             │
    │                        │ 7. Connect to conf  │                     │
    │                        │◀────────────────────│                     │
    │                        │                     │                     │
    │ 8. Joined conference   │                     │ 9. Phone user joined│
    │◀───────────────────────│                     │────────────────────▶│
    │                        │                     │                     │
    │ 10. Hear room audio    │                     │                     │
    │◀═══════════════════════│═════════════════════│═════════════════════│
    │                        │ (via SIP bridge)    │                     │
```

### Step 1: Configure Digital Samba Room

#### Create a Telephony-Enabled Room

When creating a room via the API, include the telephony configuration:

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/rooms \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "My Telephony Room",
    "friendly_url": "telephony-room",
    "telephony_enabled": true,
    "telephony_phone_number": "+1234567890",
    "telephony_pin_dtmf": "WWW123#"
  }'
```

#### Telephony Room Properties

| Property                 | Type    | Description                                                      |
| ------------------------ | ------- | ---------------------------------------------------------------- |
| `telephony_enabled`      | boolean | Enable telephony for this room                                   |
| `telephony_phone_number` | string  | The phone number for SIP to dial into your Voice API conference  |
| `telephony_pin_dtmf`     | string  | DTMF sequence for SIP to enter when connecting to the conference |

#### DTMF Sequence Format

The `telephony_pin_dtmf` field uses special characters:

| Character | Meaning                                    |
| --------- | ------------------------------------------ |
| `W`       | Wait 1 second (for IVR prompts)            |
| `w`       | Wait 0.5 seconds                           |
| `0-9`     | Dial digit                                 |
| `*`       | Dial asterisk                              |
| `#`       | Dial pound/hash (often used as terminator) |

**Example**: `WWW123#` means:

* Wait 3 seconds for IVR prompt
* Dial `123`
* Press `#` to confirm

### Step 2: Build Your Middleware Application

Your middleware application handles communication between your Voice API provider and Digital Samba.

#### Core Responsibilities

1. **Handle incoming calls** from your Voice API provider
2. **Play IVR prompts** and collect PIN input
3. **Route callers** to the correct conference based on PIN
4. **Manage SIP connection** to Digital Samba room
5. **Synchronise phone user state** with Digital Samba API
6. **Handle webhooks** from both Voice API and Digital Samba

#### Conference and PIN Management

Your application must maintain a mapping between:

* Digital Samba room IDs
* Voice API conference IDs
* PINs for phone callers
* PINs for SIP bridge connections

> **Important**: Voice API providers do not have inherent knowledge of conferences until you create them. You must build your own database and logic to:
>
> * Generate and assign PINs
> * Map PINs to conferences
> * Route callers based on PIN input

#### Example PIN Structure

```javascript
// Example conference mapping
const conferenceMapping = {
  conferences: {
    "conf_123": {
      digitalSambaRoomId: "a74d5723-6b98-45e3-8135-149e57fe9072",
      voiceApiConferenceId: "your-provider-conf-id",
      callerPins: ["1234", "5678", "9012"],  // PINs for phone users
      sipPin: "11",  // PIN for SIP bridge connection
      sipDtmfSequence: "WWW11#"
    }
  }
};
```

#### Identifying the SIP Connection

When the SIP bridge connects to your Voice API conference, you must identify it distinctly from regular phone callers. Common approaches:

1. **Reserved PIN** - Use a specific PIN only for SIP connections
2. **Display Name** - Check for a specific display name (e.g., starts with "SIP")
3. **Origination Type** - Check call metadata for SIP origin
4. **Domain** - Check if domain equals "SIP"

> **Critical**: Do NOT notify Digital Samba when the SIP bridge joins. The SIP connection is not a "real" phone user—it's the audio bridge between your Voice API conference and the Digital Samba room.

### Step 3: Digital Samba Phone User API

#### Notify When Phone Users Join

When a phone caller successfully joins your Voice API conference (after PIN validation and only after SIP is connected), notify Digital Samba:

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/rooms/{room_id}/phone-participants-joined \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY \
  --header 'Content-Type: application/json' \
  --data '{
    "participants": [
      {
        "callId": "unique-call-identifier",
        "name": "Phone User 1",
        "callerNumber": "+1987654321",
        "externalId": "your-internal-user-id"
      }
    ]
  }'
```

**Request Parameters**

| Parameter      | Type   | Required | Description                                                 |
| -------------- | ------ | -------- | ----------------------------------------------------------- |
| `callId`       | string | Yes      | Unique identifier for this phone call (from your Voice API) |
| `name`         | string | No       | Display name for the phone user                             |
| `callerNumber` | string | No       | Phone number of the caller                                  |
| `externalId`   | string | No       | Your internal user identifier                               |

> **Note**: The `externalId` parameter is reserved for future functionality. It may be used to link phone participants with web participants who share the same external ID.

#### Notify When Phone Users Leave

When a phone caller disconnects:

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/rooms/{room_id}/phone-participants-left \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY \
  --header 'Content-Type: application/json' \
  --data '{
    "callIds": ["unique-call-identifier"]
  }'
```

#### Raise Hand for Phone User

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/rooms/{room_id}/phone-participants/{callId}/raise-hand \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY
```

#### Lower Hand for Phone User

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/rooms/{room_id}/phone-participants/{callId}/lower-hand \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY
```

### Step 4: Configure Digital Samba Webhooks

Set up webhooks to receive events from Digital Samba rooms. This enables you to synchronise actions (like mute/unmute) with your Voice API.

#### Create a Webhook

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/webhooks \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY \
  --header 'Content-Type: application/json' \
  --data '{
    "endpoint": "https://your-app.com/webhooks/digitalsamba",
    "name": "Telephony Integration Webhook",
    "events": [
      "participant_joined",
      "participant_left",
      "session_started",
      "session_ended"
    ],
    "authorization_header": "your-webhook-secret"
  }'
```

#### Relevant Webhook Events

| Event                | Description                                         |
| -------------------- | --------------------------------------------------- |
| `participant_joined` | Triggered when any participant (web or phone) joins |
| `participant_left`   | Triggered when any participant leaves               |
| `session_started`    | Triggered when a room session begins                |
| `session_ended`      | Triggered when a room session ends                  |

#### Webhook Security

Always validate that webhook requests are legitimately from Digital Samba by checking the `Authorization` header matches your configured secret.

```javascript
// Example webhook validation
app.post('/webhooks/digitalsamba', (req, res) => {
  const authHeader = req.headers['authorization'];
  
  if (authHeader !== 'your-webhook-secret') {
    return res.status(401).send('Unauthorized');
  }
  
  // Process webhook
  const event = req.body;
  handleDigitalSambaEvent(event);
  
  res.status(200).send('OK');
});
```

### Step 5: Initiate SIP Connection

When a moderator in the Digital Samba room clicks "Connect Telephony" (requires the "Manage phone users" permission), Digital Samba initiates a SIP call to your Voice API.

#### What Happens

1. Digital Samba's SIP server calls the configured `telephony_phone_number`
2. Your Voice API answers and plays IVR
3. SIP sends the `telephony_pin_dtmf` sequence
4. Your application routes SIP to the correct conference
5. Room audio is now bridged to the PSTN conference

#### Important Timing

* Moderators should connect telephony **early in the session** if phone users are expected
* Phone users who call before SIP is connected will be in the Voice API conference but won't hear room audio
* Only notify Digital Samba of phone users **after** SIP has connected

### Step 6: Managing Phone Users in Room

Once connected, phone users appear in the Digital Samba participant list. Moderators can:

* **See phone users** in the participants panel
* **Mute/unmute phone users** via the menu
* **Remove phone users** from the room

#### Handling Mute/Unmute

When a moderator mutes a phone user in Digital Samba, you'll receive a webhook. Your middleware should then call your Voice API to mute that participant in the PSTN conference.

```javascript
// Example mute handler
function handleMuteEvent(event) {
  if (event.type === 'phone_participant_muted') {
    const callId = event.data.callId;
    
    // Call your Voice API to mute this participant
    voiceApi.muteParticipant(callId);
  }
}
```

### Integration Checklist

#### Before Development

* \[ ] Contact Digital Samba support to configure SIP trunk
* \[ ] Set up Voice API provider account with phone number
* \[ ] Understand your Voice API's webhook/callback structure
* \[ ] Plan your PIN/conference management strategy

#### Development

* \[ ] Create rooms with telephony enabled via API
* \[ ] Build middleware to handle Voice API callbacks
* \[ ] Implement IVR flow for PIN collection
* \[ ] Build PIN validation and conference routing
* \[ ] Integrate Digital Samba Phone User API
* \[ ] Set up webhook handlers for Digital Samba events
* \[ ] Implement mute/unmute synchronisation

#### Testing

* \[ ] Test phone dial-in flow end-to-end
* \[ ] Verify SIP connection with correct PIN/DTMF
* \[ ] Confirm phone users appear in Digital Samba room
* \[ ] Test mute/unmute from room to phone
* \[ ] Test phone user disconnect handling
* \[ ] Verify audio quality and latency

### API Reference

#### Phone Participants Endpoints

| Method | Endpoint                                                      | Description               |
| ------ | ------------------------------------------------------------- | ------------------------- |
| `POST` | `/api/v1/rooms/{room}/phone-participants-joined`              | Notify phone users joined |
| `POST` | `/api/v1/rooms/{room}/phone-participants-left`                | Notify phone users left   |
| `POST` | `/api/v1/rooms/{room}/phone-participants/{callId}/raise-hand` | Raise hand for phone user |
| `POST` | `/api/v1/rooms/{room}/phone-participants/{callId}/lower-hand` | Lower hand for phone user |

#### Room Creation with Telephony

Include these properties when creating or updating rooms:

```json
{
  "telephony_enabled": true,
  "telephony_phone_number": "+1234567890",
  "telephony_pin_dtmf": "WWW123#"
}
```

### Troubleshooting

#### SIP Connection Issues

| Issue                           | Possible Cause                  | Solution                                                 |
| ------------------------------- | ------------------------------- | -------------------------------------------------------- |
| SIP cannot connect              | IP not whitelisted              | Contact DS support to verify IP whitelist                |
| No audio after SIP connects     | Wrong DTMF sequence             | Verify PIN and timing in `telephony_pin_dtmf`            |
| SIP connects but no phone users | Phone users notified before SIP | Only call `phone-participants-joined` after SIP connects |

#### Common Mistakes

1. **Notifying Digital Samba when SIP joins** - The SIP bridge is not a phone user; do not send `phone-participants-joined` for it
2. **Phone users notified before SIP connects** - Phone users won't hear room audio until SIP is bridged; wait for SIP before notifying DS
3. **Missing DTMF terminator** - Many IVR systems require `#` to confirm PIN entry
4. **Insufficient wait time** - If IVR prompts are long, increase `W` characters in DTMF sequence

### Support

For assistance with your telephony integration:

* **SIP Trunk Configuration** : [Contact Digital Samba support](https://www.digitalsamba.com/embedded-support)
* **Platform Documentation**: [docs.digitalsamba.com](https://docs.digitalsamba.com/)
* **API Reference**: [developer.digitalsamba.com](https://developer.digitalsamba.com/)
* **Sinch Middleware demo middleware:** <https://github.com/digitalsamba/sinch-conference-middleware>

***

### Appendix: Example Application Architecture

```
┌──────────────────────────────────────────────────────────────────────────┐
│                         Middleware Application                           │
├──────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────────┐   │
│  │  Voice API      │    │  Conference     │    │  Digital Samba      │   │
│  │  Event Handler  │    │  Manager        │    │  Client             │   │
│  │                 │    │                 │    │                     │   │
│  │ /voice-events   │───▶│ • Create conf   │───▶│ • Phone user join   │   │
│  │                 │    │ • Validate PIN  │    │ • Phone user leave  │   │
│  │ • ICE callback  │    │ • Route caller  │    │ • Raise/lower hand  │   │
│  │ • DTMF input    │    │ • Track SIP     │    │                     │   │
│  │ • Call ended    │    │ • Track callers │    │                     │   │
│  └─────────────────┘    └─────────────────┘    └─────────────────────┘   │
│           │                      │                        ▲              │
│           │                      │                        │              │
│           ▼                      ▼                        │              │
│  ┌─────────────────────────────────────────────────────────────────┐     │
│  │                          Database                                 │   │
│  │                                                                   │   │
│  │  conferences: {room_id, voice_conf_id, caller_pins[], sip_pin}  │     │
│  │  active_calls: {call_id, conf_id, phone_number, is_sip}         │     │
│  └─────────────────────────────────────────────────────────────────┘     │
│                                                                          │
├──────────────────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐                                                     │
│  │  DS Webhook     │◀────── Digital Samba webhook events                 │
│  │  Handler        │        (mute, unmute, session events)               │
│  │                 │                                                     │
│  │ /ds-webhooks    │───────▶ Voice API (mute participant, etc.)         │
│  └─────────────────┘                                                     │
└──────────────────────────────────────────────────────────────────────────┘
```

#### Data Flow Summary

1. **Incoming Call** → Voice API → Your App → Validate PIN → Join Conference
2. **SIP Connection** → Voice API Conference → Audio Bridge → Digital Samba Room
3. **Phone User Joins** → Your App → Digital Samba API (`phone-participants-joined`)
4. **Moderator Mutes** → Digital Samba → Webhook → Your App → Voice API Mute
5. **Phone User Leaves** → Voice API → Your App → Digital Samba API (`phone-participants-left`)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.digitalsamba.com/sip-telephony-integration/telephony-integration-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
