Skip to main content
All interactive bot endpoints follow the pattern:
{METHOD} /bots/{platform}/{native_meeting_id}/{action}
Authentication: X-API-Key header (same as all Vexa endpoints).
Interactive bot endpoints are available by default (voice_agent_enabled defaults to true). To disable, pass voice_agent_enabled: false when creating the bot. See Bots API for the request format.
Interactive endpoints require an active meeting. For non-active meetings, they return:
{
  "detail": "No active meeting found for {platform}/{native_meeting_id}"
}
Most command endpoints return 202 Accepted with this shape:
{
  "message": "Speak command sent",
  "meeting_id": 220
}
message text varies by endpoint (for example, Chat message sent, Screen content command sent, Avatar set command sent).

Response Envelope (Codebase)

The backend implementation for these endpoints is in services/bot-manager/app/main.py and returns stable command acknowledgements:
EndpointStatusResponse
POST /.../speak202{"message":"Speak command sent","meeting_id":<int>}
DELETE /.../speak202{"message":"Speak stop command sent","meeting_id":<int>}
POST /.../chat202{"message":"Chat message sent","meeting_id":<int>}
POST /.../screen202{"message":"Screen content command sent","meeting_id":<int>}
DELETE /.../screen202{"message":"Screen stop command sent","meeting_id":<int>}
PUT /.../avatar202{"message":"Avatar set command sent","meeting_id":<int>}
DELETE /.../avatar202{"message":"Avatar reset command sent","meeting_id":<int>}
GET /.../chat200{"messages":[...],"meeting_id":<int>}

Speak (Text-to-Speech)

Make the bot speak in the meeting. The bot unmutes, plays the audio, then re-mutes.

POST /bots/{platform}/{native_meeting_id}/speak

Send text for the bot to synthesize and speak, or provide pre-rendered audio.
curl -X POST "$API_BASE/bots/google_meet/abc-defg-hij/speak" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -d '{
    "text": "Hello everyone, here is the summary.",
    "provider": "openai",
    "voice": "nova"
  }'
Request body:
FieldTypeDefaultDescription
textstringText to speak (mutually exclusive with audio_url / audio_base64)
providerstring"openai"TTS provider
voicestring"alloy"Voice ID. OpenAI voices: alloy, echo, fable, onyx, nova, shimmer
{
  "message": "Speak command sent",
  "meeting_id": 220
}
{
  "detail": "Must provide one of: text, audio_url, or audio_base64"
}

DELETE /bots/{platform}/{native_meeting_id}/speak

Immediately stop any ongoing speech. The bot re-mutes.
curl -X DELETE "$API_BASE/bots/google_meet/abc-defg-hij/speak" \
  -H "X-API-Key: $API_KEY"
{
  "message": "Speak stop command sent",
  "meeting_id": 220
}

Chat

Read and write messages in the meeting chat.

POST /bots/{platform}/{native_meeting_id}/chat

Send a chat message. The bot opens the chat panel (if not already open), types the message, and sends it.
curl -X POST "$API_BASE/bots/google_meet/abc-defg-hij/chat" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -d '{"text": "Meeting summary: 3 action items identified."}'
Request body:
FieldTypeDescription
textstringMessage to send to the meeting chat
{
  "message": "Chat message sent",
  "meeting_id": 220
}
{
  "detail": "text is required"
}

GET /bots/{platform}/{native_meeting_id}/chat

Read all captured chat messages from the meeting.
curl "$API_BASE/bots/google_meet/abc-defg-hij/chat" \
  -H "X-API-Key: $API_KEY"
{
  "messages": [
    {
      "sender": "John Smith",
      "text": "Can you share the action items?",
      "timestamp": 1771268061761,
      "is_from_bot": false
    },
    {
      "sender": "AI Assistant",
      "text": "Here are the action items...",
      "timestamp": 1771268061885,
      "is_from_bot": true
    }
  ],
  "meeting_id": 220
}
Response fields:
FieldTypeDescription
senderstringParticipant name (or bot name for bot messages)
textstringMessage content
timestampnumberUnix timestamp from bot runtime (commonly milliseconds in current integrations)
is_from_botboolWhether the bot sent this message
meeting_idintegerInternal Vexa meeting ID

