Skip to content

Live Events API

Managed live streaming and event broadcasting.

Create events, manage stream keys and access tokens, control lifecycle (rehearsal → live → stop), and retrieve recordings, stats, and health. A separate set of public viewer endpoints resolves watch state for watch pages and embeds.


Management endpoints (authenticated)

Authentication: WAYSCloud API key or Keycloak JWT via Authorization: Bearer header or X-API-Key header.

Event lifecycle:

TransitionEndpointPrecondition
Create eventPOST /v1/live-events/events
Start rehearsalPOST /v1/live-events/events/{id}/rehearsal/startStatus: ready
Go livePOST /v1/live-events/events/{id}/live/startStatus: ready or rehearsal
StopPOST /v1/live-events/events/{id}/live/stopStatus: live or rehearsal
Rotate stream keyPOST /v1/live-events/events/{id}/stream-key/rotateNot while live
UpdatePATCH /v1/live-events/events/{id}Status: draft, scheduled, or ready
DeleteDELETE /v1/live-events/events/{id}Not while live, ending, or processing

RTMP ingest: rtmp://ingest.wayscloud.services/live with the stream key from event creation.


Viewer endpoints (public, no authentication)

Resolve event watch state for watch pages, embeds, and custom players. Verify viewer access for password- or token-protected events.

The resolve endpoint returns two state fields:

  • watch_state — canonical viewer-facing UI state (not_started, access_required, live, replay_available, etc.)
  • status — internal lifecycle state for diagnostics

Access control modes:

ModeBehavior
publicAnyone with the URL can watch. Playback URLs returned directly.
passwordViewer submits password → receives access grant + playback.
tokenViewer submits pre-shared token → receives access grant. Token consumed on playback start, not on verify.
tenant_onlyViewer must be authenticated as a member of the same customer account.

Watch pages: https://live.wayscloud.services/watch/{slug}Embed: https://live.wayscloud.services/embed/{slug}


Manage events in dashboard: my.wayscloud.services/live-events

Endpoints

MethodPathDescription
GET/v1/live-events/watch/{slug}Resolve watch state
POST/v1/live-events/watch/{slug}/verify-passwordVerify event password
POST/v1/live-events/watch/{slug}/verify-tokenVerify watch token
POST/v1/live-events/watch/{slug}/consume-grantConsume access grant on playback start
GET/v1/live-events/eventsList events
POST/v1/live-events/eventsCreate event
GET/v1/live-events/events/{event_id}Get event
PATCH/v1/live-events/events/{event_id}Update event
DELETE/v1/live-events/events/{event_id}Delete event
POST/v1/live-events/events/{event_id}/rehearsal/startStart rehearsal
POST/v1/live-events/events/{event_id}/live/startGo live
POST/v1/live-events/events/{event_id}/live/stopStop live
POST/v1/live-events/events/{event_id}/stream-key/rotateRotate stream key
GET/v1/live-events/events/{event_id}/recordingsList recordings
POST/v1/live-events/events/{event_id}/tokensCreate watch token
GET/v1/live-events/events/{event_id}/tokensList watch tokens
GET/v1/live-events/events/{event_id}/statsGet event statistics
GET/v1/live-events/limitsGet plan limits
GET/v1/live-events/events/{event_id}/ingestGet ingest details
GET/v1/live-events/events/{event_id}/healthGet event health
GET/v1/live-events/events/{event_id}/sessionsList sessions

GET /v1/live-events/watch/

Resolve watch state

Returns the current watch state for an event. The watch page polls this every 10 seconds to detect state changes (e.g. event goes live, replay becomes available).

Returns watch_state (viewer-facing UI state) and status (internal lifecycle). Playback objects are only included for public events — auth-required events must call verify-password or verify-token first.

Draft events are not publicly resolvable and return 404.

Response:

FieldTypeDescription
event_idstringUnique event identifier
slugstringURL-safe event identifier used in watch and embed URLs
namestringEvent display name
descriptionstringOptional event description
statusstringInternal lifecycle state. For UI logic, use watch_state instead. Values: scheduled, ready, rehearsal, live, ending, ended, processing, failed, cancelled
watch_statestringCanonical viewer-facing UI state. The watch page should render based on this field. Values: not_started, access_required, live, rehearsal_hidden, processing_replay, replay_available, ended_no_replay, cancelled
visibility_modestringAccess control model for this event Values: public, token, password, tenant_only
requires_authbooleanWhether the viewer must verify access (password, token, or login) before playback URLs are returned
auth_typestringWhich auth method is required, if any. Null for public events. Values: password, token, tenant_only
scheduled_start_atstringPlanned start time (ISO 8601)
scheduled_end_atstringPlanned end time (ISO 8601)
timezonestringIANA timezone for display purposes
countdown_enabledbooleanWhether to show a countdown timer before the event starts
playback_modestringWhich playback path is currently active Values: live, replay, none
live_playbackobjectLive stream playback info. Present only when the event is live and the viewer has access.
replay_playbackobjectReplay playback info. Present only when the event has ended with a published replay and the viewer has access.
embed_enabledbooleanWhether iframe embedding is permitted for this event
banner_urlstringOptional banner image URL for the watch page
logo_urlstringOptional logo image URL for the watch page

