---
name: webex-meeting-bot-app
description: Sets up and registers the Webex Integration (Webex's OAuth app) behind Unified.to's Webex (meeting bot) integration (`webexmeetingbot`) end to end — creating the Integration in the Webex Developer Portal with Unified's redirect URI, the `meeting:schedules_read`, `meeting:participants_read`, `meeting:recordings_read` and `meeting:transcripts_read` scopes, entering the client ID and secret in Unified, the signed Webex webhooks Unified registers per connection, and an end-to-end test from `READY` through `IN_CALL_NOT_RECORDING` to `CALL_ENDED` and `RECORDING_READY`. Use when asked to set up Webex meeting bots or a Webex notetaker, register a Webex Integration for Unified, or fix a Webex bot that gets no events or no recordings. Read `unified-meeting-bots` for creating bots and handling events.
---

# Webex (meeting bot) App Setup and Registration

Get a working **Webex (meeting bot)** integration (`webexmeetingbot`): your own Webex Integration with the meeting
scopes, entered on the integration in Unified, so `calendar_bot`s follow Webex meetings through Webex webhooks.

Three things cost more than they look:

- **It's a monitor, not a bot in the call.** No participant joins; no audio, video or chat is captured. Unified
  follows the meeting through Webex webhooks: start/end and participants live, recording and transcript afterwards.
- **It never reaches `DONE`.** The `meetings` ended notification doesn't say whether a recording will follow, so the
  final status is `CALL_ENDED`; watch for `RECORDING_READY`.
- **Bring your own Integration.** Unified has no shared Webex credentials for meeting bots. The integration is
  separate from the **Webex** integration; existing Webex connections don't change.

## Built on

- **`unified-meeting-bots`** — creating bots, the `calendar_botevent` webhook, statuses and the `501` matrix.
- **`unified-quickstart`** — workspace basics and the Authorization component.

There is no separate Webex OAuth skill; this file covers the Webex Developer Portal steps Unified needs.

## Inputs to collect before you start

Ask in one batch. Never invent.

| Input | Notes |
| --- | --- |
| **Webex account for the Developer Portal** | Owns the Integration (§1) |
| **Integration name, icon, description** | Shown to users on the Webex consent screen |
| **Unified region** | Decides the redirect URI (§1) |
| **Which Unified permissions** | Bot permissions; `calendar_event_read`, `calendar_recording_read` if needed (§3) |
| **End users on Webex Meetings sites** | Needed for meeting, participant, recording and transcript data |
| **Is recording / transcription on in meetings?** | No recording → no `RECORDING_READY`. Cloud recording and transcripts aren't on the Webex Free plan |
| **Do connected users host the meetings?** | Webex returns only recordings of meetings hosted by or shared with the authenticated user |
| **Transcripts needed?** | Need recording on plus Webex Assistant or Closed Captions (or the Cisco AI Assistant); not available on Webex for Government (FedRAMP) |

## Quick Start

1. Developer Portal → **My Webex Apps** → create an **Integration** with Unified's redirect URI (§1).
2. Select the scopes in §2, save, copy **Client ID** and **Client Secret**.
3. In Unified, activate **Webex (meeting bot)**, enter them, select permissions (§3).
4. Nothing to configure in Webex for webhooks — create the `calendar_botevent` webhook before the meeting starts (§4).
5. Connect a test user and run the end-to-end test (§5, §6).

## Product state (from the TICKET-3338 Webex meeting-bot PR — re-verify before trusting)

- Integration type `webexmeetingbot`, a webhook monitor ("Option A": no bot joins the call); not launched yet.
- Signed Webex webhooks verified on Unified's raw-body route.
- Inherits Webex `calendar_calendar`, `calendar_event`, `calendar_recording` and `calendar_webinar`.
- `join_at` and any `recording_config` return `501`; only `name` can be updated.

## 1. Create a Webex Integration

1. Sign in at https://developer.webex.com/ → **My Webex Apps** → create an **Integration**.
2. Redirect URI for your region:
   - US `https://api.unified.to/oauth/code`
   - EU `https://api-eu.unified.to/oauth/code`
   - AU `https://api-au.unified.to/oauth/code`
3. Select the §2 scopes, save, and copy the **Client ID** and **Client Secret**. The secret is shown only when the
   integration is created, so store it safely then; never commit it.

## 2. Scopes

Select these in **My Webex Apps**:

| Scope | Unified permission | Why |
| --- | --- | --- |
| `meeting:schedules_read` | `calendar_bot_read`, `calendar_bot_write`, `calendar_botevent_read`, `calendar_event_read`, `calendar_recording_read` | Find the meeting on create; meeting started/ended webhooks; list meetings |
| `meeting:participants_read` | `calendar_botevent_read`, `calendar_event_read` | Participant joined/left webhooks |
| `meeting:recordings_read` | `calendar_botevent_read`, `calendar_recording_read` | Recording created webhooks; reading the recording |
| `meeting:transcripts_read` | `calendar_botevent_read`, `calendar_recording_read` | Transcript created webhooks, snippets and recording transcripts |

For other inherited permissions, add the scopes the Webex integration uses: `spark:rooms_read`
(`calendar_calendar_read`), and `meeting:schedules_write` and `meeting:participants_write` (`calendar_event_write`,
`calendar_webinar_write`). Webex lists the scope each webhook resource needs in its webhooks documentation.

Sign-in also uses the OpenID Connect scopes `openid`, `profile` and `email`. They aren't in the portal's scope list and
don't need to be registered.

If you add scopes later, existing users must reconnect to grant them.

## 3. Enter the credentials in Unified

1. `app.unified.to` → **Integrations** → activate **Webex (meeting bot)**.
2. Enter the Integration's **Client ID** and **Client Secret**.
3. Select permissions: `calendar_bot_read`, `calendar_bot_write`, `calendar_botevent_read`, plus
   `calendar_event_read` (to list meetings) and `calendar_recording_read` as needed. Creating a bot from an
   `event_id` needs only `calendar_bot_write`, which carries `meeting:schedules_read`.

## 4. Webhooks (nothing to configure in Webex)

When you create a native `calendar_botevent` webhook on a connection, Unified registers six Webex webhooks for it:
`meetings` started and ended, `meetingParticipants` joined and left, `recordings` created, `meetingTranscripts`
created. Each registration gets its own random signing secret, and Unified verifies every delivery with the secret
of the registration that sent it. Deleting the Unified webhook
removes the Webex registrations. Create it **before the meeting starts**, or the bot misses the meeting.

## 5. How end users connect

End users authorize **Webex (meeting bot)** through the Authorization component or authorization link and approve the
§2 scopes. A bot only receives notifications from its own connection's webhooks.

## 6. Test end to end

1. Create the native `calendar_botevent` / `created` webhook on the connection.
2. Create a `calendar_bot` with the Webex meeting link (`meeting_url`) or an `event_id` (Webex meeting ID) →
   `READY`.
3. Start the meeting → `BOT_STATUS_CHANGE` to `IN_CALL_NOT_RECORDING`, `PARTICIPANT_JOINED`.
4. End it → `CALL_ENDED`. If recorded or transcribed, `RECORDING_READY` and `TRANSCRIPT_RECEIVED` (one per snippet)
   follow later: a recording can take up to 24 hours, and a transcript about twice the meeting's length (up to 24
   hours).
