> ## Documentation Index
> Fetch the complete documentation index at: https://docs.voice.wixzel.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Meetings: send an AI voice agent into Zoom, Google Meet or Teams

> Your agent joins a Zoom, Google Meet or Microsoft Teams meeting as a named participant, hears everyone and speaks into the meeting, through your own Attendee account.

Your agent can join a video meeting as a participant with its own name. It
hears everyone in the meeting and speaks into it with its usual voice, prompt,
knowledge base and tools.

Meetings run through your own [Attendee](https://attendee.dev) account. Attendee
is the open-source meeting-bot service that joins the meeting; Wixzel Voice is
the agent that listens and talks. You bring the Attendee key, the same way you
bring your own SIP carrier for phone calls.

## What you need

1. An Attendee account: sign up at [app.attendee.dev](https://app.attendee.dev),
   or run Attendee yourself. Create an API key in your Attendee project.
2. For **Zoom**, your Attendee project also needs Zoom credentials (a Zoom
   Meeting SDK app). Attendee's docs walk through it. Google Meet and Teams
   need nothing extra.
3. An agent in Wixzel Voice.

## 1. Connect Attendee

In the console, open **Integrations → Meetings**, or call the API once:

```bash cURL theme={null}
curl -X POST https://api.voice.wixzel.com/v1/meetings/integration \
  -H "Authorization: Bearer $WIXZEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "base_url": "https://app.attendee.dev",
    "api_key": "YOUR_ATTENDEE_API_KEY"
  }'
```

The key is checked with Attendee before it is saved, stored encrypted, and
never returned. Calling this again replaces it.

Optional: add `"webhook_secret"` with your Attendee project's webhook secret
(Settings → Webhooks in Attendee). Then every status update Attendee sends us is
also checked against its signature.

## 2. Send an agent to a meeting

```bash cURL theme={null}
curl -X POST https://api.voice.wixzel.com/v1/meetings \
  -H "Authorization: Bearer $WIXZEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "AGENT_ID",
    "meeting_url": "https://meet.google.com/abc-defg-hij",
    "bot_name": "Ava from Acme"
  }'
```

The answer comes back at once with `status: "joining"`. Follow it with
`GET /v1/meetings/{id}`:

| `status` | Meaning |
| - | - |
| `joining` | The bot is on its way in. |
| `waiting_room` | It is waiting for the host to let it in. |
| `in_meeting` | It is in, listening and ready to speak. |
| `ended` | It left. `end_reason` says why, e.g. `meeting_ended`. |
| `failed` | It never got in, or nothing was said. `error` says why. |

To make it leave: `POST /v1/meetings/{id}/leave`.

## Signed-in bots

By default the bot joins as an anonymous guest, and Google Meet marks it as
"appears to be a bot" in the host's waiting list. A **signed-in bot** logs into
an account first, so the meeting shows a named participant with its own avatar.
It can also join meetings that do not let anonymous guests in.

1. In your Attendee, set up a bot login under **Settings → Bot Logins**: a
   Google Workspace account for Google Meet, or a Microsoft 365 account for
   Teams. Attendee's [signed-in bots guide](https://docs.attendee.dev/guides/signedinbots)
   walks through it.
2. Turn it on for that platform, in the console (**Integrations → Meetings →
   Signed-in bots**) or with the API:

```bash cURL theme={null}
curl -X POST https://api.voice.wixzel.com/v1/meetings/integration \
  -H "Authorization: Bearer $WIXZEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "base_url": "https://app.attendee.dev",
    "signed_in_bots": { "google_meet": true, "teams": false, "login_group": null }
  }'
```

You do not need to send the API key again: without one, the stored key is kept.
To join one meeting differently, pass `"signed_in": true` or `false` with
`POST /v1/meetings`. Signed-in bots are not available for Zoom.

A bot signed into an account outside the host's organisation can still be
shown as an external guest, just not as a bot.

## When the agent speaks

In a meeting most of what is said is not for the agent. By default
(`respond_when: "addressed"`) it speaks only after someone says its name, and
for a short while after it last spoke, so people can answer its questions
without naming it again. Anything else it would have said is not played and is
left out of the transcript.

Add other names people might use with `wake_names`, for example
`["Ava", "Acme bot"]`. Set `respond_when: "always"` for a one-to-one meeting
where every word is for the agent.

## Billing

* **Attendee** bills you for the bot's time in meetings, directly, on your
  Attendee account. Wixzel Voice adds nothing to that.
* **Wixzel Voice** bills the conversation like a [realtime session](/realtime.md):
  per second of the engine's usage plus the platform fee, from the moment the
  bot is let into the meeting until it leaves. Joining and the waiting room cost
  nothing.

The meeting appears in `GET /v1/calls` with `channel: "meeting"`, with its
transcript, and sends a `callCompleted` webhook when it ends.

## Limits

* `max_duration_seconds`: up to 4 hours in the meeting (default 1 hour).
* `waiting_room_timeout_seconds`: up to 1 hour (default 10 minutes).
* Audio in and out of the meeting is telephone quality (the same 8 kHz audio the
  engines use on phone calls).
* Zoom meetings that use Zoom's RTMS stream cannot take audio from a bot, so the
  agent can listen there but not speak. Use the standard Zoom bot in Attendee.
* Human transfer is not available in meetings.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.