Screen Share

Display visual content (images, web pages, video) to meeting participants via screen sharing.

POST /bots/{platform}/{native_meeting_id}/screen

Show content via screen share. Content is rendered on an Xvfb display (1920x1080), then the bot starts presenting.
# Share an image
curl -X POST "$API_BASE/bots/google_meet/abc-defg-hij/screen" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -d '{"type": "image", "url": "https://example.com/quarterly-chart.png"}'

# Share a web page (e.g., Google Slides)
curl -X POST "$API_BASE/bots/google_meet/abc-defg-hij/screen" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -d '{"type": "url", "url": "https://docs.google.com/presentation/d/..."}'

# Share a video
curl -X POST "$API_BASE/bots/google_meet/abc-defg-hij/screen" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -d '{"type": "video", "url": "https://example.com/demo.mp4"}'

# Render custom HTML
curl -X POST "$API_BASE/bots/google_meet/abc-defg-hij/screen" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -d '{"type": "html", "html": "<h1>Quarterly Report</h1>"}'
Request body:
FieldTypeDefaultDescription
typestringContent type: image, url, video, or html
urlstringContent URL (required for image, url, video)
htmlstringRaw HTML content (required for html)
start_sharebooltrueAuto-start screen sharing (if not already sharing)
Content types:
TypeBehavior
imageRenders image fullscreen on black background
urlOpens the URL in a browser window (e.g., Google Slides, dashboards)
videoPlays video fullscreen with autoplay
htmlRenders custom HTML content in the display page
{
  "message": "Screen content command sent",
  "meeting_id": 220
}
{
  "detail": "type must be one of: image, video, url, html"
}

DELETE /bots/{platform}/{native_meeting_id}/screen

Stop screen sharing and clear the display.
curl -X DELETE "$API_BASE/bots/google_meet/abc-defg-hij/screen" \
  -H "X-API-Key: $API_KEY"
{
  "message": "Screen stop command sent",
  "meeting_id": 220
}

Avatar

Set or reset the bot’s virtual camera avatar. The avatar is displayed in the bot’s video tile when no screen share is active.
The virtual camera is experimental and only tested on Google Meet. Screen share is the recommended approach for displaying visual content.

PUT /bots/{platform}/{native_meeting_id}/avatar

Set a custom avatar image for the bot’s camera feed.
curl -X PUT "$API_BASE/bots/google_meet/abc-defg-hij/avatar" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -d '{"url": "https://example.com/avatar.png"}'
Request body:
FieldTypeDescription
urlstringURL to an image file (PNG, JPG, SVG)
image_base64stringBase64-encoded image data (alternative to url)
{
  "message": "Avatar set command sent",
  "meeting_id": 220
}
{
  "detail": "Either 'url' or 'image_base64' must be provided"
}

DELETE /bots/{platform}/{native_meeting_id}/avatar

Reset the bot’s avatar to the default Vexa logo.
curl -X DELETE "$API_BASE/bots/google_meet/abc-defg-hij/avatar" \
  -H "X-API-Key: $API_KEY"
{
  "message": "Avatar reset command sent",
  "meeting_id": 220
}

WebSocket Events

When interactive bot mode is enabled, additional events are published on the WebSocket connection:
EventPayloadDescription
speak.started{"text": "..."}Bot started speaking
speak.completedSpeech playback finished
speak.interruptedSpeech was interrupted via API
chat.received{"sender": "John", "text": "...", "timestamp": 1234}Chat message captured
chat.sent{"text": "..."}Bot sent a chat message
screen.sharing_started{"content_type": "image"}Screen sharing started
screen.sharing_stoppedScreen sharing stopped
Wait for the speak.completed event before sending the next speak command to avoid overlapping audio. Alternatively, use DELETE /speak to interrupt.