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:
| Transition | Endpoint | Precondition |
|---|---|---|
| Create event | POST /v1/live-events/events | — |
| Start rehearsal | POST /v1/live-events/events/{id}/rehearsal/start | Status: ready |
| Go live | POST /v1/live-events/events/{id}/live/start | Status: ready or rehearsal |
| Stop | POST /v1/live-events/events/{id}/live/stop | Status: live or rehearsal |
| Rotate stream key | POST /v1/live-events/events/{id}/stream-key/rotate | Not while live |
| Update | PATCH /v1/live-events/events/{id} | Status: draft, scheduled, or ready |
| Delete | DELETE /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:
| Mode | Behavior |
|---|---|
public | Anyone with the URL can watch. Playback URLs returned directly. |
password | Viewer submits password → receives access grant + playback. |
token | Viewer submits pre-shared token → receives access grant. Token consumed on playback start, not on verify. |
tenant_only | Viewer 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
| Method | Path | Description |
|---|---|---|
GET | /v1/live-events/watch/{slug} | Resolve watch state |
POST | /v1/live-events/watch/{slug}/verify-password | Verify event password |
POST | /v1/live-events/watch/{slug}/verify-token | Verify watch token |
POST | /v1/live-events/watch/{slug}/consume-grant | Consume access grant on playback start |
GET | /v1/live-events/events | List events |
POST | /v1/live-events/events | Create 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/start | Start rehearsal |
POST | /v1/live-events/events/{event_id}/live/start | Go live |
POST | /v1/live-events/events/{event_id}/live/stop | Stop live |
POST | /v1/live-events/events/{event_id}/stream-key/rotate | Rotate stream key |
GET | /v1/live-events/events/{event_id}/recordings | List recordings |
POST | /v1/live-events/events/{event_id}/tokens | Create watch token |
GET | /v1/live-events/events/{event_id}/tokens | List watch tokens |
GET | /v1/live-events/events/{event_id}/stats | Get event statistics |
GET | /v1/live-events/limits | Get plan limits |
GET | /v1/live-events/events/{event_id}/ingest | Get ingest details |
GET | /v1/live-events/events/{event_id}/health | Get event health |
GET | /v1/live-events/events/{event_id}/sessions | List 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:
| Field | Type | Description |
|---|---|---|
event_id | string | Unique event identifier |
slug | string | URL-safe event identifier used in watch and embed URLs |
name | string | Event display name |
description | string | Optional event description |
status | string | Internal lifecycle state. For UI logic, use watch_state instead. Values: scheduled, ready, rehearsal, live, ending, ended, processing, failed, cancelled |
watch_state | string | Canonical 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_mode | string | Access control model for this event Values: public, token, password, tenant_only |
requires_auth | boolean | Whether the viewer must verify access (password, token, or login) before playback URLs are returned |
auth_type | string | Which auth method is required, if any. Null for public events. Values: password, token, tenant_only |
scheduled_start_at | string | Planned start time (ISO 8601) |
scheduled_end_at | string | Planned end time (ISO 8601) |
timezone | string | IANA timezone for display purposes |
countdown_enabled | boolean | Whether to show a countdown timer before the event starts |
playback_mode | string | Which playback path is currently active Values: live, replay, none |
live_playback | object | Live stream playback info. Present only when the event is live and the viewer has access. |
replay_playback | object | Replay playback info. Present only when the event has ended with a published replay and the viewer has access. |
embed_enabled | boolean | Whether iframe embedding is permitted for this event |
banner_url | string | Optional banner image URL for the watch page |
logo_url | string | Optional logo image URL for the watch page |
Example:
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:
| Field | Type | Description |
|---|---|---|
password | string | Required. Event password set by the event organizer |
Response:
| Field | Type | Description |
|---|---|---|
verified | boolean | Whether verification succeeded |
access_grant | string | Short-lived access grant. Pass this to consume-grant when playback starts. |
access_grant_expires_at | string | When the access grant expires. Viewer must re-verify after expiry. |
watch_state | string | Current watch state at time of verification Values: not_started, access_required, live, rehearsal_hidden, processing_replay, replay_available, ended_no_replay, cancelled |
playback_mode | string | Which playback path is active Values: live, replay, none |
live_playback | object | Live stream info, if event is live |
replay_playback | object | Replay info, if replay is available |
Example:
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:
| Field | Type | Description |
|---|---|---|
token | string | Required. Full watch token value as received when the token was created |
Response:
| Field | Type | Description |
|---|---|---|
verified | boolean | Whether verification succeeded |
access_grant | string | Short-lived access grant. Pass this to consume-grant when playback starts. |
access_grant_expires_at | string | When the access grant expires. Viewer must re-verify after expiry. |
watch_state | string | Current watch state at time of verification Values: not_started, access_required, live, rehearsal_hidden, processing_replay, replay_available, ended_no_replay, cancelled |
playback_mode | string | Which playback path is active Values: live, replay, none |
live_playback | object | Live stream info, if event is live |
replay_playback | object | Replay info, if replay is available |
Example:
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:
| Field | Type | Description |
|---|---|---|
access_grant | string | Required. Access grant string (prefixed with ag_) received from verify-password or verify-token |
Response:
| Field | Type | Description |
|---|---|---|
consumed | boolean | Whether the grant was consumed |
already_consumed | boolean | True if this grant was already consumed in a previous call. Token use_count is not incremented again. |
Example:
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:
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:
| Field | Type | Description |
|---|---|---|
name | string | Required. Event display name |
slug | string | URL-safe slug. Auto-generated if omitted. Unique per customer. |
description | string | Optional event description |
scheduled_start_at | string | Planned start time (ISO 8601) |
scheduled_end_at | string | Planned end time |
timezone | string | |
visibility_mode | string | Values: public, token, password, tenant_only |
password | string | Required when visibility_mode is password |
record_enabled | boolean | |
replay_enabled | boolean | |
rehearsal_enabled | boolean | |
auto_start_on_ingest | boolean | Auto-transition to live when encoder connects |
embed_enabled | boolean | |
max_bitrate_kbps | integer | Max ingest bitrate (plan-dependent) |
retention_days | integer | Recording retention period |
Example:
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:
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:
| Field | Type | Description |
|---|---|---|
name | string | |
description | string | |
scheduled_start_at | string | |
scheduled_end_at | string | |
visibility_mode | string | Values: public, token, password, tenant_only |
password | string | Required when changing to password visibility |
record_enabled | boolean | |
replay_enabled | boolean | |
embed_enabled | boolean | |
auto_start_on_ingest | boolean |
Example:
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:
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:
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:
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:
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:
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:
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:
| Field | Type | Description |
|---|---|---|
label | string | Human-readable label |
max_uses | integer | Max playback sessions (consumed via access-grant model) |
expires_at | string | Token expiry |
Example:
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:
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:
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:
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:
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:
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:
curl https://api.wayscloud.services/v1/live-events/events/{event_id}/sessions \
-H "X-API-Key: YOUR_API_KEY"