Create live

Creates a live stream. Returns the ingest endpoint for your encoder, the playback URLs and the live status. A live is created as provisioning; region, quality_package and save_vod are set here and cannot be changed later.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

POST /lives

Creates a new live stream and returns the live object with the ingest endpoint for your encoder (OBS, etc.), the playback URLs and the IDs needed to broadcast.

📘

Authorization

Requires a valid Panda API token sent in the Authorization header (no Bearer prefix).

🚧

Maximum quality is 720p. Values above it — fhd, 4k, and the 1080p / 2160p entries of bitrate — are accepted and silently reduced to 720p. The live is created without an error. Set your encoder to 720p.

HTTP Method & Path

POST /lives

Base URL: https://api-v2.pandavideo.com.br

Authentication Requirements

Security SchemeHeaderNote
API KeyAuthorizationPanda API token (without Bearer prefix)

Parameters

NameInTypeRequiredDescription
AuthorizationheaderstringYesPanda API token (without Bearer prefix)

Request Body

Content-Type: application/json

Body Parameters

FieldTypeRequiredDefaultDescription
titlestringYesTitle of the live stream — shown in the live preview and used as the name of the recorded video. Minimum 3 characters.
regionstringNousWhere the stream is ingested: us or br. This is where your encoder publishes, not your viewers' region. It also affects the per-minute rate. If the stream key has a fixed region, that wins.
quality_packagestringNoderived from bitrateSets the whole quality ladder at once: sd, hd, fhd, 4k. Overrides bitrate when both are sent.
save_vodbooleanNoRecord the live as a video when it ends. With false no recording is produced and it cannot be recovered later.
stream_keystring (uuid)NoThe stream key value, as an alternative to stream_key_id.
stream_key_idstring (uuid)Noaccount default keyID of the stream key to attach to this live. Retrieve available keys with GET /live_stream_key.
bitratearray of stringsNo360p, 480p, 720pVideo qualities to enable: 240p, 360p, 480p, 720p, 1080p, 2160p.
scheduled_atstringNoDate and time with no timezone suffix. At most 30 days ahead.
latency_typestringNodefaultLatency profile: low, default or high.
active_dvrbooleanNotrueLets viewers rewind during the broadcast.
folder_idstring (uuid)NoFolder where the recorded video is saved.
📘

The body rejects unknown fields

Any key outside the list above returns 400 naming the offending field.

🚧

No timezone suffix. Send 2026-09-20T14:30:00. A trailing Z (2026-09-20T14:30:00Z), which toISOString() always adds, is rejected. Scheduling is limited to 30 days ahead.

⚠️

One live per stream key. To run two lives at the same time you need two stream keys. How many keys you can create comes from your plan, so the limit shows up when creating a key — POST /live_stream_key returns 400 the plan has no slot available to create stream key — not when creating a live.

📘

region is where you publish, not where your viewers are. It selects the server that receives the signal from your encoder. Picking the wrong one only makes your encoder publish further away; delivery to viewers does not depend on this field. It also affects the per-minute rate, and if the stream key was created with a fixed region, the key's region wins.

⚠️

save_vod: false means there will be no video afterwards. The live runs normally and simply leaves no recording, and it cannot be recovered later.

{
  "title": "Aula ao vivo 01",
  "region": "us",
  "quality_package": "hd",
  "save_vod": true,
  "active_dvr": true,
  "latency_type": "default"
}

Response

Success Response (200)

{
  "id": "{live_id}",
  "title": "Aula ao vivo 01",
  "status": "provisioning",
  "stream_key_id": "{stream_key_id}",
  "stream_key": "{stream_key}",
  "user_id": "USER_ID",
  "region": "us",
  "quality_package": "hd",
  "save_vod": true,
  "bitrate": ["360p", "480p", "720p"],
  "active_dvr": true,
  "latency_type": "default",
  "ingest_endpoint": "rtmp://vz-{hash}.us.pandavideo.live/live/{stream_key}",
  "ingest_hostname": "vz-{hash}.us.pandavideo.live",
  "rtmp": "rtmp://vz-{hash}.us.pandavideo.live/live",
  "playback_url": null,
  "live_hls": "https://b-vz-{hash}.tv.pandavideo.com.br/{live_id}/playlist.m3u8.live",
  "live_player": "https://player-vz-{hash}.tv.pandavideo.com.br/embed/live/?v={live_id}",
  "scheduled_at": null,
  "started_at": null,
  "ended_at": null,
  "vod_id": null,
  "video_id": null,
  "folder_id": null,
  "view_metrics": {},
  "config": {},
  "chat_id": null,
  "chat_status": null,
  "created_at": "2026-09-07T02:37:22.591Z",
  "current_time": "2026-09-07T02:41:51.204Z"
}
📘

Two things worth noticing in the response

The live is created as provisioning, and playback_url comes back null at this moment — it is filled in once the live is ready. The ingest_endpoint, on the other hand, comes back right away, and it is what you need to configure your encoder.

Response Schema

