Skip to content

Human agents and queues

MoreVoice isn’t only AI. It is also a cloud contact centre: your people answer and place calls in the browser, in the agent workspace, and queues share incoming calls between them. The AI can answer first and hand over to a queue, or take the calls nobody could answer. Over the API you invite the people, build the queues, send calls to them, watch the floor live, act on agents’ calls, and work the callbacks people asked for.

Object ID What it is
User usr_… A member of your organisation who signs in to MoreVoice: an agent, a supervisor, an admin or the owner.
Team team_… A group of users. Queues and reports can address a whole team.
Queue q_… Callers waiting for a human agent, and the rules for who answers, how long callers wait and what happens then.
Agent status A user’s presence right now: available, busy, in wrap-up, away or offline.
Callback cb_… A request to call someone back, and its progress.

Users, teams and queues are configuration: test keys and live keys see and change the same ones (the objects’ livemode only echoes the key). Agents answer calls in the browser, in the Agent workspace; the help centre shows them how.

A user joins your organisation by accepting an invitation. Invite them with the role and team they should have:

Terminal window
# Invite an agent into the Support team. The invitation is emailed; it is valid for 7 days.
curl https://api.morevoice.ai/v1/invitations \
-H "Authorization: Bearer $MOREVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "yossi@example.com",
"role": "agent",
"team_id": "'"$TEAM_ID"'"
}'
  • The invitation is emailed; the API never returns the link. It is valid for 7 days, and POST /v1/invitations/{id}/resend emails a new one.
  • A seat is reserved for each open invitation: 402 plan_limit when your plan has none free.
  • API keys invite and manage agents and supervisors. Owners and admins are made by an owner, in the dashboard.
  • Someone who already has a MoreVoice account (in another organisation) joins with it: existing_user is true.

Then manage people with /v1/users and /v1/teams: PATCH /v1/users/{id} changes a user’s role, team_id or extension; DELETE /v1/users/{id} deactivates them (they are signed out, their seat is freed and their open callbacks go back to their queue), and POST /v1/users/{id}/reactivate brings them back. POST /v1/teams creates a team; deleting one leaves its members in no team.

Only name is required; everything else takes the defaults shown on the queue object. This one shares calls between a team’s agents, tells callers their place in line, offers a callback, and hands the call to the AI when nobody can take it:

Terminal window
# A support queue: the team's agents answer, callers hear their place in line, can press 1 for a callback,
# and after 3 minutes (or when no agent is signed in) the AI assistant takes the call.
curl https://api.morevoice.ai/v1/queues \
-H "Authorization: Bearer $MOREVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Support",
"member_team_ids": ["'"$TEAM_ID"'"],
"strategy": "longest_idle",
"ring_timeout_seconds": 20,
"max_wait_seconds": 180,
"wrap_up_seconds": 15,
"overflow": { "when_no_agents": true, "action": "assistant", "assistant_id": "'"$ASSISTANT_ID"'" },
"hold": { "audio": "music", "announce_position": true, "position_interval_seconds": 45 },
"wait_keys": { "callback": "1" },
"callbacks": { "route": "agent_queue", "priority": 6 }
}'
Field What it does
member_user_ids, member_team_ids Who answers: users, whole teams, or both.
strategy longest_idle rings the agent who has waited longest since their last call; round_robin takes turns.
ring_timeout_seconds How long one agent’s phone rings before the next agent is tried (5–120).
max_wait_seconds How long a caller waits before the overflow action (0: no limit; up to an hour).
wrap_up_seconds After-call time before an agent gets the next call (0–600).
away_on_missed An agent who misses a call is set to away, so callers aren’t offered to an empty desk.
overflow What happens after max_wait_seconds, or at once when when_no_agents and nobody is signed in: assistant (the AI answers), voicemail, busy, agent, queue or number, with the matching assistant_id, user_id, queue_id or number.
hold What callers hear: music, ringback, silence, or asset (a recording you uploaded, audio_asset_id), plus an announcement and their place in line every position_interval_seconds.
wait_keys Keys a waiting caller presses to leave a voicemail or ask for a callback (empty: off).
callbacks Who returns the callbacks asked for in this queue: its agents (agent_queue), one agent, or an assistant, and their priority.
copilot_profile_id The copilot profile agents get on this queue’s calls.

PATCH /v1/queues/{id} changes a queue: nested objects (overflow, hold, callbacks…) merge with the stored values, and lists replace them. The change applies to the next call at once. Deleting a queue sends its waiting callers to overflow, and inbound routes that targeted it stop doing so.

  • Inbound. Give an inbound route a queue target: { "type": "queue", "queue_id": "q_…" }.
  • From the AI. An assistant or a flow hands over with its transfer step, or you transfer a live AI call yourself: POST /v1/calls/{id}/transfer with { "to": { "queue_id": "q_…" }, "note": "…" }. The agent sees your note next to the call. See outbound calls.
  • From an agent. An agent’s call can be transferred to another queue, cold or warm: see below.

Your endpoints follow every queued call: queue.call_entered (with its position), then queue.call_answered (agent_id, wait_ms), queue.call_abandoned when the caller hangs up first, or queue.overflowed. The call object keeps queue_id, and agent_id once an agent took it.

