---
title: "List meetings"
method: GET
path: "/meetings"
tags: ["Meetings"]
---

# List meetings

`GET /meetings`

## Request

- Base URL: `https://www.happyscribe.com/api/v1`
- URL: `https://www.happyscribe.com/api/v1/meetings`
- Auth: API key in header `Authorization`

The meetings of one workspace, whether they came from a connected calendar or a
bot. Upcoming meetings are listed soonest first; any other list, latest start
first. Cancelled meetings are listed only with `phase=cancelled`.

## Query parameters

- `workspace_id` string, required
- `member_id` string
- `phase` 'upcoming' | 'live' | 'past' | 'cancelled': About time only; what happens after the call is in `results`. - `upcoming`: not started, and nothing recording yet. - `live`: a recording is active. An early start counts: activity beats the calendar. - `past`: the recording ended, or the scheduled end went by. - `cancelled`: the source event was cancelled. Listed only with `phase=cancelled`.
- `starts_after` string, date-time
- `starts_before` string, date-time
- `limit` integer
- `cursor` string

## Response `200`

One page of meetings.

- MeetingList
  - `object` string: Always `list`.
  - `data` Meeting[]: The meetings on this page.
    - `id` string: Beginning with `mtg_`. Stays the same through reschedules, URL changes and bot retries.
    - `object` string: Always `meeting`.
    - `workspace_id` string: Workspace ID, beginning with `wks_`. Treat it as an opaque string.
    - `source` 'calendar_connection' | 'calendar_sync' | 'bot': Where the meeting came from. - `calendar_connection`: a calendar the member connected. - `calendar_sync`: an event you pushed with `POST /calendar_events`. - `bot`: a bot you sent with `POST /bots`.
    - `phase` 'upcoming' | 'live' | 'past' | 'cancelled': About time only; what happens after the call is in `results`. - `upcoming`: not started, and nothing recording yet. - `live`: a recording is active. An early start counts: activity beats the calendar. - `past`: the recording ended, or the scheduled end went by. - `cancelled`: the source event was cancelled. Listed only with `phase=cancelled`.
    - `title` string, nullable: The calendar event's title, or a generated one for a bot sent without a calendar event.
    - `starts_at` string, date-time, nullable: A bot meeting starts at the bot's `join_at`.
    - `ends_at` string, date-time, nullable: Scheduled end, or `null` when unknown.
    - `meeting_url` string, nullable: The link to join the call, or `null` when the event has none.
    - `platform` 'meet' | 'zoom' | 'teams' | 'null', nullable: The meeting platform, from the link. `null` for any other link (Webex, a dial-in page) or none. - `meet`: Google Meet. - `zoom`: Zoom. - `teams`: Microsoft Teams, Teams Live included.
    - `organizer` MeetingPerson
      - `name` string, nullable: The person's name, or `null` when unknown.
      - `email` string, nullable: The person's email, or `null` when unknown.
      - `member_id` string, nullable: Set when the person is a member of the meeting's workspace.
    - `participants` MeetingPerson[]: The people on the invite, or given when the bot was sent.
      - `name` string, nullable: The person's name, or `null` when unknown.
      - `email` string, nullable: The person's email, or `null` when unknown.
      - `member_id` string, nullable: Set when the person is a member of the meeting's workspace.
    - `calendar_event` CalendarEvent: One calendar event per occurrence and workspace: every member's copy of it shares this object, as they share the meeting. Its times, link and title are the occurrence's; its people come from the organizer's copy.
      - `id` string: Beginning with `cev_`. One per meeting; stays the same through reschedules and every member's push.
      - `object` string: Always `calendar_event`.
      - `meeting_id` string: The meeting of this occurrence, beginning with `mtg_`.
      - `ical_uid` string, nullable: The iCal UID shared by every attendee's copy of the event, or `null` when the calendar sent none.
      - `recurring` boolean, nullable: Whether the event is an occurrence of a recurring series. `null` only in a webhook event from before 2026-10-12, which did not record it.
      - `title` string, nullable: The event title.
      - `starts_at` string, date-time, nullable: Scheduled start, in ISO 8601.
      - `ends_at` string, date-time, nullable: Scheduled end, in ISO 8601.
      - `meeting_url` string, nullable: The link to join the call, or `null` when the event has none.
      - `organizer` MeetingPerson
        - `name` string, nullable: The person's name, or `null` when unknown.
        - `email` string, nullable: The person's email, or `null` when unknown.
        - `member_id` string, nullable: Set when the person is a member of the meeting's workspace.
      - `attendees` object[]: Everyone on the invite, the organizer included. Empty once no member has the event.
        - `name` string, nullable: The attendee's name, when the calendar has one.
        - `email` string, nullable: The attendee's email.
        - `member_id` string, nullable: Set when the attendee is a member of the workspace.
        - `response` 'accepted' | 'declined' | 'tentative' | 'needs_action' | 'null', nullable: The attendee's answer to the invite, or `null` when the calendar does not say. - `accepted`: accepted. - `declined`: declined. - `tentative`: answered maybe. - `needs_action`: has not answered.
      - `source` 'calendar_connection' | 'calendar_sync': Where the event came from. - `calendar_connection`: a calendar the member connected. - `calendar_sync`: an event you pushed with `POST /calendar_events`.
      - `metadata` Metadata: Your own key-value pairs, for your ids and context. HappyScribe stores them, returns them on the object and in every webhook that carries it, and never acts on them. Up to 50 keys of up to 40 characters (no square brackets), values up to 500 characters. See [metadata](/meetingkit/setup#a-workspace-per-customer).
      - `cancelled_at` string, date-time, nullable: When the event was cancelled, once no member of the workspace still has it; otherwise `null`.
      - `created_at` string, date-time: When the event first appeared, in ISO 8601.
      - `updated_at` string, date-time: When the event or its meeting last changed, in ISO 8601.
    - `policy` Policy: What an object prefers for the meetings it covers. Every group is optional: an object shows only what it sets. Which fields each owner accepts is listed on [Update a policy](#operation/updatePolicy).
      - `recording` object: Which meetings get recorded, and how.
        - `scope` Scope[]: Which meetings get recorded (workspace, member). `[]` records none.
        - `enabled` boolean: Meeting only. Record this meeting or not.
        - `methods` object: How meetings are recorded.
          - `bot` object: The notetaker bot that joins the call.
            - `start` 'on_join' | 'on_command': When the bot starts recording. - `on_join`: as soon as it joins the call. - `on_command`: it joins paused, until someone types `!resume` in the chat.
            - `mode` 'audio_and_video' | 'audio_only': What the bot records. - `audio_and_video`: audio and video. - `audio_only`: audio only.
            - `silence_detection` object: What the bot does when nobody speaks for a while.
              - …
      - `transcription` object: How the recording is transcribed.
        - `language` string: A language tag, `auto` or `multi`. See [Languages](/api-reference/languages).
      - `summary` object: How the summary is written.
        - `template` string, nullable: A built-in template's slug, such as `discovery_call`, or a custom template's `tpl_` id. Integer custom template ids are still accepted.
        - `language` string, nullable: A language tag (see [Languages](/api-reference/languages)); `null` follows the transcript's language.
      - `branding` object: How the notetaker is branded.
        - `brand_kit_id` string, nullable: Workspace only. The brand kit the workspace's bots use, beginning with `brk_`; `null` uses HappyScribe's default branding. The same link as the kit's `workspace_ids`. The kit must be used by a workspace the key belongs to. On a meeting's `effective_policy`, the kit its bot is sent with, `null` when the workspace's plan does not include notetaker customization.
    - `effective_policy` EffectivePolicy: What an object prefers for the meetings it covers. Every group is optional: an object shows only what it sets. Which fields each owner accepts is listed on [Update a policy](#operation/updatePolicy).
      - `recording` object: Whether this meeting is recorded, and why.
        - `scope` Scope[]: Which meetings get recorded (workspace, member). `[]` records none.
        - `enabled` boolean: Meeting only. Record this meeting or not.
        - `methods` object: How meetings are recorded.
          - `bot` object: The notetaker bot that joins the call.
            - `start` 'on_join' | 'on_command': When the bot starts recording. - `on_join`: as soon as it joins the call. - `on_command`: it joins paused, until someone types `!resume` in the chat.
            - `mode` 'audio_and_video' | 'audio_only': What the bot records. - `audio_and_video`: audio and video. - `audio_only`: audio only.
            - `silence_detection` object: What the bot does when nobody speaks for a while.
              - …
        - `enabled_because` 'in_scope' | 'not_in_scope' | 'meeting_override' | 'bot_requested' | 'bot_cancelled' | 'unsupported_platform' | 'no_meeting_url': Why recording is on or off. `in_scope`: the meeting matches a member's `recording.scope`. `not_in_scope`: it matches no member's scope. `unsupported_platform`: the link is not Zoom, Google Meet or Microsoft Teams. `meeting_override`: set on the meeting with `PATCH /policies/{id}`. `bot_requested`: a meeting created by `POST /bots`. `bot_cancelled`: that bot was cancelled before it joined (with `PATCH /policies/{id}`, `DELETE /bots/{id}` or in HappyScribe); the meeting's `policy` stays empty, since nothing is stored on it. `no_meeting_url`: a calendar meeting with no link to join.
      - `transcription` object: How the recording is transcribed.
        - `language` string: A language tag, `auto` or `multi`. See [Languages](/api-reference/languages).
      - `summary` object: How the summary is written.
        - `template` string, nullable: A built-in template's slug, such as `discovery_call`, or a custom template's `tpl_` id. Integer custom template ids are still accepted.
        - `language` string, nullable: A language tag (see [Languages](/api-reference/languages)); `null` follows the transcript's language.
      - `branding` object: How the notetaker is branded.
        - `brand_kit_id` string, nullable: Workspace only. The brand kit the workspace's bots use, beginning with `brk_`; `null` uses HappyScribe's default branding. The same link as the kit's `workspace_ids`. The kit must be used by a workspace the key belongs to. On a meeting's `effective_policy`, the kit its bot is sent with, `null` when the workspace's plan does not include notetaker customization.
    - `recordings` object[]: How audio came in. Each bot sent to the meeting, oldest first.
      - `id` string: The bot's `bot_` ID.
      - `type` 'bot': How the audio came in. Only `bot` for now.
      - `status` 'queued' | 'joining' | 'in_call' | 'completed' | 'failed' | 'cancelled': - `queued`: scheduled, or waiting to join. - `joining`: joining the call. - `in_call`: in the call and recording. - `completed`: left the call; what it recorded is processed into the results. - `failed`: ended without a recording. - `cancelled`: cancelled before it joined.
      - `started_at` string, date-time, nullable: When the bot joined, or is scheduled to join.
      - `ended_at` string, date-time, nullable: When the bot left.
    - `results` object: Statuses only. The content is at `GET /meetings/{id}/results`.
      - `status` 'processing' | 'ready' | 'failed' | 'none': `none` until a recording produces it (and for good when nothing was recorded, or no summary for a failed transcript), `processing` while it is made, then `ready` or `failed`. Results never forecast: whether a recording will come is the meeting's `phase`, `recordings` and `effective_policy.recording`.
      - `transcript` object: The transcript: its status and language.
        - `status` 'processing' | 'ready' | 'failed' | 'none': `none` until a recording produces it (and for good when nothing was recorded, or no summary for a failed transcript), `processing` while it is made, then `ready` or `failed`. Results never forecast: whether a recording will come is the meeting's `phase`, `recordings` and `effective_policy.recording`.
        - `language` string, nullable: The transcript's language tag.
      - `summary` object: The summary: its status.
        - `status` 'processing' | 'ready' | 'failed' | 'none': `none` until a recording produces it (and for good when nothing was recorded, or no summary for a failed transcript), `processing` while it is made, then `ready` or `failed`. Results never forecast: whether a recording will come is the meeting's `phase`, `recordings` and `effective_policy.recording`.
      - `media` object: The recording: its status and length.
        - `status` 'processing' | 'ready' | 'failed' | 'none': `none` until a recording produces it (and for good when nothing was recorded, or no summary for a failed transcript), `processing` while it is made, then `ready` or `failed`. Results never forecast: whether a recording will come is the meeting's `phase`, `recordings` and `effective_policy.recording`.
        - `duration_seconds` number, nullable: Length of the recording, in seconds.
    - `metadata` Metadata: Your own key-value pairs, for your ids and context. HappyScribe stores them, returns them on the object and in every webhook that carries it, and never acts on them. Up to 50 keys of up to 40 characters (no square brackets), values up to 500 characters. See [metadata](/meetingkit/setup#a-workspace-per-customer).
    - `created_at` string, date-time: When the meeting first appeared, in ISO 8601.
    - `updated_at` string, date-time: When anything in the meeting last changed, in ISO 8601.
  - `has_more` boolean: Whether more results follow this page.
  - `_links` object: Empty on the last page.
    - `next` object: The next page. Absent on the last page.
      - `url` string, uri: The next page, with the same filters. Follow it rather than building a cursor.

## Other responses

- `400`: Missing `workspace_id`, an unknown `phase`, or a `limit`, `cursor` or time that cannot be read.
- `401`: Missing or invalid API key, or the key is not an owner or admin of the workspace.
- `404`: The workspace or member is not one the key can see.

---

[API](https://skmtc.dev/happyscribe/apis/happyscribe-api.md) - [All operations](https://skmtc.dev/happyscribe/apis/happyscribe-api/llms.txt) - [OpenAPI document](https://skmtc.dev/happyscribe/apis/happyscribe-api/revisions/1281bd968c3d?raw)
