Work the Parked Calls lobby
Call park is the classic operator hand-off: put a live caller into a numbered slot, tell a teammate which slot to pick up, and they retrieve the call from their own phone. The Parked Calls page under Voice is the shared lobby where every operator sees the live parked calls, with a retrieve and a release action on each row. Park is one of four control-plane endpoints over the tenant’s voice API. Use it when a call must move between people or devices without a conference bridge — the caller hears hold music, the first retrieval at any phone wins, and the slot frees for the next hand-off.1. Park slots and the four endpoints
Your organization gets nine shared slots, numbered 1 through 9. A park puts one live call on one slot; the caller hears hold music until someone retrieves the slot or the call hangs up. Retrieve and release are one-stroke claims — the first succeeds and every later attempt returns a clear error instead of a race.
Two operators parking into the same slot within milliseconds resolve
through a single occupancy check — the first succeeds, the second
receives a
409 PARK_SLOT_OCCUPIED with the occupant’s slot, caller,
and elapsed time. The PARK_… error codes are mapped to fixes in
Troubleshooting: voice call park orbit.
2. Worked responses for every endpoint
Every call below is tenant-scoped under/api/v1/voice/park — the
Voice API reference covers the shared base path
and auth headers; the body-level diagnosis for each PARK_… code lives
in the voice call park troubleshooting catalog.
List live parked calls — GET /api/v1/voice/park
cURL
200
parkedForSeconds badge, so a lobby client never
re-computes elapsed time client-side.
Park a live call — POST /api/v1/voice/park
cURL
slot and the park auto-picks the lowest free slot (the same
digits a desk phone dials with *N). Send "slot": 4 when the
operator named a number deliberately.
201
201 carries the picked slot so the client goes straight to the
“Parked on slot 3” toast. If all nine slots are occupied, the park
returns 409 PARK_SLOTS_FULL with the occupied-slot list:
409
Retrieve a parked call — POST /api/v1/voice/park/retrieve
cURL
200
retrievedAt and
releaseReason flip in one write and the slot frees for the next
park. A retrieve against a slot nobody ever parked is a 404 PARK_SLOT_EMPTY.
Release a parked call — POST /api/v1/voice/park/:id/release
Release frees the slot without bridging the caller back. The
:id is the park_… id from the list row, not the slot number.
cURL
200
3. Collision envelopes — 409, 410, and 403
Park’s concurrency primitives push the race decision to the client:
every live claim is one-stroke, and the losing attempt gets a body
that names the winner. These shapes drive the retry / different-slot
logic in a client, so they are shown in full.
409 PARK_SLOT_OCCUPIED — park into a taken slot
A named slot in the park body that collides returns 409 with the
current occupant’s slot, caller, and elapsed hold time — enough to
re-park on a different slot or point the operator at the winner.
409
slot in the body) never collides — it claims the
lowest free slot in one transaction. This 409 only fires when the
operator deliberately named a slot number.
410 PARK_ALREADY_RETRIEVED — retrieval race
Two operators retrieving at the same moment resolve to one claim:
the winner gets 200 and the loser gets 410 with the winning
claim’s full view (including retrievedByUserId) — safe to treat as
taken instead of a failed call-flip.
410
:id flips 410 PARK_ALREADY_RELEASED with the same { "prior": {…} } contract, and an unknown id is 404 PARK_NOT_FOUND:
410
403 INSUFFICIENT_PERMISSIONS — role guard
Every endpoint in this surface is gated server-side by the same role
list the lobby page displays — owner, admin, developer, agent. A
viewer or observer token is refused before any body validation:
403
4. Polling the lobby — SDK pattern
The dashboard polls/voice/park every ten seconds and renders each
row. A light client does the same through the SDK’s generic
orbit.request() helper — the only client-side surface on this page,
so this is the one sample that matters.
Node.js
409 re-parks on a different
slot (or gives up), a 410 drops the row from the local list.
5. Who can act on a parked call
Parked rows carry the caller’s number and display name — a PII-bearing surface. The lobby and every control-plane action are restricted to owner, admin, developer, and agent roles (the dashboard page mounts a role guard showing the role you need; the API routes enforce the same guard server-side). Viewer and observer roles see nothing on the lobby. If you only expect to supervise, take the read path: the GET list is a read guard, so a role with read-only permission on parked calls still cannot park, retrieve, or release.Every park, retrieve, and release writes an audit event with the
operator, the slot, and the caller’s E.164 number. The audit log is the
record of who claimed a held caller.
6. Park from the active call, retrieve from the lobby
Parking starts on the active-call surface; the lobby is where the row lands.- Answer the caller from the browser softphone or your registered device. The active-call surface shows a Park action.
- Click Park. The softphone sends
POST /api/v1/voice/parkwith the call SID and auto-picks the lowest free slot — the toast naming the slot number (for example “Call parked — slot 3”) is the confirmation. To place a specific slot, the same call carries aslotfield when you pick one explicitly. - Open Voice → Parked Calls. The new row appears within one poll cycle (the list refreshes every ten seconds) with the slot number, the caller’s number and name, and a live “parked for” counter.
- Any teammate retrieves the caller by clicking Retrieve on the
row — or by dialing
*Nfor the slot number on any registered device. The first retrieval wins; the row drops off every operator’s lobby on the next poll.
7. Slot naming and collision conventions
Agree on the naming discipline with the team before parking:- Auto-pick is the default. Leave the slot field blank and park
slots claim the lowest free number (the same digits a desk phone
dials with
*N). Team muscle memory stays consistent — the numbers mean “next free slot,” not “my slot.” - Named slots are for deliberate placement. When a receptionist says
“Mr Santos is on 2,” the number is the message. Pick the slot explicitly
and the occupant’s
409response carries the info needed to re-park elsewhere. - Never let auto-pick hide a collision. A
409on a named slot means another operator claimed it first — the response also carries on the occupant view the parked-at time and the caller info, so name the free slot and re-issue rather than retrying the same slot.
8. Hold and abandon discipline
The nine slots are a shared, finite lobby. Every row carries a running elapsed counter the whole floor sees, so a parked call that goes unanswered for minutes is visible to everyone — that is the abandon signal to act on before the caller hangs up. Decide the team’s longest-hold window (for example, two minutes). When a row crosses it, one of three things should happen:- Retrieve the row — the slot frees normally.
- Release the row — when retrieval would mean an abandoned call is dropped anyway; confirm the destructive action.
- Route inbound into a queue instead — if the same caller would have waited in a queue, the queue’s SLA and abandon metrics own the recording; park is the wrong surface for that flow.
9. Worked example — the receptionist’s hand-off
Acme’s receptionist covers the main number from a browser softphone.- A caller asking for Billing lands on the desk. The receptionist answers, speaks to the caller, and clicks Park — auto-pick claims slot 4.
- The toast reads “Call parked — slot 4”; the receptionist tells the billing specialist “Billing on 4.”
- The specialist opens Voice → Parked Calls, clicks Retrieve
on the row for slot 4 (or dials
*4from a desk phone); the first attempt bridges the caller and frees the slot. - While the specialist talks, the ticket the team keeps for this
caller updates as the parked row’s
parkedForSecondsshows the elapsed hold time — the lobby is the ground truth for “how long has this caller been on hold?”
410 PARK_ALREADY_RETRIEVED naming the retriever — safe to
treat the claim as taken (see Troubleshooting).
10. When NOT to use park
Park is a per-slot, team-visible lobby — not a queue, and not a warm transfer.- Inbound volume belongs on a queue. A queue holds hundreds of callers in FIFO order with SLA metrics; park holds nine total live calls against the team. Route inbound numbers to a voice queue and park only for hand-offs the queue cannot dispatch.
- A known teammate belongs on a transfer. Blind-transfer targets a named extension with a single click through the attendant console — park is for the “anyone can grab this caller” pattern, not a directed hand.
- Warm hand-off belongs on a conference. When the specialist must hear who is on the line first, use a warm transfer or the conference bridge — never park, since there is no announcement step before the retrieve claim.
See also
- Voice API reference — the generic voice surface (calls, SIP trunks, IVR, conferences) the four park endpoints extend
- Troubleshooting: voice call park — the full
PARK_…error catalog and slot-state diagnosis - Paging, ring groups & call park — the three sibling group-distribution primitives
- Attendant console guide — the four-panel operator workspace that carries the shared lobby panel
- Voice queues — the ACD path inbound volume belongs on