# Meeting ended

**Event:** `meeting.ended`

## Description

Fires once a meeting's transcript and AI summary are ready. The
payload mirrors [`/meeting.info`](/docs/api/meeting-info) so handlers
do not need a follow-up fetch in the common case.

Personal destinations only receive meetings the authorizing user
participated in. Organization destinations are roam-wide only with
[`admin:meetings:read`](/docs/guides/scopes#meeting-width-adminmeetingsread);
otherwise the install's bot must have access to the meeting.

**Event name:** `meeting.ended`

**Filter:** `{"hasVideo": true}` — only deliver when the meeting was
video recorded. The filter keys on "was recorded", not "the recording is
ready to fetch", so a matching delivery normally arrives while the upload
is still in flight. Omit the filter to receive every `meeting.ended`
event. `{"hasVideo": false}` is rejected at subscribe time so it is not
silently treated as no filter.

**No `videoStatus` here.** [`/meeting.info`](/docs/api/meeting-info) and
[`/meeting.list`](/docs/api/meeting-list) carry a `videoStatus` field
(`none`, `processing`, `available`); this payload deliberately does not.
`meeting.ended` fires once, at meeting end, when the value would be
`processing` for essentially every recorded meeting and would already be
stale by the time the delivery landed. To find out whether a recording is
playable, call [`/meeting.info`](/docs/api/meeting-info) for a fresh read.

Delivered inside the standard [event envelope](/docs/webhooks/webhooks#event-envelope);
the schema below shows the full delivery body with this event's payload
under `data`.

**Required scope:** `meetings:read` (`user:read` to include
participants and the host, `user:read.email` for emails).

## Webhook Payload


### Example Payload

```json
{
  "type": "meeting.ended",
  "eventId": "0197f9a5-4d84-7dd4-be5f-6a7b8c9d0e1f",
  "timestamp": "2026-04-21T17:52:18.000000Z",
  "apiVersion": "2026-07-07",
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "title": "Weekly Team Standup",
    "start": "2026-04-21T17:00:00Z",
    "participantCount": 8,
    "hasVideo": true,
    "host": {
      "type": "member",
      "id": "709b8a57-70bc-427a-b6f0-b16ba5297f8c",
      "name": "Alex Chen",
      "email": "alex.chen@example.com"
    },
    "summary": "The team reviewed Q2 priorities and assigned next-sprint action items.",
    "actionItems": [
      {
        "id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
        "title": "Update API documentation",
        "description": "Add v1 meeting endpoints to the developer docs",
        "complete": false,
        "assigneeId": "709b8a57-70bc-427a-b6f0-b16ba5297f8c",
        "suggestedAssigneeName": "Alex Chen"
      }
    ],
    "chapters": [
      {
        "name": "Sprint Review",
        "start": 0,
        "synopsis": "Reviewed completed tasks from the previous sprint"
      },
      {
        "name": "Q2 Planning",
        "start": 1140000,
        "synopsis": "Discussed priorities and resource allocation for Q2"
      }
    ]
  }
}
```

---

*Machine-readable API documentation.*
*Full documentation: https://developer.ro.am/docs/webhooks/meeting-ended*
