Call control
Tring has two control paths:
| Path | Who uses it | Auth | Controls |
|---|---|---|---|
| Agent SDK | The agent’s browser | Agent token | The agent’s own call |
| Backend REST | Your server | Tenant API key | Any call of the tenant, by id |
Supervision (listen, whisper, barge) is console-only. Each action is scoped to one tenant; an agent can never act on someone else’s call.
From the agent SDK
Section titled “From the agent SDK”The agent widget shows Hold, Transfer, mute and keypad buttons. With the JavaScript API, the active call object exposes the same actions:
call.hold(); // customer hears hold music, agent is mutedcall.resume(); // back to the conversationcall.transfer({ toTeam: "billing" }); // or { toSip: "crm-user-22" }These are messages on the call’s /rtc socket, handled by the gateway. No API key and no backend proxy are involved.
Hold and resume
Section titled “Hold and resume”- Hold: the agent’s microphone is muted in the browser, the tenant’s hold music is played to the other party, and the agent hears neither the music nor the customer.
- Resume: the music stops and audio flows both ways again.
If the tenant has no playable hold-music file, the held party hears silence. See Sounds and hold music.
Blind transfer
Section titled “Blind transfer”transfer takes exactly one target: toSip (another agent’s sip_username) or toTeam (a team name).
- The gateway checks the target first. If it is unreachable now (agent offline or busy, team with nobody available), or the agent names themselves, the transfer is rejected with
transfer-failedand the agent keeps the call. - Otherwise the agent gets
transfer-okand leaves the call immediately (blind transfer). The customer stays connected and hears hold music. - The routing engine rings the target into the same call, with the team’s strategy and queue if it is a team (see Agents and routing).
- If nobody answers, the customer hears the tenant’s transfer failed message (Settings, or
transfer_failed_messageonPATCH /v1/tenants/me, synthesized to speech when saved), then the call ends.
Only one transfer can run per call at a time. The transfer is recorded on the call’s timeline.
The widget’s target picker lists online, available agents (by name) and all teams from GET /v1/sdk/transfer-targets, called with the agent token.
Attended (consult) transfer and conferencing are not available yet.
Keypresses from the widget’s keypad go to the call’s IVR (for menus and gathers), on the same socket.
From your backend
Section titled “From your backend”# Put a call on hold, then resume itcurl -sS -X POST https://api.example.com/v1/calls/<call-id>/hold \ -H "Authorization: Bearer $TRING_API_KEY"curl -sS -X POST https://api.example.com/v1/calls/<call-id>/resume \ -H "Authorization: Bearer $TRING_API_KEY"The call must be answered (else 409). Hold plays the tenant’s hold music, or FreeSWITCH’s built-in music, into the customer’s leg on FreeSWITCH. Response: {"id": "<call-id>", "held": true}.
The agent-token REST endpoints POST /v1/sdk/calls/hold, POST /v1/sdk/calls/resume and POST /v1/sdk/calls/transfer ({"to_sip": …} or {"to_team": …}) do the same on the agent’s own newest answered call, resolved from the token. A team transfer through this path rings all reachable members at once. See the Calls API.
Supervision
Section titled “Supervision”A console user with the supervise permission can join a live call silently and switch modes. This works on web, phone and WhatsApp calls: any call whose audio runs through the gateway, including click-to-calls placed with POST /v1/calls and POST /v1/calls/connect.
| Mode | Supervisor hears | Who hears the supervisor |
|---|---|---|
monitor |
Everyone | Nobody |
whisper |
Everyone | The agent only |
barge |
Everyone | Everyone |
- From the live calls list, the console calls
POST /v1/calls/{id}/supervise. This endpoint accepts only a console session, never an API key, because the permission belongs to a user. The call must be live (ringingoranswered) and have a media room. - Tring returns a single-use supervisor token (2 minutes) pinned to that call’s room, plus
gateway_urland ICE servers. - The console joins in
monitorand can switch modes. The agent’s widget shows that a supervisor is present, with the mode and name.
On a phone call, a supervisor can listen from the IVR onwards, before any agent has answered. An agent who answers later is shown the supervisor and hears a whisper already in progress. The phone caller never hears a supervisor in monitor or whisper.
Barge on a phone call needs the gateway to mix the agent’s and the supervisor’s audio into the one stream the caller receives. The tring image does this: it is built with libopus (-tags opus). A binary built without it, such as go run ./cmd/tring, logs a warning on barge, and the caller hears one of them at a time.
Every session is audited (who, which call, when, which modes) and appears on the call’s timeline. The first console admin created at bootstrap has the supervise permission; other users do not by default.