---
title: "Create a meeting session"
method: POST
path: "/meeting_sessions"
tags: ["Meeting Sessions"]
---

# Create a meeting session

`POST /meeting_sessions`

Creates a new meeting session. When an idempotency_key is supplied in the request body, replay lookup is scoped to the authenticated account and compares only the key; the request payload is not fingerprinted or compared. If a session with that key already exists for the account, the existing session is replayed (200); otherwise a new session is created (201). Supports bring-your-own-key (BYOK) configuration. The session may enter asynchronous states (e.g. joining, waiting_for_admission) before becoming active. Optional `camera_image` input is write-only and applies only when no Avatar or Assistant webpage output takes precedence. An ignored URL is not fetched. An effective URL source is resolved before bot creation; neither the source URL nor image bytes are persisted, returned, or logged. Treat signed URLs as credentials.

## Request body

- CreateMeetingSessionRequest — Request body for creating a new meeting session. Cross-field rules: - Neither `avatar` nor `assistant` can be combined with `join_at`; both are available only for sessions that join immediately. - `assistant` cannot be combined with `barge_in: true`. - The `avatar` and `assistant` options take effect at session creation and cannot be modified later. - An effective Avatar or Assistant webpage output takes precedence over `camera_image`; the static image is ignored and a URL source is not fetched.
  - `assistant` MeetingSessionAssistantRequest — Request options for attaching a voice assistant to the session. Routing fields (`call_control_connection_id`, `from`, and `loopback_sip_uri`) are used only to establish the assistant call leg and are omitted from response objects. `audio_gate` is returned with `id` in the assistant response object.
    - `audio_gate` 'none' | 'half_duplex' — Audio gating strategy for the assistant call leg.
    - `call_control_connection_id` string, required — Call control connection used to bridge the assistant into the meeting audio.
    - `from` string, required — E.164 calling number used as the originating party for the assistant call leg.
    - `id` string, required — Identifier of the assistant to attach.
    - `loopback_sip_uri` string, required — SIP URI to which the assistant media loopback is established.
  - `avatar` MeetingSessionAvatarRequest — Request options for attaching a bring-your-own-key avatar to the session.
    - `api_key` string, required — Bring-your-own-key API key for the avatar provider. The key is never stored or returned by the API.
    - `avatar_id` string, required — Identifier of the avatar to use.
    - `provider` 'anam', required — Avatar provider identifier. Currently only "anam" is supported.
  - `barge_in` boolean — When enabled, a human participant `speech_on` event interrupts and stops the current bot audio; it does not bypass admission or initiate speech. Assistant sessions reject `barge_in: true`.
  - `bot_name` string — Display name for the bot in the meeting. Defaults to "Meeting Bot".
  - `camera_image` union — Write-only static camera-tile image for this session, not a native account or participant profile photo. Supply exactly one JPEG source. When effective, the image is used as the bot's static camera/video output; presentation varies by meeting platform and recording configuration and is not guaranteed in recordings. An effective Avatar or Assistant webpage output takes precedence, so this input is ignored and a URL source is not fetched.
    - object
      - `base64_data` string, required — Canonical plain RFC 4648 Base64 for a valid decoded JPEG. Data URIs, whitespace, and the URL-safe alphabet are rejected. The encoded value is limited to 1,835,008 characters and the decoded JPEG to 1,363,148 bytes. The JPEG is limited to 4,096 pixels per dimension, 4 megapixels, and 128 MB of decoder memory. The image bytes are not persisted, returned, or logged.
      - `format` 'jpeg', required — Only JPEG images are accepted.
    - object
      - `format` 'jpeg', required — Only JPEG images are accepted.
      - `url` string, uri, required — Public HTTPS JPEG URL with at most 2,048 characters and no credentials, fragment, surrounding whitespace, raw control characters, or explicit non-default port. Signed queries are allowed but must be treated as credentials. Fetching is limited to public network destinations, a five-second timeout, no redirects, a 2xx image/jpeg response with identity or no content encoding, and a 1,363,148-byte limit enforced against both declared and streamed content. The service resolves the URL before bot creation and does not persist, return, or log the URL or image bytes.
  - `idempotency_key` string — Client-supplied idempotency key to safely retry creation requests without duplicating sessions. Lookup is scoped to the authenticated account and compares the key only; the request payload is not fingerprinted or compared.
  - `join_at` string, date-time — ISO-8601 timestamp in the future at which the bot should join. If omitted, the bot joins immediately.
  - `meeting_url` string, uri, required — The meeting URL the bot should join.
  - `metadata` object — Arbitrary key-value metadata attached to the session. The serialized JSON representation must not exceed 16384 characters at runtime.
  - `speak_on_enter` string — Text the bot speaks when it enters the meeting.
  - `summarize_on_end` boolean — If true, generate a summary artifact when the session ends.
  - `voice` string — Session-default voice identifier used for `speak_on_enter` and ordinary speak actions. A voice supplied on an individual speak action overrides this default for that utterance.
  - `webhook_url` string, uri — HTTPS endpoint to receive session lifecycle callbacks. Static validation requires HTTPS, rejects embedded credentials and blocked hosts, and enforces egress policy. Validation makes no network request to the endpoint.

