pinecallDocs
Guides / Handing a call to a person

Handing a call to a person

Transfer the caller, or ask your team to take the line.

An agent can pass a caller to a colleague's number, or ask your team to join the conversation. You call both from a @tool of your own, and both tell your tool what really happened, so the agent knows what to say next.

How it works#

Handing off is two methods of this.call. Your tool decides when to call them, and the words the caller hears are the agent's.

Each method returns a value. When ok is false, nothing moved: the caller is still with the agent, and the string your tool returns is how the agent knows what to tell them.

transfer: the caller goes to a number#

agents/front-desk/agent.tsx
/** Pass the call to a person at the front desk. Use it when the caller asks to speak to someone. */
@tool({ timeout: 60 })
async transferToHuman(): Promise<string> {
  await this.say("I'll put you through to a colleague, one moment.");
  const done = await this.call.transfer("+34910000099");
  if (done.ok) return "The call went to a colleague. Say nothing more.";
  return "The transfer failed and the caller is still with you. Tell them, and keep helping.";
}

Announce the transfer first, and await the announcement. say resolves once the line has been spoken, so the caller hears it before the line moves.

What transfer does depends on where the caller is:

the caller is what happens afterwards
on a phone their line is sent on to the number (cold) the agent has left the call
in a browser the number is dialled into the call (warm); when it answers, the agent goes silent the call goes on with the two of them, until one hangs up
in a written conversation nothing: there is no line to send unchanged. Use attention instead

Leave mode out and the right one is used. Pass { mode: "cold" } or { mode: "warm" } only to insist; a mode the call cannot take is refused rather than swapped.

transfer returns { to, mode, ok, error }. A warm transfer dials out on the org's own carrier account, so it needs outbound calls turned on (Calling out). Every transfer leg also passes the org's dial limits: the number's shape, and how many calls the org placed this minute and today. When one refuses, nothing is dialled and error says which.

attention: a person joins the call#

agents/front-desk/agent.tsx
/** Ask for a person on the team to join the conversation. */
@tool({ timeout: 90 })
async askForAPerson(): Promise<string> {
  await this.say("Let me get a colleague, one moment.");
  const taken = await this.call.attention("refund outside the return window", { waitS: 60 });
  if (taken.ok) return "A person has joined the conversation. Say nothing more.";
  return "Nobody is free right now. Tell the caller, and carry on yourself.";
}

The caller waits: on hold with music on a call, unanswered in a written conversation. The console marks the call wants a person, puts it first in Calls, and shows the reason you passed. The ask settles when somebody takes the line, when waitS seconds pass with nobody, or when the caller hangs up. It returns { ok, by, error }, where by is the person who took it.

waitS has no default: how long your caller holds is your decision. Give the tool a timeout longer than waitS, or the tool gives up first and the model starts talking while the caller is still on hold.

While a person holds the line, the agent hears nothing and says nothing, and a tool that finishes in that time produces no reply. What the person does next is in Supervising a live call.

The rest of the line#

TypeScript
this.call.hold();              // hold music; the agent neither speaks nor listens
this.call.unhold();            // and back
this.call.dtmf("1,2#");        // touch tones for a menu at the far end; a comma is a pause
this.call.hangup("served");    // say goodbye first: nothing after this is heard

These return nothing. When one cannot happen, for example a hold in a written conversation, the call's log gets one error line saying why. callback and optOut are covered in Callbacks and Data & privacy.

What the log records#

entry written when
call.transferred a transfer settled, either way: to, mode, ok, error
attention.requested · attention.answered a person was asked for, and somebody came or nobody did
call.line the caller went on hold or came off it

Next steps#