SiteCallDevelopers

Call center

Queues, agents and live calls.

Agents are SiteCall members or your application users. Queues hand callers to the longest-idle agent with the right skills; your application, a supervisor or the agent controls each live call.

Queues

POST /api/v1/queues creates one (scope routing:*). Members carry skills and a priority (lower wins a tie between equally idle agents); a queue's requiredSkills filter who is offered its calls. maxWaitSecs bounds the wait (a plan's queue step overflows after it), wrapUpSecs gives an agent time after each call, and awayOnMiss sets an agent away after a missed offer. The service-level target (answerTargetSecs, default 20 s, and serviceLevelGoalPct, default 80) feeds team metrics. Route callers into a queue with a plan's queue step.

Agents and their states

StateSet by
offlineThe agent, a supervisor or your application
availableThe agent, a supervisor or your application
offeredSiteCall (an offer, a call, wrap-up)
on_callSiteCall (an offer, a call, wrap-up)
wrap_upSiteCall (an offer, a call, wrap-up)
awayThe agent, a supervisor or your application

GET /api/v1/agents lists members and active application users (kind, externalUserId) with their live state. PUT /api/v1/agents/{memberId}/state { "state": "available" } asks for a state: a member sets their own with calls:*; setting anyone else's, including with your application key, needs calls:supervise. System states (on_call, wrap_up) stay until the call or wrap-up ends. Every change is an agent.state_changed event.

The answer is { memberId, changed, state, previous }, plus one of two flags. deferred: true: you asked an agent who is ringing or on a call to go away or offline; it applies when the call (and any wrap-up) ends, so state is still the busy one, and a later available cancels it. stuck: true: the agent read as ringing or on a call with no live call or offer behind it, so the state you asked for applied at once.

Placing calls

POST /api/v1/calls/dial rings the agent's device first, then the destination. A token's own user or member is the agent; with your key, name it in agent. An application user dials only from the numbers you gave it (numberIds on POST /api/v1/users). Answering-machine detection is off unless machineDetection: "premium".

const placed = await sitecall.calls.dial({
  to: "+15125550123",
  from: { phoneNumberId },
  agent: { externalUserId: "user-7" },
});
// placed.callId; progress arrives as call.* events

The call id is callId if you send one, else derived from the Idempotency-Key, and every refusal after it is fixed carries callId beside the error: a retry after a 503 with the same key is the same call. Refusals include caller_id_forbidden, invalid_destination, destination_blocked, agent_unreachable and emergency_location_required (see E911).

Controlling a live call

Hang up, transfer, hold, resume and swap take your key, a member's token, or an application user's token (acting with the role you gave it). Each answers 202 once the engine has the command (200 for a repeat of the same command); the outcome arrives as events.

OperationBodyNotes
POST /calls/{id}/hangupnoneEnds the call.
POST /calls/{id}/transfer{ target, warm? }target is { e164 }, { queueId } or { memberId }; blind unless warm.
POST /calls/{id}/holdnoneThe remote party hears hold audio; so does the agent's leg, so hold that leg locally too.
POST /calls/{id}/resumenoneHolds the device's other call first: one active leg per device.
POST /calls/{id}/swapnoneSwaps the device's live and server-held calls.

Only server holds count for resume and swap: a hold the phone does on its own leg is not server state. A 409 device_busy means a call on the device cannot be held right now (mid transfer, still being set up); nothing changed.

Supervision

POST /api/v1/calls/{id}/supervise (scope calls:supervise, your key or a member's token) dials a supervisor in with role monitor (listen), whisper (the agent hears them) or barge (everyone does). A member's token dials in that member; your key names supervisorMemberId and optionally a deviceId. With supervisorLegId an existing supervisor leg changes role in place.

Web devices take calls

A browser gets no push. While it is registered, it reads the calls ringing it from GET /api/v1/devices/{deviceId}/offers and answers with POST /api/v1/calls/{id}/answer { deviceId }: SiteCall hands the call to that device's WebRTC credential (POST /api/v1/credentials). @sitecall/web does all of this for you (Quickstart).

After the call