Skip to main content

Intents reference

Send a typed command and render its resulting state patch. This reference maps common controls to TypeScript and Go methods. The generated Command reference is exhaustive; SDK availability and return conventions are in TypeScript vs Go.

Session & identity

IntentWhat it doesResult in AgentViewTypeScript · Go
RegisterAnnounce reachability + arm the media path, and load the agent's deployment data (presence options, caller-ID numbers, phonebook, feature config).config, agentregister(caps?) · Register(caps...)
Set WebRTCToggle the in-browser phone on/off.agentsetWebrtc(on) · SetWebrtc(on)
Set agent numberSet the external phone to bridge to.agentsetAgentNumber(num) · SetAgentNumber(num)
Set presenceSwitch presence ("available" or a pause reason).agentsetPresence(name) · SetPresence(name)
Set display-asChoose the outbound number presented to the consumer.agentsetDisplayAs(num) · SetDisplayAs(num)

Choose a presence by presenceOptions[].name; render its label and availability flag. The availability model distinguishes chosen presence, coarse state and an involuntary line block.

Outbound caller ID: the numbers the agent can present are AgentView.agent.availableNumbers; the current selection is agent.displayAs, and setDisplayAs changes it.

Number format: phone numbers (to, from, displayAs, transfer targets) are E.164 — a leading +, country code, then the national number, no spaces or punctuation (e.g. +49301234567), as in the examples.

Where calls ring: setWebrtc and setAgentNumber choose the agent's audio path. With WebRTC enabled (setWebrtc(true)) the agent's call leg routes to the in-browser phone; with it disabled, the backend bridges the call to the agent's external number (setAgentNumber) instead. AgentView.agent.webrtcEnabled tells you which is active. An agent needs one of the two — WebRTC on, or an agent number set — to be reachable; with neither, calls can't reach them.

Registration requests WebRTC reachability, regardless of capabilities. TypeScript supplies ["webrtc"] by default; Go has no default list; the current server ignores both. For an external phone, follow the ordered setup in Control only.

Calls

IntentWhat it doesResult in AgentViewTypeScript · Go
Place callDial out; answering follows the SDK's auto-answer policy. Go's positional args are to (destination), displayAsTo (what the consumer sees), displayAsFrom (what the agent sees), record.callUpsertplaceCall(to, opts?) · PlaceCall(to, displayAsTo, displayAsFrom, record)
AnswerAccept a RINGING call by id.callUpsert (→ in-progress)answerCall(id) · Answer(id)
HangupEnd / reject a call by id.callRemovehangup(id) · Hangup(id)
MuteMute or unmute your leg.callUpsertmute(id, on) · Mute(id, on)
HoldHold or retrieve a call.callUpserthold(id, on) · Hold(id, on)
Send digitsSend DTMF into the call.— (tones only)sendDigits(id, digits) · SendDigits(id, digits)
TransferHand the call to a number, agent, or queue (warm = attended).callUpsert / callRemovetransfer(id, to, opts?) · Transfer(id, to, agentID, applicationID, warm)
Reset line statusClear a blocked line (busy / unreachable).agentresetLineStatus() · ResetLineStatus()

Answering: answerCall(id) does more than flip state — the SDK takes the ringing call's webrtcOffer, runs it through your media leg to produce the WebRTC SDP answer, and sends that. So answering needs a media leg; a control-only client (no mediaFactory) raises no_media instead.

Place-call options: to is the destination number being dialled; displayAsTo is the service number the consumer sees (the outbound caller ID); displayAsFrom is the number shown to the agent. record: true starts the recording from answer (instead of calling startRecording later). In TypeScript these are opts keys (placeCall(to, { displayAsTo, displayAsFrom, record })); in Go they're positional, in this order — PlaceCall(to, displayAsTo, displayAsFrom, record) — so it's easy to swap the two caller-ID arguments by mistake. The TypeScript opts also accepts a session map — opaque CTI correlation, the same keys the embed bridge sets via session.set (see SMS session); the Go signature omits it.

