Skip to main content
You create the room. The live-session call starts the Akapulu Labs worker. Your voice bot’s job is to send the assistant audio to that worker. The worker joins the call as a Daily participant and publishes the audio and the video. The voice bot does not publish audio or video.

1. Create the room

create_akapulu_call, from pipecat-akapulu, runs on your server, before the voice bot starts. It reads DAILY_API_KEY and AKAPULU_API_KEY. It creates a private Daily room for three participants: the user browser, your voice bot, and the Akapulu Labs worker. It mints the three meeting tokens and POST /api/live-sessions/. It returns the room URL, the bot token, the browser token, and session_id. The worker token is sent to Akapulu Labs and is not returned. The room lasts two hours unless you pass room_exp_secs. Daily removes everyone when the room expires. The browser joins as You. The worker joins as Avatar. Daily Prebuilt shows the browser and the avatar.
session is an aiohttp.ClientSession. The voice bot joins Daily with bot_token. The browser joins with browser_token. Pass session_id to AkapuluAvatar. A bot that already has a Daily room skips create_akapulu_call. Mint the Akapulu Labs worker’s meeting token and POST /api/live-sessions/ yourself.

2. Start the live session

This is the call create_akapulu_call makes. Use it yourself when the Daily room already exists. Put the Akapulu Labs worker’s meeting token in avatar_token. Your voice bot joins Daily with its token. The browser joins Daily with its token.
show_ai_label is a boolean. On success the response is:
The call returns when the session is stored and the Akapulu Labs worker has been asked to start. It does not wait for the first video frame.

Loading status

The AkapuluAvatar Pipecat plugin connects to the Akapulu Labs worker in the background. When the pipeline starts, it forwards StartFrame right away so your voice bot keeps moving. It does not wait for the first face frame. While the Akapulu Labs worker boots, the plugin pushes RTVI server messages into your voice-bot pipeline. Each message body has type status and these fields:
  • call_is_ready: whether the Akapulu Labs worker has published the first frame
  • completion_percent: how far startup has gotten (0 to 100)
  • latest_update_text: the latest human-readable startup line
Those are not Daily audio or video tracks. With RTVI on the call (for example @pipecat-ai/client-js in the browser), they arrive on the client as RTVI ServerMessage events over that same Daily connection. Use them for a loading spinner, percent, and copy. Keep the loading UI up until call_is_ready is true.

3. Put AkapuluAvatar in the pipeline

Install pipecat-akapulu. Put the AkapuluAvatar Pipecat plugin after your TTS (or whatever produces assistant audio). AkapuluAvatar sends that audio to the Akapulu Labs worker. The worker joins the call as a Daily participant and publishes the audio and the video. The voice bot does not publish audio or video, so audio_out_enabled and video_out_enabled stay False.
YourVoiceBotSTT, YourVoiceBotLLM, and YourVoiceBotTTS are stand-ins for your own STT, LLM, and TTS. Leave audio_out_enabled and video_out_enabled as False because the voice bot’s job is to send the assistant audio to the Akapulu Labs worker. The worker joins the call as a Daily participant and publishes the audio and the video. The voice bot does not publish audio or video. The worker starts the face only after a short stretch of assistant audio has arrived. Speech-to-speech models often reach that first audio quickly, then trickle, so the buffer fills slowly. A streaming TTS keeps the audio coming after the first chunk, which fills the buffer sooner. Cartesia has been the best mix we have tried: a low time to first audio, and audio that keeps arriving quickly enough to fill that buffer. Pipecat subscribes your voice bot to every remote microphone. When the participant named Avatar joins, turn that microphone off. The voice bot still hears the browser. The browser stays subscribed to the Avatar microphone. That track is the voice the visitor hears.
Call this once, when Avatar joins. Do not set subscriptions again on a participant update. The public example is akapulu-examples: a local server, a page, and a voice bot that speaks first.

Errors

When POST /api/live-sessions/ fails, the response JSON includes error and error_code. Branch on error_code. The codes are in the API overview.