5. `GET /calendar/{connection_id}/recording/{recording_id}` on the same connection.

## Limits

- `501`: `join_at`, any `recording_config`. `400`: a link that isn't a Webex meeting link, or a
  `transcription.provider` other than `MEETING_CAPTIONS`. `404`: unknown meeting or event. `422`: the meeting has no
  web link. `automatic_leave` isn't used.
- Final status is `CALL_ENDED`; never `DONE`.
- No live transcript, chat, webcam, screen-share or speaking events.
- Recurring/scheduled series: the bot follows the first occurrence that starts after it was created.
- One unfinished bot per meeting link per connection: `409` while an earlier bot for the exact same link isn't
  `CALL_ENDED`, `DONE` or `FATAL`. Only `name` can be updated (`meeting_url` or `event_id` in an update returns
  `400`); no event on delete.
- A bot starts in `READY`, except one created from an `event_id` that is a running Webex meeting instance
  (`meetingType` `meeting`, state `inProgress`), which starts in `IN_CALL_NOT_RECORDING`. A `meeting_url` resolves to
  the scheduled meeting or series, never a running instance, so a bot from a link always starts in `READY`.
- Unified asks for 100 transcript snippets per page, for up to 50 pages.
- Webex's target is that the API data behind a notification catches up within 10 minutes in 99.5% of cases; until
  then a lookup can return `404`. Unified handles this for transcripts: if the transcript snippets lookup returns
  `404`, it retries the notification after 30 seconds, then 1, 2, 3 and 5 minutes (about 11.5 minutes in all), so
  `TRANSCRIPT_RECEIVED` events usually still arrive, just later.
- Webex disables a webhook after repeated delivery failures and doesn't re-enable it; it also disables webhooks
  whose creator is deleted.

## Troubleshooting by error message

| Symptom | Cause and fix |
| --- | --- |
| No events at all | `calendar_botevent` webhook created after the meeting started, or on another connection; a §2 scope missing (reconnect after adding scopes); Webex disabled the webhooks after repeated delivery failures or because their creator was deleted — recreate the `calendar_botevent` webhook |
| Creating a bot returns `501` | Request has `join_at` or `recording_config` — remove them |
| Creating a bot returns `400` | Not a Webex meeting link |
| Creating a bot returns `404` | The meeting or event doesn't exist, or the connected user can't see it |
| Creating a bot returns `422` | The Webex meeting has no web link |
| Updating a bot returns `400` | The update includes `meeting_url` or `event_id` — only `name` can change |
| No recording or transcript events | Meeting not recorded/transcribed in Webex; the connected user didn't host it and it wasn't shared with them; Free plan or Webex for Government (transcripts); not ready yet (up to 24 hours); connection lacks `meeting:recordings_read` / `meeting:transcripts_read` |
| Bot never reaches `DONE` | Expected on Webex — use `RECORDING_READY` |
| `invalid_client` / redirect mismatch at sign-in | Client ID/secret pasted wrong, or redirect URI doesn't match your region exactly |

## Stop and ask

- The product needs live captions, chat or media from Webex — not available.
- End users aren't on Webex Meetings sites.

## References

- Webex Developer Portal: https://developer.webex.com/
- Webex integrations (OAuth): https://developer.webex.com/docs/integrations
- Webex meeting webhooks: https://developer.webex.com/meeting/docs/register-and-manage-webhooks
- Receiving and verifying webhooks (data sync, disabled webhooks): https://developer.webex.com/docs/receive-and-verify-webhooks
- Accessing meeting resources (transcript prerequisites): https://developer.webex.com/meeting/docs/access-meeting-resources-guide
- Recordings API: https://developer.webex.com/docs/api/v1/recordings/list-recordings
- Webex cloud recording availability: https://help.webex.com/en-us/article/n62735y
- `calendar_bot` model: https://docs.unified.to/calendar/bot/model
- Guide — How to Set Up a Webex Meeting Bot with Unified (published at launch):
  https://docs.unified.to/guides/how_to_set_up_a_webex_meeting_bot_with_unified