Transfer targets: set the field that matches the destination — an external number as to, another agent as agentId, or a queue / voice application as applicationId. In TypeScript, to is the second argument and agentId / applicationId are opts keys (transfer(id, to, { agentId })); in Go all three are positional params — Transfer(id, to, agentID, applicationID, warm). warm: true is an attended (warm) transfer; false is blind (cold).

Warm transfer is a two-step consult. An attended (warm: true) transfer isn't a single call: first addConferenceMember to pull the target into a conference (the customer is parked on hold while you consult privately), then transfer(id, …, { warm: true }) to complete — that unholds the customer and drops your own leg, leaving them connected to the target. Calling the warm transfer before the target is in a conference returns the no_conference error. A blind (warm: false) transfer is the single hand-off, no consult.

Because of that, the two transfers gate on different config flags: a blind transfer is gated by config.calls.allowTransfer (the cold-transfer action), but a warm transfer runs through a conference, so gate that control on config.calls.allowConference — with conferencing disabled there's no consult step, and the warm transfer can't happen.

DTMF: sendDigits sends RFC-2833 tones to the far end — valid characters are 09, *, #, and AD. The digits string can carry several at once (e.g. "1234#"), sent in sequence; it needs an active call.

Reset line status: if the agent's external phone goes busy, unreachable, or declines a call, the line can get stuck so new calls no longer reach the agent. resetLineStatus clears that blocked state — confirmed back via an agent presence patch — so they can take calls again.

Wrap-up (after-call work)

IntentWhat it doesResult in AgentViewTypeScript · Go
Extend wrap-upAdd seconds to the ACW countdown.wrapUpwrapUpExtend(seconds) · WrapUpExtend(seconds)
Cancel wrap-upEnd after-call work early.wrapUpwrapUpCancel() · WrapUpCancel()

