We are making calls using LiveKit API, now our que...
# ask-ai
d
We are making calls using LiveKit API, now our question if a voice agent initiate the call from livekit but user didn't pick up or cancelled the call, would it still be counted as agent session and minute would be charged from Livekit?
t
Thanks for reaching out, Saurabh. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — regarding whether an outbound call that isn't answered or is cancelled counts toward agent session minutes: Yes. Once a voice agent is dispatched and connected to the outbound call flow (for example by creating a SIP participant and dialing), the agent is considered to be actively serving the user and the session starts. Agent session minutes begin accruing from that connection/dispatch time, even if the recipient never answers or cancels the call. If you’d like, tell me how you initiate calls (API flow or SIP setup) and I can point to the exact event/point in your flow where the session begins so you can minimize unwanted charges. Sources: Quotas and limits | LiveKit docs | Deploy and scale agents on LiveKit Cloud
d
We are initiating the call through Livekit API and third party SIP Trunk
t
Thanks — regarding calls you start via the LiveKit API + a third‑party SIP trunk: • Once your voice agent is dispatched and connected into the outbound call flow (for example when the agent creates the SIP participant and LiveKit establishes the call leg), that agent session is considered active and session minutes begin accruing. • That billing starts even if the callee never answers or cancels while the agent is still connected/waiting (for example during ringing). If you want, I can: • Identify the exact API call or event in your flow that marks session start so you can measure or gate billing, or • Suggest ways to minimize unwanted charges (examples: shorten ringing timeout, end the agent side earlier, or detect no‑answer before creating the SIP participant). Which would you prefer? Also share which API call or SDK flow you use to create the SIP participant so I can point to the precise step.
d
How to detect no‑answer before creating the SIP participant.
t
You're asking how to detect a no‑answer before creating the SIP participant so you don't start an agent session and incur minutes. You cannot detect no‑answer before creating the SIP participant. Instead use this approach to avoid starting agent sessions when calls go unanswered: 1. Create the outbound call with CreateSIPParticipant using wait_until_answered: true so the API call only returns when the callee answers (or fails/timeouts). 2. If the API returns success, the call was answered and you can proceed to attach the agent (start the agent session). 3. If the API returns an error or the
sip.callStatus
transitions to
hangup
without
active
, treat the call as no‑answer and do not create/attach the agent. 4. To handle voicemail being reported as answered by some carriers, add post‑answer checks (e.g., short‑speech detection or silence detection) before fully starting the agent session. If you want, share the exact API call/SDK flow you currently use and I’ll point to the precise field and code placement to implement this. Sources: SIP APIs | LiveKit docs | SIP participant | LiveKit docs | Agents telephony integration | LiveKit docs | How to detect and handle silence during calls
d
wouldn't these lead to delay in first audio by agent and latency?
t
You're asking whether using the no‑answer detection approach (e.g.,
wait_until_answered
) will introduce delay or latency to the agent's first audio. Short answer: No — it does not necessarily add user‑visible latency to the agent’s first audio, but it can affect when your backend knows the call was answered. Why: • The agent’s audio is produced from inside the LiveKit room, and the agent process can be started and publish audio as soon as the participant is created in the room. That means the agent can generate and send its first audio immediately (sub‑1.5s typical latency), independent of whether the SIP leg has answered yet. •
wait_until_answered
affects when the API call returns to your backend — not when the agent is able to speak in the room. Using
wait_until_answered: true
blocks the API response until the callee answers (or the call fails), but the agent can already be connected and play audio into the room while the SIP leg rings. Tradeoffs and things to consider: • Billing: starting the agent in the room begins agent session billing immediately, even if the callee never answers. Detecting no‑answer after the SIP attempt cannot prevent that initial agent-minute charge. • Perceived call experience: if you want the agent to speak only after a real person answers (to avoid playing greetings into voicemail), you should: ◦ Use
wait_until_answered: true
and then attach or enable the agent’s greeting only after the API returns success, or ◦ Start the agent early but gate the greeting with a short post‑answer check (e.g., voice activity/speech detection or short silence threshold) to avoid playing into voicemail. • Early media: some SIP trunks/carriers support early media (so the callee hears agent audio before the call is fully answered). Behavior varies by carrier; test with your trunk to confirm how early media is handled. • Latency mitigation: start the agent connection and warm up any TTS/ASR models and audio pipeline ahead of time so the first utterance is ready immediately once you choose to play it. If you want, tell me which behavior you prefer: • Always play the agent greeting immediately (risk playing into voicemail but lowest perceived latency), or • Only play after a confirmed human answer (avoids voicemail but may add the API/decision latency). Share your current API call/flow and I’ll point to the exact place to create/attach the agent or insert post‑answer checks. Sources: LiveKit Cloud billing | LiveKit docs | examples/frontdesk | livekit/livekit_composite | DeepWiki | sip | livekit/livekit_composite | DeepWiki | https://blog.livekit.io/introducing-livekit-phone-numbers-zero-to-ringing-in-60-seconds/#/portal| | LiveKit for Robotics
d
• Only play after a confirmed human answer (avoids voicemail but may add the API/decision latency).
t
You want the agent to play audio only after a confirmed human answer. Below is a concise, actionable plan with implementation options, tradeoffs, and a small code sketch to place the decision point. Recommended approach (lowest voicemail risk): 1. Dial with CreateSIPParticipant using
wait_until_answered: true
. ◦ The API call blocks until the callee answers (or fails), so your backend only proceeds when the call is answered. 1. On success, attach/start the agent in the room and immediately play the greeting. 2. On error or timeout, do not start/attach the agent — no agent session minutes will be started. Alternative approach (avoid blocking backend, still gate greeting): • Create the SIP participant without attaching the agent. Monitor
sip.callStatus
events: ◦ If
sip.callStatus
transitions to
active
, then attach the agent and play greeting. ◦ If it transitions to `hangup`/error, do nothing. • This avoids blocking your API call thread but requires event handling and a short window between
active
and agent attachment. Handling false-positives (voicemail detected as answered): • After
active
, run a brief post-answer check before playing the greeting: ◦ 2–4 seconds of speech/voice-activity detection (VAD) or simple energy/silence detection. ◦ Optional short TTS probe and listen for human response characteristics. • If probe suggests voicemail, hang up and avoid attaching the full agent session. Billing and latency notes: • Starting/attaching the agent begins agent session billing. Using
wait_until_answered: true
prevents attaching until answer — this avoids agent-minute charges but blocks the API call. • Attaching after
active
adds minimal delay (typically sub-second to a few seconds) before the first agent audio — acceptable if you warm up TTS/ASR and pre-create room resources. • Voicemail detection adds a small delay (2–4s) but reduces wasted agent minutes. Minimal code sketch (pseudo / placement):
Copy code
// Option: wait_until_answered
try {
  await livekit.createSIPParticipant({ to: callee, wait_until_answered: true });
  // call answered -> attach/start agent and play greeting
} catch (err) {
  // call failed or no-answer -> do not attach agent
}

// Option: event-driven
livekit.createSIPParticipant({ to: callee, wait_until_answered: false });
// listen for participant updates
onParticipantUpdate(participant) {
  if (participant.sip.callStatus === 'active') {
    // optional: run 2-4s VAD/probe to detect voicemail
    attachAgentAndPlayGreeting();
  } else if (participant.sip.callStatus === 'hangup') {
    // do nothing
  }
}
Which option do you prefer: blocking
wait_until_answered
(no agent attach until confirmed, simpler) or non-blocking event-driven with post-answer checks (more scalable, slightly more complex)? Share your current call flow code and I’ll point to exact fields/events to update.