Example:

bash
curl https://api.wayscloud.services/v1/live-events/watch/{slug} \
  -H "X-API-Key: YOUR_API_KEY"

POST /v1/live-events/watch/{slug}/verify-password

Verify event password

Verifies the password for a password-protected event. On success, issues a short-lived access grant and returns the current playback information.

Failed attempts are logged for abuse detection.

Request Body:

FieldTypeDescription
passwordstringRequired. Event password set by the event organizer

Response:

FieldTypeDescription
verifiedbooleanWhether verification succeeded
access_grantstringShort-lived access grant. Pass this to consume-grant when playback starts.
access_grant_expires_atstringWhen the access grant expires. Viewer must re-verify after expiry.
watch_statestringCurrent watch state at time of verification Values: not_started, access_required, live, rehearsal_hidden, processing_replay, replay_available, ended_no_replay, cancelled
playback_modestringWhich playback path is active Values: live, replay, none
live_playbackobjectLive stream info, if event is live
replay_playbackobjectReplay info, if replay is available

Example:

bash
curl -X POST https://api.wayscloud.services/v1/live-events/watch/{slug}/verify-password \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{...}'

POST /v1/live-events/watch/{slug}/verify-token

Verify watch token

Validates an access token for a token-gated event. On success, issues a short-lived access grant and returns playback information.

The token use_count is not incremented here — it is consumed when playback actually starts via the consume-grant endpoint. This means opening the watch page and entering a token does not use up a token slot.

The token can also be supplied as a URL parameter on the watch page (?token=...) for auto-verification.

Request Body:

FieldTypeDescription
tokenstringRequired. Full watch token value as received when the token was created

Response:

FieldTypeDescription
verifiedbooleanWhether verification succeeded
access_grantstringShort-lived access grant. Pass this to consume-grant when playback starts.
access_grant_expires_atstringWhen the access grant expires. Viewer must re-verify after expiry.
watch_statestringCurrent watch state at time of verification Values: not_started, access_required, live, rehearsal_hidden, processing_replay, replay_available, ended_no_replay, cancelled
playback_modestringWhich playback path is active Values: live, replay, none
live_playbackobjectLive stream info, if event is live
replay_playbackobjectReplay info, if replay is available

Example:

bash
curl -X POST https://api.wayscloud.services/v1/live-events/watch/{slug}/verify-token \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{...}'

POST /v1/live-events/watch/{slug}/consume-grant

Consume access grant on playback start

Called by the watch page when video playback actually starts. Marks the access grant as consumed and increments the token use_count.

This is the point where a token use is actually spent. Idempotent — calling twice with the same grant returns already_consumed: true without incrementing again.

If the grant has expired, returns 403.

Request Body:

FieldTypeDescription
access_grantstringRequired. Access grant string (prefixed with ag_) received from verify-password or verify-token

Response:

FieldTypeDescription
consumedbooleanWhether the grant was consumed
already_consumedbooleanTrue if this grant was already consumed in a previous call. Token use_count is not incremented again.

Example:

bash
curl -X POST https://api.wayscloud.services/v1/live-events/watch/{slug}/consume-grant \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{...}'

GET /v1/live-events/events

List events

Returns a paginated list of the authenticated customer's events, ordered by creation date descending.

Example:

bash
curl https://api.wayscloud.services/v1/live-events/events \
  -H "X-API-Key: YOUR_API_KEY"

POST /v1/live-events/events

Create event

Creates a new live event, generates RTMP stream credentials, and activates the live_events service if this is the customer's first event.

Important: The stream_key is returned only at creation. Store it securely.

Request Body:

FieldTypeDescription
namestringRequired. Event display name
slugstringURL-safe slug. Auto-generated if omitted. Unique per customer.
descriptionstringOptional event description
scheduled_start_atstringPlanned start time (ISO 8601)
scheduled_end_atstringPlanned end time
timezonestring
visibility_modestringValues: public, token, password, tenant_only
passwordstringRequired when visibility_mode is password
record_enabledboolean
replay_enabledboolean
rehearsal_enabledboolean
auto_start_on_ingestbooleanAuto-transition to live when encoder connects
embed_enabledboolean
max_bitrate_kbpsintegerMax ingest bitrate (plan-dependent)
retention_daysintegerRecording retention period

Example:

bash
curl -X POST https://api.wayscloud.services/v1/live-events/events \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{...}'

GET /v1/live-events/events/

Get event

Returns full event detail including ingest status, current session, and recording count.

Example:

bash
curl https://api.wayscloud.services/v1/live-events/events/{event_id} \
  -H "X-API-Key: YOUR_API_KEY"

PATCH /v1/live-events/events/

Update event

Update event properties. Only allowed when status is draft, scheduled, or ready. Events that are live, ending, or processing cannot be modified.

Request Body:

