Offer this call to another agent or a department
POST/api/calls/:callId/transfer
Hand a live call over (SES-1 F4 — devir). A transfer is a PROPOSAL with a deadline, not a hand-off that happens by itself, and the whole design follows from one promise: THE CUSTOMER IS NEVER SILENT AND NEVER OWNERLESS.
Order of operations, which is the feature and not an implementation detail:
- the customer is PARKED first — hold
reason: transfer, so they hear hold music while this is arranged — and the row says "held" only after the bridge confirms it. A bridge that cannot park anyone refuses the whole transfer with 501 rather than handing the customer to silence; - the target is rung through the SAME pipeline an inbound call uses (targeted push + banner), flagged as a transfer so a device can say who is handing it over;
- the call keeps belonging to the agent who answered it.
answered_bymoves only onaccept, in one conditional UPDATE, so two targets pressing at once produce one winner and one honest 409.
Every way the proposal can fail — declined, timed out, cancelled — leaves the call with the offering agent and the customer still parked.
Only the agent HOLDING the call may offer it: reply permission lets a colleague answer a ringing call, it must not let them push a live conversation onto someone else's phone.
Request
Responses
- 202
- 401
- 403
- 404
- 409
- 422
- 501
The customer is parked and the target is ringing. Accepted rather than OK because the hand-off has NOT happened yet — the call is still the offering agent's until somebody takes it.
Not authenticated. code: account_disabled means the member's seat was deactivated in this workspace: the session is over even though the token was not revoked (clients sign out and clean up).
The call is held by another agent (code: call_held_by_other) — only the agent who answered it may give it away.
No such call — or no such target. A target in ANOTHER tenant is invisible under row-level security and reads as "not found", so a user id cannot be probed across tenants.
call_not_active (only a connected call can be transferred) or transfer_in_progress (one offer at a time).
The transfer was refused BEFORE the customer was parked: transfer_target_required, transfer_to_self, transfer_target_not_permitted (that agent cannot work this conversation), transfer_target_unavailable (their phone would not ring), transfer_no_targets (nobody in that department is available) — or, after the park was attempted and failed, hold_failed, in which case nothing was written and the customer is still talking to the offering agent.
hold_unsupported — this bridge cannot park a customer, and a transfer must never leave them in silence — or consult_unsupported for the consultative mode.