Wrap-up: wrapUpExtend adds time to the after-call-work countdown — the TypeScript form defaults to 30 seconds (wrapUpExtend()), while Go takes an explicit int32. Show the extend / cancel controls only when wrapUp.canExtend / wrapUp.canCancel are set, and render the countdown locally from remainingSeconds (the server doesn't tick it per second; reconcile to each wrapUp patch). See the wrap-up walkthrough for the full sequence.

Recording

IntentWhat it doesResult in AgentViewTypeScript · Go
Start recordingBegin recording the current call.callUpsertstartRecording(id) · StartRecording(id)
Stop recordingStop recording.callUpsertstopRecording(id) · StopRecording(id)
Flag recordingToggle the "flagged" tag on the recording.callUpsertflagRecording(id) · FlagRecording(id)
Set recording tagsReplace the recording's tags.callUpsertsetRecordingTags(id, tags) · SetRecordingTags(id, tags)

Recording: gate these on AgentView.agent.canRecord. The call's recording flag, recordingId, recordingTags, and recordingFlagged reflect the current state; pick tags from agent.availableTags. When agent.alwaysRecordOutbound is set, outbound calls record automatically — and placeCall's record option starts recording from answer without a separate startRecording.

Conferencing

IntentWhat it doesResult in AgentViewTypeScript · Go
Start conferenceOpen a conference around a call.conferenceUpsertstartConference(hold?, callId?) · StartConference(hold, callID?)
Add memberInvite an agent or a number.conferenceUpsertaddConferenceMember(opts) · AddConferenceMember(agentID, number, holdOthers, displayAs, callID?)
Kick memberModerator removes a member.conferenceUpsertkickConferenceMember(id) · KickConferenceMember(id)
Hold memberModerator holds / unholds a member.conferenceUpsertholdConferenceMember(id, on) · HoldConferenceMember(id, on)
Mute memberModerator mutes / unmutes a member.conferenceUpsertmuteConferenceMember(id, on) · MuteConferenceMember(id, on)
End conferenceModerator ends the whole conference.conferenceRemoveendConference() · EndConference()
Leave conferenceHang up only your own leg.conferenceUpsert / conferenceRemoveleaveConference(callId?) · LeaveConference(callID?)

Conferencing: the agent who calls startConference becomes the moderator — gate the moderator-only controls (kick / hold / mute member, end) on Conference.iAmModerator. Each member is an agent or an external number with its own state and onHold; endConference finishes it for everyone, while leaveConference drops only your own leg. startConference opens the conference around your current call (you need an active call, or it's rejected with no_call); its hold flag parks that call while you add members and consult before bridging them together. You don't have to call it explicitly: addConferenceMember starts a conference for you if none is active, and that auto-start parks the current call on hold — which is why a warm transfer is just addConferenceMember(target) then transfer, with no separate startConference.

Which call? startConference, addConferenceMember and leaveConference all take an optional call id — the call the command addresses, matching mute/hold/transfer. Omit it and the SDK names the active call, which is what the server assumed before the field existed; pass it when the agent has more than one call attached, or the server has nothing to disambiguate on.

Messaging (SMS)

IntentWhat it doesResult in AgentViewTypeScript · Go
Send SMSSend a message; optionally a from and CTI session.smsUpsertsendSms(to, text, opts?) · SendSms(to, text, from, session)
Set conversation openOpen or close (resolve) a thread.smsUpsertsetConversationOpen(id, open) · SetConversationOpen(id, open)
Mark conversation readClear the unread count on a thread.smsUpsertmarkConversationRead(id) · MarkConversationRead(id)

SMS from & session: from is the sending number (which of your numbers the message goes out from); session attaches opaque CTI correlation — the same data the embed bridge sets via session.set.

Sending is the same operation on either surface: the sendSms command and POST /v1/agent/sms send the identical message, and the unary REST form returns the upserted SmsConversation summary directly.

Reference data (unary — not intents)

These are request/response calls, not stream intents: they fetch reference data and return it directly, without producing a patch. They're also the operations exposed over REST/OpenAPIGET /v1/agent/history, GET /v1/agent/sms/thread, and GET /v1/agent/phonebook (plus GET /v1/agent/state for the snapshot and POST /v1/agent/sms to send a message), each with the same bearer token (see Authentication).

OperationWhat it returnsTypeScript · Go
Get historyRecent call records (paged).getHistory(max=50, page=1) · GetHistory(ctx, max, page)
Get SMS threadMessages in one conversation (paged).getSmsThread(id, max=50, page=1) · GetSmsThread(ctx, id, max, page)
Get phonebookContact entries (paged, searchable).getPhonebook(max=200, page=1, query='') · GetPhonebook(ctx, max, page, query)

Paging is 1-based offset paging: pass max (page size — default 50, or 200 for the phonebook) and page (default 1). The responses carry only the list — there's no total or hasMore — so you've reached the end when a page returns fewer than max items (or none). getPhonebook also takes a query to filter contacts server-side.

// Fetch every page — there's no total, so stop on the first short page.
async function allHistory(pageSize = 50) {
const out = [];
for (let page = 1; ; page++) {
const batch = await bc.getHistory(pageSize, page);
out.push(...batch);
if (batch.length < pageSize) return out; // a short (or empty) page is the last one
}
}

The Go pattern is identical — loop GetHistory(ctx, max, page) (or GetSmsThread / GetPhonebook), incrementing page until a call returns fewer than max records.

SMS thread: getSmsThread's id is normally the SmsConversation.id, but it also accepts the peer's phone number — handy for opening a thread for a contact before any conversation exists yet. Messages come back oldest-first, ready to render top-to-bottom. (markConversationRead and setConversationOpen need the actual conversation id, though — only getSmsThread takes the peer.)

History entries (CallRecord) carry an id, direction, from / to (with a contact phonebook label when known), time (unix seconds), durationMs (call length in milliseconds), and hasRecording + a recordingUrl for playback (set only when hasRecording).

Phonebook is also available without a fetch: AgentView.agent.phonebook is a register-time snapshot (dial-from contacts + recent numbers). Each PhonebookEntry is just a label + number, where label is the contact name — or the literal "recent" for a recently-dialed number, so you can separate the two in the UI. Use getPhonebook for a paged, searchable refresh.

See also