---
title: "Start a live voice and video call in a chatroom, or join the one already running."
method: POST
path: "/v1/create_call_session"
tags: ["Live calls"]
---

# Start a live voice and video call in a chatroom, or join the one already running.

`POST /v1/create_call_session`

## Request

- Base URL: `https://partner.mindupload.app`
- URL: `https://partner.mindupload.app/v1/create_call_session`
- Auth: API key in header `X-Partner-Key`

Starts a live voice and video call in a chatroom. Only one call runs in a room at a time: if somebody has already started one, this returns that call rather than a second one, so two people pressing call at the same moment end up together. The response contains a short-lived joining pass for the person making the request. Hand that pass to the real-time client library on your own app, which is what carries the sound and picture; the media never travels through this API, which only grants permission to join. Live calls are enabled per account, and we send you the client library and its integration guide when we switch them on for you — ask us to get started. Starting a call counts against your monthly allowance; `get_quota` reports your entitlement and what you have used. Use `mode` to choose the kind of call: a conversation everyone can speak in, or a broadcast where the audience listens and asks to speak first. Use `media_tier` to choose whether it carries a picture: `voice` is sound only. Voice and video minutes are counted separately, and your plan may put a ceiling on each kind on top of your combined monthly allowance — `get_quota` reports every ceiling and every figure. A broadcast is always a video call, whatever `media_tier` asks for.

## Request body

- object
  - `preferred_language` string, nullable: BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages.
  - `username` string, nullable: The end-user's username.
  - `password` string, nullable: The end-user's password on first sign-in. After login/register, send the returned session token (JWT) here instead — the field accepts either, and reusing the token keeps raw passwords out of your storage.
  - `chatroom_id` string, nullable: Chatroom id as returned by chatroom operations.
  - `mode` 'conversation' | 'broadcast', nullable: What kind of call to start. `conversation` (the default) admits everyone able to speak and show their camera. `broadcast` admits everyone except the chatroom owner and admins able to watch, listen and ask to speak, until somebody running the call lets them. Only the chatroom owner and admins may start a broadcast; anyone else asking for one starts a conversation.
  - `media_tier` 'voice' | 'video', nullable: Whether this call carries a picture. `video` (the default) is a call with cameras; `voice` is a call with none at all — sound only, which asks far less of a slow or metered connection. It is fixed for the whole call and applies to everybody in it — nobody can turn a camera on in a voice call, and nobody can join one as a video participant — so switching means starting a new call. Two things override it. A call already running in the room wins: the caller joins that one, in the kind it is already in. And `mode: broadcast` wins: a broadcast is always a video call, counted and capped as one. Read `media_tier` back off the call in the response to see which kind you got.
  - `host_inheritance` boolean, nullable: Whether whoever starts this call runs it. False, and absent, mean the call controls rest only on chatroom standing — so a call whose owner and admins have all left carries on with nobody running it until one of them returns. Only the chatroom owner and admins may turn it on; anyone else asking for it is ignored. Set once, when the call starts.

## Response `200`

Result envelope — check the success field.

- object
  - `success` boolean: Whether the call succeeded.
  - `error_message` string, nullable: Human-readable reason when success is false.
  - `error_code` string
  - `call_session_id` string, nullable
  - `auth_token` string, nullable
  - `participant_id` string, nullable
  - `expires_at` integer, nullable: UNIX timestamp when this resource or capability expires.
  - `is_host` boolean, nullable
  - `call_session` object, nullable: The call you are now in. Carries `call_session_id`, the `mode` and `media_tier` it is actually running in — which is what you got, not necessarily what you asked for when a call was already going — and who is in it.

## Other responses

- `400`: Invalid request payload.
- `401`: Missing or invalid partner key.
- `403`: Partner is not authorized for this operation.
- `409`: This call already holds as many people as it can take. Nothing is wrong with the request — wait for somebody to leave and send it again, or run a second call in another room.
- `429`: Rate limit exceeded — retry later.
- `500`: Internal server error.

---

[API](https://skmtc.dev/mindupload/apis/mind-upload-partner-api.md) · [All operations](https://skmtc.dev/mindupload/apis/mind-upload-partner-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mindupload/apis/mind-upload-partner-api/revisions/0371bdf78533?raw)
