Put a LiveKit Agents voice agent, or an OpenAI Realtime agent, into a live meeting in a few minutes. Full reference: API documentation.
YOUR_ROOM_ID.export MEETINGBURNER_API_KEY=your_meetingburner_key # Settings → Developer
export OPENAI_API_KEY=your_openai_key # from your OpenAI accountSpeech-to-text, a text model and text-to-speech, wired by the LiveKit Agents framework. Swap any of the three for another LiveKit plugin you prefer. Install with pip install "livekit-agents[openai,silero]~=1.2" httpx.
"""A LiveKit Agents voice agent in a MeetingBurner meeting.
pip install "livekit-agents[openai,silero]~=1.2" httpx
Set MEETINGBURNER_API_KEY and OPENAI_API_KEY in your environment first.
Join the meeting yourself, then run: python agent.py
"""
import asyncio
import os
import httpx
from livekit import rtc
from livekit.agents import Agent, AgentSession
from livekit.plugins import openai, silero
INSTRUCTIONS = "You are a meeting assistant. Speak only when addressed by name, and keep it short."
MEETINGBURNER_API = "https://meetingburner.com/api/v1"
ROOM_ID = "YOUR_ROOM_ID" # the last part of the meeting link
async def join_meeting(http: httpx.AsyncClient) -> dict:
"""Ask MeetingBurner for a pass. Waits until you are in the meeting yourself."""
while True:
response = await http.post(
f"{MEETINGBURNER_API}/bots/join",
json={
"roomId": ROOM_ID,
"botName": "My Assistant",
"capabilities": ["listen", "speak"],
"purpose": "Answers questions when someone asks it by name",
"waitForOwner": True,
},
)
if response.status_code == 202: # you have not joined yet
await asyncio.sleep(response.json()["retryAfterSeconds"])
continue
response.raise_for_status()
return response.json()
async def run_in_meeting(build_session) -> None:
headers = {"X-API-Key": os.environ["MEETINGBURNER_API_KEY"]}
async with httpx.AsyncClient(headers=headers, timeout=30) as http:
join = await join_meeting(http)
room = rtc.Room()
ended = asyncio.Event()
room.on("disconnected", lambda *_: ended.set())
try: # from here on, always tell MeetingBurner the agent left
await room.connect(join["livekitUrl"], join["livekitToken"])
session = build_session()
await session.start(agent=Agent(instructions=INSTRUCTIONS), room=room)
await ended.wait() # until the meeting ends or you remove the agent
finally:
await room.disconnect()
await http.post(
f"{MEETINGBURNER_API}/bots/leave",
json={"connectionId": join["connectionId"]},
)
def build_pipeline_session() -> AgentSession:
return AgentSession(
vad=silero.VAD.load(),
stt=openai.STT(),
llm=openai.LLM(),
tts=openai.TTS(),
)
if __name__ == "__main__":
asyncio.run(run_in_meeting(build_pipeline_session))
One speech-to-speech model hears the meeting and answers in voice. The join and leave are the same as (a); only the session differs. Install with pip install "livekit-agents[openai]~=1.2" httpx.
"""An OpenAI Realtime voice agent in a MeetingBurner meeting.
pip install "livekit-agents[openai]~=1.2" httpx
Set MEETINGBURNER_API_KEY and OPENAI_API_KEY in your environment first.
Join the meeting yourself, then run: python agent.py
"""
import asyncio
import os
import httpx
from livekit import rtc
from livekit.agents import Agent, AgentSession
from livekit.plugins import openai
INSTRUCTIONS = "You are a meeting assistant. Speak only when addressed by name, and keep it short."
MEETINGBURNER_API = "https://meetingburner.com/api/v1"
ROOM_ID = "YOUR_ROOM_ID" # the last part of the meeting link
async def join_meeting(http: httpx.AsyncClient) -> dict:
"""Ask MeetingBurner for a pass. Waits until you are in the meeting yourself."""
while True:
response = await http.post(
f"{MEETINGBURNER_API}/bots/join",
json={
"roomId": ROOM_ID,
"botName": "My Assistant",
"capabilities": ["listen", "speak"],
"purpose": "Answers questions when someone asks it by name",
"waitForOwner": True,
},
)
if response.status_code == 202: # you have not joined yet
await asyncio.sleep(response.json()["retryAfterSeconds"])
continue
response.raise_for_status()
return response.json()
async def run_in_meeting(build_session) -> None:
headers = {"X-API-Key": os.environ["MEETINGBURNER_API_KEY"]}
async with httpx.AsyncClient(headers=headers, timeout=30) as http:
join = await join_meeting(http)
room = rtc.Room()
ended = asyncio.Event()
room.on("disconnected", lambda *_: ended.set())
try: # from here on, always tell MeetingBurner the agent left
await room.connect(join["livekitUrl"], join["livekitToken"])
session = build_session()
await session.start(agent=Agent(instructions=INSTRUCTIONS), room=room)
await ended.wait() # until the meeting ends or you remove the agent
finally:
await room.disconnect()
await http.post(
f"{MEETINGBURNER_API}/bots/leave",
json={"connectionId": join["connectionId"]},
)
def build_realtime_session() -> AgentSession:
return AgentSession(llm=openai.realtime.RealtimeModel(voice="alloy"))
if __name__ == "__main__":
asyncio.run(run_in_meeting(build_realtime_session))
If you host the meeting, open Settings → Invite your agent and copy the code. It works for this meeting only, once, within ten minutes, and the agent's time comes from your tokens. Set it as MEETINGBURNER_INVITE_CODE and run the file below: the same agent as (b), joining at /bots/join-with-code. To leave, it uses the connectionToken that join returns. If it drops, ask for a fresh code; a used code never works again.
"""An OpenAI Realtime agent that joins with a one-time MeetingBurner invite code.
pip install "livekit-agents[openai]~=1.2" httpx
Set MEETINGBURNER_INVITE_CODE (from "Invite your agent") and OPENAI_API_KEY first.
Join the meeting yourself, then run: python agent.py
"""
import asyncio
import os
import httpx
from livekit import rtc
from livekit.agents import Agent, AgentSession
from livekit.plugins import openai
INSTRUCTIONS = "You are a meeting assistant. Speak only when addressed by name, and keep it short."
MEETINGBURNER_API = "https://meetingburner.com/api/v1"
INVITE_CODE = os.environ["MEETINGBURNER_INVITE_CODE"] # one meeting, one use, ten minutes
async def join_meeting(http: httpx.AsyncClient) -> dict:
"""Ask MeetingBurner for a pass. Waits until you are in the meeting yourself."""
while True:
response = await http.post(
f"{MEETINGBURNER_API}/bots/join-with-code",
json={
"code": INVITE_CODE,
"botName": "My Assistant",
"capabilities": ["listen", "speak"],
"purpose": "Answers questions when someone asks it by name",
"waitForOwner": True,
},
)
if response.status_code == 202: # you have not joined yet
await asyncio.sleep(response.json()["retryAfterSeconds"])
continue
response.raise_for_status()
return response.json()
async def run_in_meeting(build_session) -> None:
headers = {} # no API key: the code is the whole credential
async with httpx.AsyncClient(headers=headers, timeout=30) as http:
join = await join_meeting(http)
room = rtc.Room()
ended = asyncio.Event()
room.on("disconnected", lambda *_: ended.set())
try: # from here on, always tell MeetingBurner the agent left
await room.connect(join["livekitUrl"], join["livekitToken"])
session = build_session()
await session.start(agent=Agent(instructions=INSTRUCTIONS), room=room)
await ended.wait() # until the meeting ends or you remove the agent
finally:
await room.disconnect()
await http.post(
"https://meetingburner.com/api/agents/disconnect",
headers={"Authorization": f"Bearer {join['connectionToken']}"},
)
def build_realtime_session() -> AgentSession:
return AgentSession(llm=openai.realtime.RealtimeModel(voice="alloy"))
if __name__ == "__main__":
asyncio.run(run_in_meeting(build_realtime_session))
LiveKit can start agents for you when a room opens, but only with the media server's own secret, which stays with MeetingBurner. So your agent runs as its own program and connects with the pass /bots/join gives it: livekitUrl and livekitToken. The pass works for this one meeting only. You pay your model provider directly; MeetingBurner never resells model time.
purpose and your name are shown to every person in the meeting. A join without a purpose is refused.A speaking agent is charged to your account at the voice rate, rounded up to whole tokens: a one-minute call costs 3 tokens, and 10 minutes cost 25 tokens. Your balance must cover the first minute before the agent is let in. Every rate is on Usage and Tokens.