GET /v1/queues/{id}/live is the queue right now: who is waiting and for how long, the members who are signed in by status, and today’s numbers, including the service level (the share of calls answered within 20 seconds):

Terminal window
# The queue right now: who waits, which agents can take them, and today's numbers.
curl https://api.morevoice.ai/v1/queues/$QUEUE_ID/live \
-H "Authorization: Bearer $MOREVOICE_API_KEY"

GET /v1/agents/{id}/status is one agent’s presence, the call they are on, and the queues they answer:

Terminal window
# Your agents, then one agent's presence: available, busy on a call, in wrap-up, away or offline.
curl "https://api.morevoice.ai/v1/users?role=agent&status=active" \
-H "Authorization: Bearer $MOREVOICE_API_KEY"
curl https://api.morevoice.ai/v1/agents/$USER_ID/status \
-H "Authorization: Bearer $MOREVOICE_API_KEY"
status Meaning
available Signed in and ready: queue calls ring them. Chosen by the agent.
busy On a call.
wrap_up Finishing the last call (wrap_up_until); no new calls until then.
away Signed in, not taking calls: chosen by the agent, or set after a missed call.
offline Not signed in.

The agents set their own status in the workspace; the API reads it. agent.status_changed and agent.wrapup_completed push the changes, so a wallboard or a workforce tool doesn’t have to poll.

While an agent is on a call, your code can do what the agent’s call controls do: from a CRM button, a supervisor tool or an automation. Each action returns or changes the call’s control state: who is on the call, whether the customer is on hold, and any consultation in progress.

Action Request On
Put the customer on hold, or take them off POST /v1/calls/{id}/hold with on Agents’ calls
Send DTMF tones (to navigate another company’s IVR) POST /v1/calls/{id}/dtmf with digits (, pauses) Agents’ calls
Transfer to a queue, a number, an assistant or another agent, cold or warm POST /v1/calls/{id}/transfer Agents’ calls; AI and IVR calls to a queue or a number
Finish a warm transfer: complete, merge (three-way), swap or cancel POST /v1/calls/{id}/consult/{action} Agents’ calls
Ring someone into the call (up to 8 people), or add an assistant POST /v1/calls/{id}/participants Agents’ calls
Mute, hold or promote a participant; remove one PATCH / DELETE /v1/calls/{id}/participants/{participant_id} Agents’ calls
Read the control state GET /v1/calls/{id}/control Every call
End the call for everyone POST /v1/calls/{id}/hangup Every call

A warm transfer puts the customer on hold while the agent talks to the target, then hands the customer over:

Terminal window
# A warm transfer on an agent's call: the agent talks to a colleague first while the customer holds…
curl https://api.morevoice.ai/v1/calls/$CALL_ID/transfer \
-H "Authorization: Bearer $MOREVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": { "agent_id": "'"$COLLEAGUE_ID"'" },
"mode": "warm",
"note": "Billing question on invoice 1042"
}'
# …then hands the customer over (or "merge" for a three-way call, "cancel" to go back to the customer).
curl -X POST https://api.morevoice.ai/v1/calls/$CALL_ID/consult/complete \
-H "Authorization: Bearer $MOREVOICE_API_KEY"

Adding a participant rings them in and starts a conference; the new participant is ringing until they answer, so follow them in the control state:

Terminal window
# Ring an expert's phone into an agent's call, then see who is on the line.
curl https://api.morevoice.ai/v1/calls/$CALL_ID/participants \
-H "Authorization: Bearer $MOREVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": { "number": "+97235551234" },
"announce": "Joining you to a customer call about a claim"
}'
curl https://api.morevoice.ai/v1/calls/$CALL_ID/control \
-H "Authorization: Bearer $MOREVOICE_API_KEY"

An action that doesn’t fit the call answers 409: unsupported_for_call_mode (hold on an AI call, say; details.call_type names the kind of call), call_not_active once the call has ended, or transfer_failed when the target couldn’t take it (the call continues). Calls to numbers you add pass the compliance gate like any outbound call.

Callers who press the callback key while they wait, voicemails left in a queue (with voicemail_to_callback), your website’s callback form, the AI and your own code all fill one callbacks inbox. A callback routed to a queue is offered to its next free agent, who calls back from the workspace; the inbox tracks attempts, notes and an SLA target in business hours.

Terminal window
# Callbacks waiting for the Support queue's agents, then close one that was resolved another way.
curl "https://api.morevoice.ai/v1/callbacks?status=pending&queue_id=$QUEUE_ID" \
-H "Authorization: Bearer $MOREVOICE_API_KEY"
curl https://api.morevoice.ai/v1/callbacks/$CALLBACK_ID/complete \
-H "Authorization: Bearer $MOREVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "note": "Answered by email" }'
  • Create one with POST /v1/callbacks: route is agent_queue (with queue_id), agent (with agent_id) or assistant (the AI calls back; see outbound calls).
  • Work it: PATCH reschedules or reassigns, POST …/notes adds a note, POST …/complete closes it when it was resolved another way, POST …/cancel drops it.
  • Measure with GET /v1/callbacks/stats: totals, how many were returned within their SLA, the average time to return, by source and by agent.
  • Events: callback.scheduled, then callback.completed, callback.failed or callback.cancelled.