Salesforce Voice with Partner Telephony supports four multiparty patterns.
| UI Button | Pattern | SDK Entry Point |
|---|---|---|
Blind Transfer (when hasBlindTransfer capability is enabled) |
Rep dials target, drops immediately. | addParticipant(contact, call, isBlindTransfer=true) |
| New Call | Rep dials target, stays to announce, then drops. | addParticipant(contact, call, isBlindTransfer=false) |
New Call (when canConsult capability is enabled) |
Rep dials a private leg while the original call is on a type of hold without music. | dial(contact, new DialOptions({ isConsultCall: true })) |
| Add Caller | A new participant is immediately merged. | addParticipant(contact, call, isBlindTransfer=false) with call.callAttributes.isAutoMergeOn: true |
note: The UI controls are gated by capability flags returned from getVoiceCapabilities(). The Blind Transfer button only appears when hasBlindTransfer: true. The consult variant of New Call appears only when canConsult: true. If you don't enable a capability, the UI control doesn't render.
VoiceCall Records and Leg Linking
Each call leg gets its own new VoiceCall record (0LQ...), created server-side before publishing the leg's CALL_STARTED. Set parentVoiceCallId to link the child leg back to the parent.
Prerequisite: Declare Capabilities
async getVoiceCapabilities() {
return new VoiceCapabilitiesResult({
hasBlindTransfer: true, // enables blind transfer via New Call
canConsult: true, // enables warm transfer and consult via New Call
hasMerge: true,
hasSwap: true,
});
}
Blind Transfer
The framework sends ADD_PARTICIPANT with isBlindTransfer=true. Your connector adds the new participant on the backend and returns. The framework automatically fires HANGUP for the original call. You don't publish it yourself.
Warm Transfer
The framework sends ADD_PARTICIPANT but isBlindTransfer=false. The rep stays to announce the transfer, then manually ends their own leg. When the rep drops, the framework fires PARTICIPANT_REMOVED (not HANGUP).
Consult
The rep dials a private second leg while the original call is held. The framework sends DIAL with isConsultCall: true. Then there are three options for what happens next.
| Rep Action | Connector Method | Event Framework Fires |
|---|---|---|
| Merge all into conference | conference(calls) |
PARTICIPANTS_CONFERENCED |
| Swap which leg is active | swap(call1, call2) |
PARTICIPANTS_SWAPPED |
| End consult, resume original | endCall(call) |
HANGUP for consult leg only |
Add Caller or Auto-Merge Conference
The new participant is immediately merged into a live conference. Set isAutoMergeOn: true in PhoneCallAttributes of the ParticipantResult so Salesforce knows to suppress the hold button for that leg.