FieldTypeDescription
namestring
descriptionstring
scheduled_start_atstring
scheduled_end_atstring
visibility_modestringValues: public, token, password, tenant_only
passwordstringRequired when changing to password visibility
record_enabledboolean
replay_enabledboolean
embed_enabledboolean
auto_start_on_ingestboolean

Example:

bash
curl -X PATCH https://api.wayscloud.services/v1/live-events/events/{event_id} \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{...}'

DELETE /v1/live-events/events/

Delete event

Soft-deletes the event. Retained for 30 days before permanent deletion. Not allowed while live, ending, or processing.

Example:

bash
curl -X DELETE https://api.wayscloud.services/v1/live-events/events/{event_id} \
  -H "X-API-Key: YOUR_API_KEY"

POST /v1/live-events/events/{event_id}/rehearsal/start

Start rehearsal

Transitions event to rehearsal. The encoder can connect and stream, but the watch page shows "in rehearsal" to viewers.

Precondition: Status must be ready.

Example:

bash
curl -X POST https://api.wayscloud.services/v1/live-events/events/{event_id}/rehearsal/start \
  -H "X-API-Key: YOUR_API_KEY"

POST /v1/live-events/events/{event_id}/live/start

Go live

Transitions event to live. Stream becomes visible to viewers. Recording starts if record_enabled.

Precondition: Status must be ready or rehearsal.

Example:

bash
curl -X POST https://api.wayscloud.services/v1/live-events/events/{event_id}/live/start \
  -H "X-API-Key: YOUR_API_KEY"

POST /v1/live-events/events/{event_id}/live/stop

Stop live

Stops the live event. Disconnects encoder, ends sessions, transitions to ending. Recordings are finalized automatically.

Precondition: Status must be live or rehearsal.

Example:

bash
curl -X POST https://api.wayscloud.services/v1/live-events/events/{event_id}/live/stop \
  -H "X-API-Key: YOUR_API_KEY"

POST /v1/live-events/events/{event_id}/stream-key/rotate

Rotate stream key

Generates a new stream key and invalidates the old one immediately. Encoder must be reconfigured.

Precondition: Status must NOT be live, ending, or processing.

Important: The new stream_key is shown only once in this response.

Example:

bash
curl -X POST https://api.wayscloud.services/v1/live-events/events/{event_id}/stream-key/rotate \
  -H "X-API-Key: YOUR_API_KEY"

GET /v1/live-events/events/{event_id}/recordings

List recordings

Returns recordings for the event. Each live session produces one recording when record_enabled is true.

Example:

bash
curl https://api.wayscloud.services/v1/live-events/events/{event_id}/recordings \
  -H "X-API-Key: YOUR_API_KEY"

POST /v1/live-events/events/{event_id}/tokens

Create watch token

Creates an access token for token-gated events (visibility_mode: token). The token value is returned only at creation.

max_uses counts actual playback sessions (via access-grant model), not token form submissions.

Request Body:

FieldTypeDescription
labelstringHuman-readable label
max_usesintegerMax playback sessions (consumed via access-grant model)
expires_atstringToken expiry

Example:

bash
curl -X POST https://api.wayscloud.services/v1/live-events/events/{event_id}/tokens \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{...}'

GET /v1/live-events/events/{event_id}/tokens

List watch tokens

Returns all watch tokens for the event. Token values are masked — only the prefix is shown.

Example:

bash
curl https://api.wayscloud.services/v1/live-events/events/{event_id}/tokens \
  -H "X-API-Key: YOUR_API_KEY"

GET /v1/live-events/events/{event_id}/stats

Get event statistics

Returns aggregated statistics for the event across all sessions.

Example:

bash
curl https://api.wayscloud.services/v1/live-events/events/{event_id}/stats \
  -H "X-API-Key: YOUR_API_KEY"

GET /v1/live-events/limits

Get plan limits

Returns the customer's current plan capabilities and usage for Live Events.

Example:

bash
curl https://api.wayscloud.services/v1/live-events/limits \
  -H "X-API-Key: YOUR_API_KEY"

GET /v1/live-events/events/{event_id}/ingest

Get ingest details

Returns ingest configuration for the event. Use this to configure your encoder (OBS, vMix, ffmpeg, etc.).

Example:

bash
curl https://api.wayscloud.services/v1/live-events/events/{event_id}/ingest \
  -H "X-API-Key: YOUR_API_KEY"

GET /v1/live-events/events/{event_id}/health

Get event health

Returns operator-friendly health signals for a live event. Data is best-effort — derived from periodic media server polling and may be slightly delayed.

Do not use for billing or SLA calculations.

Example:

bash
curl https://api.wayscloud.services/v1/live-events/events/{event_id}/health \
  -H "X-API-Key: YOUR_API_KEY"

GET /v1/live-events/events/{event_id}/sessions

List sessions

Returns the history of live sessions for the event. Each time an encoder connects and goes live, a new session is created.

Example:

bash
curl https://api.wayscloud.services/v1/live-events/events/{event_id}/sessions \
  -H "X-API-Key: YOUR_API_KEY"

WAYSCloud AS