diff --git a/fern/apis/signalwire-rest/openapi.yaml b/fern/apis/signalwire-rest/openapi.yaml index fff0fb9486..517e170c33 100644 --- a/fern/apis/signalwire-rest/openapi.yaml +++ b/fern/apis/signalwire-rest/openapi.yaml @@ -38695,8 +38695,8 @@ components: coach: type: string description: |- - Coach accepts a call SID of a call that is currently connected to an in-progress conference. - Specifying a call SID that does not exist or is no longer connected will result in a failure. + The call ID (a UUID) of a participant already in the conference to coach. This call becomes the coach: only the coached participant hears it, and its audio stays out of the main conference mix. + If the call ID is not a current participant, the join fails. A muted coach is heard by nobody. examples: - b3877ee3-6f3c-4985-8066-6d24e3f65e12 status_callback_event: diff --git a/fern/products/compatibility-api/pages/cxml/voice/conference-noun.mdx b/fern/products/compatibility-api/pages/cxml/voice/conference-noun.mdx index 0fba947c21..a1aea225ac 100644 --- a/fern/products/compatibility-api/pages/cxml/voice/conference-noun.mdx +++ b/fern/products/compatibility-api/pages/cxml/voice/conference-noun.mdx @@ -79,7 +79,7 @@ puts response.to_s - Coach accepts a call [SID](/docs/platform/what-is-a-sid) of a call that is currently connected to an in-progress conference. Specifying a call SID that does not exist or is no longer connected to the conference will result in the call failing to the action URL and throwing a 13240 error. + The call [SID](/docs/platform/what-is-a-sid) of a participant already in the conference to coach. This call becomes the coach: only the coached participant hears it, and its audio stays out of the main conference mix. If the SID is not a current participant, the join fails and `` completes with a `DialCallStatus` of `busy`. A muted coach is heard by nobody. See [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring) for listen-in, whisper, and barge workflows. @@ -539,10 +539,12 @@ end puts response.to_s ``` -Participants who enter a conference call muted can hear the other participants in the call who are unmuted. However, the unmuted participants cannot hear the muted callers. Muting and unmuting can be enabled and disabled in real-time via a REST API. +Participants who enter a conference call muted can hear the other participants in the call who are unmuted. However, the unmuted participants cannot hear the muted callers. Muting and unmuting can be enabled and disabled in real-time via a REST API. For a supervisor workflow that moves between silent monitoring, coaching, and speaking, see [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring). ### Coaching a conference call +The `coach` attribute makes the joining call a coach for the participant whose call SID it names. The coach hears the whole conference, and only the coached participant hears the coach. Everyone else, including a customer on the line, hears nothing from the coach. The coached participant must already be in the conference, and a coach who is also muted is heard by nobody. + ```xml @@ -577,7 +579,7 @@ class Example var response = new VoiceResponse(); var dial = new Dial(); dial.Conference("Example-Room", - coach: 'AgentCallSid'); + coach: "AgentCallSid"); response.Append(dial); Console.WriteLine(response.ToString());; @@ -601,7 +603,7 @@ require 'signalwire/sdk' response = Signalwire::Sdk::VoiceResponse.new do |response| response.dial do |dial| - dial.conference('Example-Room', coach: '') + dial.conference('Example-Room', coach: 'AgentCallSid') end end diff --git a/fern/products/platform/pages/calling/voice/overview.mdx b/fern/products/platform/pages/calling/voice/overview.mdx index 66eb307434..0dc6c80f4b 100644 --- a/fern/products/platform/pages/calling/voice/overview.mdx +++ b/fern/products/platform/pages/calling/voice/overview.mdx @@ -72,6 +72,9 @@ SignalWire's advanced APIs and elastic cloud infrastructure make it a breeze to Guide that focuses on how to make and receive phone calls via a SWML script. + + Listen in on, whisper to, or barge an agent's call from a supervisor console. + {/* Core links */} diff --git a/fern/products/platform/pages/calling/voice/supervisor-call-monitoring.mdx b/fern/products/platform/pages/calling/voice/supervisor-call-monitoring.mdx new file mode 100644 index 0000000000..7cc8f08185 --- /dev/null +++ b/fern/products/platform/pages/calling/voice/supervisor-call-monitoring.mdx @@ -0,0 +1,238 @@ +--- +title: Supervisor call monitoring +slug: /voice/supervisor-call-monitoring +description: Listen in on a live call silently, whisper to an agent without the customer hearing, or barge in, using SignalWire conferences from SWML, cXML, REST, or the Server SDKs. +max-toc-depth: 3 +--- + +[join-conference]: /docs/swml/reference/calling/join-conference +[conference-noun]: /docs/compatibility-api/cxml/reference/voice/conference +[update-participant]: /docs/compatibility-api/rest/conference-participants/update-participant +[list-participants]: /docs/compatibility-api/rest/conference-participants/list-all-participants +[call-commands]: /docs/apis/rest/calls/call-commands +[create-a-call]: /docs/compatibility-api/rest/calls/create-a-call +[sdk-py-update]: /docs/server-sdks/reference/python/rest/compat/conferences/update-participant +[sdk-ts-update]: /docs/server-sdks/reference/typescript/rest/compat/conferences/update-participant +[sdk-py-dial]: /docs/server-sdks/reference/python/rest/calling/dial +[sdk-ts-dial]: /docs/server-sdks/reference/typescript/rest/calling/dial +[sid]: /docs/platform/what-is-a-sid +[call-whisper]: /docs/swml/guides/call-whisper +[ai-params]: /docs/swml/reference/calling/ai/params +[ai-sidecar]: /docs/swml/reference/calling/ai-sidecar +[stream]: /docs/swml/reference/calling/stream +[tap]: /docs/swml/reference/calling/tap + +A supervisor on a contact-centre floor needs three things from a live call: to hear it without being heard, to coach the agent without the customer hearing, and to step into the conversation outright. SignalWire supports all three on any call that runs inside a conference, and a supervisor console can move between them mid-call with one REST request per switch. + +Monitoring works on conference participants only. The agent's call must already be in a SignalWire conference before a supervisor can hear it, so route agent calls through [`join_conference`][join-conference] in SWML or [``][conference-noun] in cXML rather than a plain two-party connect. There is no way to listen to, whisper into, or barge a call that is bridged directly to another call. + +## The three modes + +Two participant settings drive every mode: `muted` and `coach`. There is no separate listen-in or barge parameter to look for. + +| Mode | Supervisor hears | Supervisor is heard by | Settings on the supervisor's call | +|---|---|---|---| +| Listen in | Everyone | Nobody | `muted` on | +| Whisper | Everyone | The agent only | `muted` off, `coach` set to the agent's call ID | +| Barge | Everyone | Everyone | `muted` off, no `coach` | + +The `coach` setting names the participant being coached. The call that carries it becomes the coach: its audio goes to the coached participant alone and stays out of the main conference mix, so the customer never hears it. A muted coach is not heard by anyone, so whisper requires the supervisor to be unmuted. + +## Before you start + +You need three values, all of them from the agent's side of the call: + +- **The conference name** the agent's call joined. +- **The agent's call ID.** Read it from the conference `join` status callback, or from [List all active Participants][list-participants]. cXML and the Compatibility REST API call this value the call SID; SWML and the Calling API call it the call ID. Each is the [UUID that identifies the call][sid]. +- **The conference SID**, from the same status callback or from the participants list. The REST requests below address the supervisor by conference SID and call ID. + +REST requests use a project API token with the Voice scope. + +There is no REST request that adds a participant to a conference. To bring a supervisor in, create a call whose instructions join the conference, with [Send call commands][call-commands] on the Calling API for SWML or [Create a call][create-a-call] on the Compatibility API for cXML, or let the supervisor dial a number that runs those instructions. + +## Listen in + +Join the supervisor's call to the agent's conference with `muted` on. The supervisor hears every unmuted participant and is heard by nobody. + +```yaml title="SWML" +version: 1.0.0 +sections: + main: + - join_conference: + name: support-floor + muted: true +``` + +Silent monitoring leaves no marker of its own. A muted supervisor looks like any other muted participant in the participant list and in status callbacks, so if you need a record of who listened to which call, write it in your application from the `join` and `leave` events. + +## Whisper + +Join unmuted and set `coach` to the agent's call ID. The supervisor hears the whole conference, and only the agent hears the supervisor. + +```yaml title="SWML" +version: 1.0.0 +sections: + main: + - join_conference: + name: support-floor + coach: b3877ee3-6f3c-4985-8066-6d24e3f65e12 +``` + +The agent must be in the conference when the supervisor joins. If the call ID in `coach` is not a current participant, the join fails: in cXML, `` completes with a `DialCallStatus` of `busy` and control passes to its action URL; in SWML, `join_conference_result` reports the failure and the script continues. + +## Barge + +Join unmuted with no `coach`, and the supervisor is an ordinary participant that everyone hears. In practice a supervisor rarely joins this way. They start by listening or whispering and barge by changing state, as the next section shows. + +## Switch modes during the call + +Markup sets a participant's state at join time. Changing it afterward is a cross-call operation, so it belongs to the REST API rather than to the supervisor's own SWML or cXML: [Update a Participant][update-participant] on the Compatibility REST API changes `Muted`, `Coaching`, and `CallSidToCoach` for any participant, whether the conference was joined from SWML or cXML. A supervisor console with three buttons makes one request per press. + +| From | To | Request body | +|---|---|---| +| Listen in | Whisper | `Muted=false` `Coaching=true` `CallSidToCoach=` | +| Listen in | Barge | `Muted=false` | +| Whisper | Barge | `Coaching=false` | +| Whisper | Listen in | `Muted=true` `Coaching=false` | +| Barge | Whisper | `Coaching=true` `CallSidToCoach=` | +| Barge | Listen in | `Muted=true` | + +The request is form-encoded, addressed by the conference SID and the supervisor's call ID: + +```bash title="Listen in to whisper" +curl -X POST "https://example.signalwire.com/api/laml/2010-04-01/Accounts/$PROJECT_ID/Conferences/$CONFERENCE_SID/Participants/$SUPERVISOR_CALL_ID" \ + -u "$PROJECT_ID:$API_TOKEN" \ + --data-urlencode "Muted=false" \ + --data-urlencode "Coaching=true" \ + --data-urlencode "CallSidToCoach=$AGENT_CALL_ID" +``` + +The only reader this split inconveniences is a supervisor dialing in from a handset with no application behind them. Give that supervisor a console, or a separate number whose instructions join in each mode. + +### End to end with the Server SDKs + +The Server SDKs cover both halves: [`dial`][sdk-py-dial] on the Calling API places the supervisor's call with inline SWML, and [`update_participant`][sdk-py-update] on the Compatibility API changes its state. The TypeScript equivalents are [`dial`][sdk-ts-dial] and [`updateParticipant`][sdk-ts-update]. The agent's call ID and the conference SID come from the conference's `join` status callback. + + +```python {14-22,26-32,35} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +# Both values arrive on the conference's `join` status callback for the agent's call. +conference_sid = "e2a5f5c3-0b6d-4d7f-9c2a-1f3b4c5d6e7f" +agent_call_id = "b3877ee3-6f3c-4985-8066-6d24e3f65e12" + +# 1. Bring the supervisor in silently. +supervisor = client.calling.dial( + from_="+15551234567", + to="+15559876543", + swml={ + "version": "1.0.0", + "sections": {"main": [{"join_conference": {"name": "support-floor", "muted": True}}]}, + }, +) +supervisor_call_id = supervisor["id"] + +# 2. Whisper: unmute and coach the agent in one request. +client.compat.conferences.update_participant( + conference_sid, + supervisor_call_id, + Muted=False, + Coaching=True, + CallSidToCoach=agent_call_id, +) + +# 3. Barge: stop coaching, and everyone hears the supervisor. +client.compat.conferences.update_participant(conference_sid, supervisor_call_id, Coaching=False) +``` + +```typescript {14-22,26-30,33} +import { RestClient } from "@signalwire/sdk"; + +const client = new RestClient({ + project: "your-project-id", + token: "your-api-token", + host: "your-space.signalwire.com", +}); + +// Both values arrive on the conference's `join` status callback for the agent's call. +const conferenceSid = "e2a5f5c3-0b6d-4d7f-9c2a-1f3b4c5d6e7f"; +const agentCallId = "b3877ee3-6f3c-4985-8066-6d24e3f65e12"; + +// 1. Bring the supervisor in silently. +const supervisor = await client.calling.dial({ + from: "+15551234567", + to: "+15559876543", + swml: { + version: "1.0.0", + sections: { main: [{ join_conference: { name: "support-floor", muted: true } }] }, + }, +}); +const supervisorCallId = supervisor.id; + +// 2. Whisper: unmute and coach the agent in one request. +await client.compat.conferences.updateParticipant(conferenceSid, supervisorCallId, { + Muted: false, + Coaching: true, + CallSidToCoach: agentCallId, +}); + +// 3. Barge: stop coaching, and everyone hears the supervisor. +await client.compat.conferences.updateParticipant(conferenceSid, supervisorCallId, { Coaching: false }); +``` + + +To confirm the switch took effect, retrieve the supervisor's participant record. `coaching` is `true` and `call_sid_to_coach` holds the agent's call ID while whispering, and `muted` is `true` while listening in. If the update returns error 16002, `Coaching` was `true` without a `CallSidToCoach`, or the call ID in `CallSidToCoach` is not in that conference. + +## Keep the console in sync + +Subscribe to participant events so the console's buttons reflect state set anywhere, including a mute from another tool. In SWML, set `status_callback` and `status_callback_event` on the `join_conference` that creates the conference; in cXML, set `statusCallback` and `statusCallbackEvent` on ``. The `join`, `leave`, `mute`, `hold`, and `speaker` events carry each participant's mute state and coaching state: `muted` and `coaching` in SWML callbacks, `Muted`, `Coaching`, and `CallSidToCoach` in cXML callbacks. + +## Limits + +- **Conference only.** A directly bridged two-party call cannot be monitored. Put agent calls in a conference from the start if supervisors may need to join. +- **The agent must be present first.** A `coach` that names a call outside the conference fails the join, and a REST update naming one returns error 16002. +- **A participant cannot coach itself.** +- **Muted wins.** A muted coach is heard by nobody. Whisper needs `Muted=false` alongside `Coaching=true`. +- **The coach leaves with the agent.** When the coached participant leaves the conference, every participant coaching them is removed from it too, and each of those calls continues with whatever follows the join in its own instructions. Switch a supervisor to listen in or barge before the agent hangs up if they need to stay. +- **Several supervisors can coach one agent** at the same time. Each coach whispers to one participant. +- **Same project.** A supervisor can only join conferences in the project that created them. + +## Recording and consent + + +Listening to, coaching on, or joining a call counts as monitoring or recording under laws that vary by country, by state, and by whether the call is inbound or outbound. Many require notice to one or both parties. SignalWire plays no notice and performs no consent check for you. Your application is responsible for any announcement, consent capture, and record-keeping the law requires. Consult qualified counsel before deploying supervisor monitoring. + + +Coaching state is visible: the participant record and the participant status callbacks report `coaching` and the coached call ID. Silent monitoring is not distinguished from any other muted participant, so keep your own log if you need one. + +## Not the same as + +Several features share this vocabulary and do something else: + +- **[Call whisper][call-whisper]** in SWML plays an announcement to the person answering before the caller is connected. It is call screening, not coaching. +- **AI barge** in [`ai.params`][ai-params] controls whether a caller can interrupt the AI agent's speech. It has nothing to do with a human joining a call. +- **[`ai_sidecar`][ai-sidecar]** observes a call and emits text for a UI. It injects no audio and is not a participant. +- **[`stream`][stream] and [`tap`][tap]** fork call audio to a WebSocket or RTP endpoint. The receiver gets a media stream, not a call leg, and cannot speak into the call. + +## Next steps + + + + Every SWML conference parameter, including `muted`, `coach`, and the status callback events. + + + The `` attributes and the status callback fields. + + + The REST request that switches a participant between modes. + + + The same request from Python, with a TypeScript twin. + + diff --git a/fern/products/platform/pages/getting-started.mdx b/fern/products/platform/pages/getting-started.mdx index adf97ea380..b0661fe295 100644 --- a/fern/products/platform/pages/getting-started.mdx +++ b/fern/products/platform/pages/getting-started.mdx @@ -154,9 +154,10 @@ This is common for: **If you need straightforward call handling** (IVRs, call forwarding, playing messages), use **[SWML](/docs/swml)**. Your server responds to webhooks with JSON/YAML instructions. It's stateless and works with any programming language. -**If you need realtime control** (live call monitoring, mid-call transfers, complex orchestration), use the **[RELAY client](/docs/server-sdks/guides/relay-client)**. +**If you need realtime control** (reacting to call events as they happen, mid-call transfers, complex orchestration), use the **[RELAY client](/docs/server-sdks/guides/relay-client)**. It maintains a persistent WebSocket connection for instant, bi-directional communication. Best for applications that need to react to events as they happen. +For a supervisor who listens in on, whispers to, or barges an agent's call, see [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring). **If you're building AI voice agents**, use the **[Server SDKs](/docs/server-sdks)**. They're designed for creating conversational AI that handles phone calls, in the language of your choice: diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/join-conference.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/join-conference.mdx index 749735a45e..65f1e5e341 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/join-conference.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/join-conference.mdx @@ -74,8 +74,9 @@ used internally. Passing any non-default parameter triggers the full object form - SWML Call ID or CXML CallSid of a participant who can coach (whisper to) - this participant without other participants hearing. + Call ID of the participant to coach. The call that sets this becomes the + coach: only the coached participant hears it, and its audio stays out of the + main conference mix. See [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring). diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/join-conference.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/join-conference.mdx index f879d04380..466c9c0bc0 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/join-conference.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/join-conference.mdx @@ -72,7 +72,9 @@ This method emits [`calling.conference`][calling-conference] events. See [Call E - Call ID of a participant who can hear but not be heard (coaching mode). + Call ID of the participant to coach. The call that sets this becomes the + coach: only the coached participant hears it, and its audio stays out of the + main conference mix. See [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring). diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update-participant.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update-participant.mdx index f5a32b2651..59e768d8f9 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update-participant.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update-participant.mdx @@ -1,12 +1,12 @@ --- title: "update_participant" slug: /reference/python/rest/compat/conferences/update-participant -description: Update a participant in a conference (mute or hold). +description: Mute, hold, or coach a conference participant, or switch a supervisor between listening in, whispering, and barging. max-toc-depth: 3 --- -Update a participant in a conference (e.g., mute or hold). +Update a participant in a conference: mute or unmute them, put them on hold, or make them a coach who is heard by one other participant only. Switching a supervisor between listening in, whispering, and barging is this call with different fields; see [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring). @@ -27,3 +27,23 @@ client = RestClient( client.compat.conferences.update_participant("CF...", "CA...", Muted=True) ``` + +Turn a muted supervisor into a coach who is heard only by the participant named in `CallSidToCoach`: + +```python {9-15} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +client.compat.conferences.update_participant( + "CF...", + "CA...", + Muted=False, + Coaching=True, + CallSidToCoach="b3877ee3-6f3c-4985-8066-6d24e3f65e12", +) +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/function-result/join-conference.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/function-result/join-conference.mdx index 9eb5af3024..b3621a9c59 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/function-result/join-conference.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/function-result/join-conference.mdx @@ -75,8 +75,9 @@ used internally. Passing any non-default parameter triggers the full object form - SWML Call ID or CXML CallSid of a participant who can coach (whisper to) - this participant without other participants hearing. + Call ID of the participant to coach. The call that sets this becomes the + coach: only the coached participant hears it, and its audio stays out of the + main conference mix. See [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring). diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/join-conference.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/join-conference.mdx index 09db2ce786..27dada0334 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/join-conference.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/join-conference.mdx @@ -70,7 +70,9 @@ This method emits [`calling.conference`][calling-conference] events. See [Call E - Call ID of a participant who can hear but not be heard (coaching mode). + Call ID of the participant to coach. The call that sets this becomes the + coach: only the coached participant hears it, and its audio stays out of the + main conference mix. See [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring). diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/compat/conferences/update-participant.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/compat/conferences/update-participant.mdx index f6971c428e..e03b238625 100644 --- a/fern/products/server-sdks/pages/reference/typescript/rest/compat/conferences/update-participant.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/rest/compat/conferences/update-participant.mdx @@ -1,12 +1,12 @@ --- title: "updateParticipant" slug: /reference/typescript/rest/compat/conferences/update-participant -description: Update a participant in a conference (mute or hold). +description: Mute, hold, or coach a conference participant, or switch a supervisor between listening in, whispering, and barging. max-toc-depth: 3 --- -Update a participant in a conference (e.g., mute or hold). +Update a participant in a conference: mute or unmute them, put them on hold, or make them a coach who is heard by one other participant only. Switching a supervisor between listening in, whispering, and barging is this call with different fields; see [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring). @@ -27,3 +27,21 @@ const client = new RestClient({ await client.compat.conferences.updateParticipant("CF...", "CA...", { Muted: true }); ``` + +Turn a muted supervisor into a coach who is heard only by the participant named in `CallSidToCoach`: + +```typescript {9-13} +import { RestClient } from "@signalwire/sdk"; + +const client = new RestClient({ + project: "your-project-id", + token: "your-api-token", + host: "your-space.signalwire.com" +}); + +await client.compat.conferences.updateParticipant("CF...", "CA...", { + Muted: false, + Coaching: true, + CallSidToCoach: "b3877ee3-6f3c-4985-8066-6d24e3f65e12", +}); +``` diff --git a/fern/products/swml/pages/guides/recipes/call-whisper.mdx b/fern/products/swml/pages/guides/recipes/call-whisper.mdx index 507abda85c..86ebf6e9f9 100644 --- a/fern/products/swml/pages/guides/recipes/call-whisper.mdx +++ b/fern/products/swml/pages/guides/recipes/call-whisper.mdx @@ -15,6 +15,10 @@ Call Whisper is a feature that allows you to play a message to the recipient of This feature is useful for informing the recipient about the nature of the call before they answer it. This guide shows you how to perform a Call Whisper using SWML to inform the recipient the number of the caller. + +Looking for a supervisor who whispers to an agent during a live call? That is conference coaching, covered in [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring). + + ## Setting up the SWML scripts To perform a Call Whisper using SWML, you need to create two diff --git a/fern/products/swml/pages/reference/methods/calling/join_conference.mdx b/fern/products/swml/pages/reference/methods/calling/join_conference.mdx index 114165cd88..571d1cded9 100644 --- a/fern/products/swml/pages/reference/methods/calling/join_conference.mdx +++ b/fern/products/swml/pages/reference/methods/calling/join_conference.mdx @@ -75,7 +75,7 @@ This method allows you to connect the current call to a named conference where m **Possible Values**: `trim-silence`, `do-not-trim` - Coach accepts a [call SID](/docs/platform/what-is-a-sid) of a call that is currently connected to an in-progress conference. Specifying a call SID that does not exist or is no longer connected will result in a failure. + The [call ID](/docs/platform/what-is-a-sid) (a UUID) of a participant already in the conference to coach. This call becomes the coach: only the coached participant hears it, and its audio stays out of the main conference mix. If the call ID is not a current participant, the join fails. A muted coach is heard by nobody. See [Supervisor call monitoring](/docs/platform/voice/supervisor-call-monitoring) for listen-in, whisper, and barge workflows. diff --git a/specs/swml/calling/Methods/join_conference/main.tsp b/specs/swml/calling/Methods/join_conference/main.tsp index 7c445ea379..c83af9d859 100644 --- a/specs/swml/calling/Methods/join_conference/main.tsp +++ b/specs/swml/calling/Methods/join_conference/main.tsp @@ -88,8 +88,8 @@ model JoinConferenceObject { trim?: "trim-silence" | "do-not-trim" = "trim-silence"; @doc(""" - Coach accepts a call SID of a call that is currently connected to an in-progress conference. - Specifying a call SID that does not exist or is no longer connected will result in a failure. + The call ID (a UUID) of a participant already in the conference to coach. This call becomes the coach: only the coached participant hears it, and its audio stays out of the main conference mix. + If the call ID is not a current participant, the join fails. A muted coach is heard by nobody. """) @example("b3877ee3-6f3c-4985-8066-6d24e3f65e12") coach?: string; diff --git a/specs/swml/calling/tsp-output/@typespec/json-schema/SWMLObject.json b/specs/swml/calling/tsp-output/@typespec/json-schema/SWMLObject.json index b74abd0da0..e276350efe 100644 --- a/specs/swml/calling/tsp-output/@typespec/json-schema/SWMLObject.json +++ b/specs/swml/calling/tsp-output/@typespec/json-schema/SWMLObject.json @@ -4258,7 +4258,7 @@ "examples": [ "b3877ee3-6f3c-4985-8066-6d24e3f65e12" ], - "description": "Coach accepts a call SID of a call that is currently connected to an in-progress conference.\nSpecifying a call SID that does not exist or is no longer connected will result in a failure." + "description": "The call ID (a UUID) of a participant already in the conference to coach. This call becomes the coach: only the coached participant hears it, and its audio stays out of the main conference mix.\nIf the call ID is not a current participant, the join fails. A muted coach is heard by nobody." }, "status_callback_event": { "type": "string",