FieldTypeDescription
idstring (uuid)Unique identifier of the created live.
titlestringTitle of the live stream.
statusstringCurrent status — see the table below. A live is created as provisioning.
ingest_endpointstringFull RTMP publish URL, stream key included. This is what goes into your encoder.
ingest_hostnamestringIngest server only, without the key. Specific to your account.
playback_urlstring | nullPlayback URL for the live. null until the live is ready.
regionstringIngest region of this live: us or br.
quality_packagestringQuality ladder applied to this live.
save_vodbooleanWhether this live is being recorded.
video_idstring | nullVideo created from the recording, once ready.
view_metricsobjectAudience metrics of the live.
configobjectSettings of the live.
chat_idstring | nullChat of the live.
chat_statusstring | nullStatus of the live chat.
stream_key_idstring (uuid)Stream key attached to this live.
stream_keystring (uuid)Stream key value. Still returned — prefer ingest_endpoint, which already includes it.
rtmpstringIngest server without the key. Still returned — prefer ingest_endpoint.
live_hlsstringLegacy playback URL. Still returned — prefer playback_url.
live_playerstringPlayer URL to embed the live.
bitratearray of stringsEnabled video qualities.
active_dvrbooleanWhether DVR is enabled.
latency_typestringLatency profile.
folder_idstring (uuid) | nullFolder where the recorded video is saved.
scheduled_atstring | nullScheduled start, with no timezone suffix.
started_atstring | nullWhen the broadcast actually started.
ended_atstring | nullWhen the broadcast ended.
vod_idstring | nullRecording identifier.
created_atstringCreation timestamp.
current_timestringServer time when the response was produced.

Live status values

StatusMeaningFinal?
provisioningThe live is being prepared — it does not accept the encoder yet.No — moves to offline
offlineReady, waiting for the signal from your encoder.No
onlineOn air.No
finishingEnd requested, still finalizing.No — moves to finished
finishedEnded.Yes
finished_importedEnded, and the video of the recording has been created.Yes
expiredBecame ready but no signal ever arrived — it never went on air.No — it is recoverable
canceledCanceled.Yes
📘

expired is not a failure. If the live becomes ready but no signal ever arrives, it moves to expired. Do not create a new live: call POST /lives/{live_id}/regenerate and the same live goes back to provisioning, keeping its id, its stream key and its player URL.

Error Responses

400 Bad Request — the message names what went wrong:

// unknown field in the body
{ "errCode": "BadRequest", "errMsg": "must NOT have additional properties: X" }

// title shorter than 3 characters
{ "errCode": "BadRequest", "errMsg": "must NOT have fewer than 3 characters" }

// value outside the allowed list (the error lists what is accepted)
{ "errCode": "BadRequest", "errMsg": "must be equal to one of the allowed values: us,br." }

// scheduled_at with a timezone suffix, or more than 30 days ahead
{ "errCode": "BadRequest", "errMsg": "invalid scheduled_at property" }

// no valid stream key on the account
{ "errCode": "BadRequest", "errMsg": "Could not find any valid stream key" }

// trial account
{ "errCode": "BadRequest", "errMsg": "live is not available for trial accounts" }

// storage full
{ "errCode": "BadRequest", "errMsg": "storage limit reached. Free up space before creating a new live." }
⚠️

Three of these errors are returned in Portuguese. The API mixes languages, and this is the text your integration will actually receive:

  • stream_key já está em uso por uma live ativa (online/provisionando) ou expirada — regenere a live expirada
    The key is in use by an active or expired live — regenerate the expired one.
  • stream_key já está em uso por uma live ativa (online/provisionando)
    The key is in use by a live that is online or provisioning.
  • stream_key já possui uma live aguardando transmissão
    The key already has a live waiting for the broadcast.

All three say the same thing by different routes: that key is already taken. Use another key, finish the live that is using it, or — if the live is expired — call the regenerate endpoint. This is the most likely error family in day-to-day use, because it is one live per stream key.

  • 401 Unauthorized — missing or invalid API token.
  • 500 Internal Server Error — server-side error.

Example Usage

cURL

curl -X POST "https://api-v2.pandavideo.com.br/lives" \
  -H "Authorization: {api_key}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Aula ao vivo 01",
    "region": "us",
    "quality_package": "hd",
    "save_vod": true,
    "active_dvr": true,
    "latency_type": "default"
  }'
Body Params
string
required
length ≥ 3

Default title of the live stream - shown in the live preview and used as the name of the recorded video.

uuid

ID of the stream key to attach to this live. Retrieve available keys with GET /live_stream_key.

string

Schedules the live for a specific date and time, with no timezone suffix. A trailing Z is rejected with 400. Limited to 30 days ahead.

bitrate
array of strings

Video qualities to enable for adaptive playback. Values above 720p are accepted and silently reduced to 720p.

bitrate
Allowed:
string
enum

Latency profile of the live stream. low (5-7s), default (15-20s), high (60-70s).

Allowed:
boolean

Enables DVR so viewers can rewind during the broadcast.

uuid

Folder where the recorded video will be stored after the live ends.

string
enum
Defaults to us

Where the stream is ingested: us or br. Defaults to us. This is where your encoder publishes, not your viewers region. It also affects the per-minute rate. If the stream key has a fixed region, that wins.

Allowed:
string
enum

Sets the whole quality ladder at once: sd, hd, fhd, 4k. Overrides bitrate when both are sent. Maximum delivered quality is currently 720p.

Allowed:
boolean

Record the live as a video when it ends. With false no recording is produced and it cannot be recovered later.

uuid

The stream key value, as an alternative to stream_key_id.

Headers
string
enum
Defaults to application/json

Generated from available response content types

Allowed:
Responses

Language
Credentials
Header
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json