## Response `200`

Replayed existing meeting session matching the account-scoped idempotency_key. Replay is key-only; the request payload is not fingerprinted or compared.

- MeetingSessionResponse
  - `data` MeetingSession, required — Represents a meeting session. All serializer fields are present and required; nullable fields use null when absent. No actor, provider-bot, idempotency, routing, key, or internal fields are exposed.
    - `account_id` string, required — Identifier of the owning account.
    - `assistant` MeetingSessionAssistant, required
      - `audio_gate` 'none' | 'half_duplex', required — Audio gating strategy for the assistant call leg.
      - `id` string, required — Identifier of the assistant.
    - `assistant_state` 'starting' | 'connected' | 'failed' | 'ended' | 'null', nullable, required — Current state of the assistant, or null if no assistant is attached.
    - `assistant_state_changed_at` string, date-time, nullable, required — Timestamp of the last assistant state change, or null.
    - `avatar` MeetingSessionAvatar, required
      - `avatar_id` string, required — Identifier of the avatar.
      - `provider` 'anam', required — Avatar provider identifier.
    - `avatar_state` 'starting' | 'connected' | 'degraded' | 'disconnected' | 'null', nullable, required — Current state of the avatar connection, or null if no avatar is attached.
    - `avatar_state_changed_at` string, date-time, nullable, required — Timestamp of the last avatar state change, or null.
    - `bot_name` string, required — Display name of the bot in the meeting.
    - `config` MeetingSessionConfig, required
      - `barge_in` boolean, required — When enabled, a human participant `speech_on` event interrupts and stops the current bot audio; it does not bypass admission or initiate speech. Assistant sessions reject `barge_in: true`.
      - `speak_on_enter` string, nullable, required — Text spoken on meeting entry, or null if not set.
      - `summarize_on_end` boolean, required — Whether a summary artifact is generated on session end.
      - `voice` string, nullable, required — Configured voice identifier, or null if not set.
    - `created_at` string, date-time, required — Timestamp when the session was created.
    - `ended_at` string, date-time, nullable, required — Timestamp when the session ended, or null if ongoing.
    - `failure_reason` string, nullable, required — Human-readable failure reason if the session failed, or null.
    - `id` string, required — Unique identifier for the meeting session.
    - `join_at` string, date-time, nullable, required — Scheduled join time, or null for immediate join.
    - `joined_at` string, date-time, nullable, required — Timestamp when the session first became `active`, or null if it never became active. This remains positive admission evidence after terminal transitions.
    - `meeting_url` string, uri, required — The meeting URL the bot joins.
    - `metadata` object, required — Arbitrary key-value metadata attached to the session.
    - `platform` 'zoom' | 'google_meet' | 'teams' | 'webex' | 'unknown', required — Detected meeting platform.
    - `provider` string, required — Provider handling the meeting session.
    - `recording` boolean, required — Whether the session is being recorded.
    - `status` 'scheduled' | 'joining' | 'waiting_for_admission' | 'active' | 'leaving' | 'ended' | 'failed' | 'admission_denied', required — Lifecycle status. `waiting_for_admission` means the bot reached the meeting lobby and may require host approval. `active` means the bot entered the meeting/media path. `ended` alone does not prove attendance; use non-null `joined_at` as positive evidence that the session became active. `admission_denied` is reserved for an explicit provider denial, while cancellation or another termination can end a never-admitted session as `ended`.
    - `status_detail` string, nullable, required — Additional human-readable detail about the status, or null.
    - `updated_at` string, date-time, required — Timestamp of the last update to the session.
    - `webhook_url` string, uri, nullable, required — Webhook endpoint for session lifecycle callbacks, or null if not configured.

## Other responses

- `201` — New meeting session created.
- `400` — Bad Request
- `401` — Unauthorized. On api.telnyx.com, authentication is enforced by the API gateway before the request reaches the Meeting service, so a missing or invalid API key returns the standard Telnyx error envelope (`{"errors": [{"code": "10009", ...}]}`) rather than the single-`error` shape below.
- `403` — The authenticated credential is not permitted to perform this operation.
- `413` — Payload Too Large
- `422` — Unprocessable Entity, including an unsupported capability
- `429` — Authentication is temporarily overloaded. Retry after the number of seconds in `Retry-After`.
- `500` — Internal Server Error
- `502` — The meeting provider rejected bot creation.
- `503` — A required feature or dependency is not configured or authentication is unavailable.

---

[API](https://skmtc.net/team-telnyx/apis/telnyx-api-2.md) · [All operations](https://skmtc.net/team-telnyx/apis/telnyx-api-2/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/team-telnyx/telnyx-api-2/revisions/3fdc16374d70/schema)
