LiveStreamStartedPayload live.stream.started@1
Generated at from
openvibe-contracts v0.33.0 and
openvibe-sdk v0.5.0.
- Version
- 1.0.0
- Owner
- live
- Visibility
- public
- Status
- active
- Compatibility
- backward
- Decision
- ADR-004
- Schema
https://openvibe.network/contracts/events/payloads/live.stream.started.v1.json
live.stream.started v1 (OpenVibe.Live server/events/stream-events.js envelopeFor, fired by server/db/database.js createStream). A streams row went live: WebRTC/JSMPEG from the dashboard, RTMP ingest, WHIP, or an OpenRe.Stream session mirrored into Live. Written to Live's event_outbox in the transaction that inserts the row, so the event exists if and only if the stream did. Carries public channel facts only (the stream is listed publicly already); consumers such as Network's go-live notifications decide who hears about it. Never the stream key, the Live user id or the description. Envelope: subject { type: stream, id: <stream_id as a string>, revision: 1 }, visibility public, priority important, actor the streamer's user subject when Live knows it, else service:live.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
stream_id | integer | yes | Live's streams row id (the envelope subject id). |
|
channel | object | yes |
| |
channel.username | string | yes | The streamer's Live username (the channel slug). |
|
channel.display_name | string | yes | The display name, or the username when there is none. |
|
channel.url | string | yes | The channel page, https://openvibe.live/@<username, URI-encoded>. Events from Live before 4c70332 (2026-09-23) carry https://openvibe.live/<username>, which Live answers with a 301 to the @ address since that commit. |
|
channel.subject | object | The streamer's canonical subject; absent until Live has seen it (a Network sign-in or the subject backfill). |
| |
channel.subject.type | const | yes |
| |
channel.subject.id | string | yes |
| |
title | string | yes | ||
category | string | null | yes | null when the streamer chose none (the AI classifies the stream from what it shows). | |
protocol | enum | yes | How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp). |
|
is_nsfw | boolean | yes | ||
started_at | string | null | yes | UTC. null only for a row without a start time, which createStream never writes. |
|
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: no-subject-no-category
{
"stream_id": 4212,
"channel": {
"username": "jp_guy",
"display_name": "jp_guy",
"url": "https://openvibe.live/@jp_guy"
},
"title": "jp_guy's Stream",
"category": null,
"protocol": "rtmp",
"is_nsfw": false,
"started_at": "2026-09-23T18:02:11.000Z"
}Valid: with-subject
{
"stream_id": 4211,
"channel": {
"username": "alice",
"display_name": "Alice",
"url": "https://openvibe.live/@alice",
"subject": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}
},
"title": "Morning walk through Shinjuku",
"category": "irl",
"protocol": "webrtc",
"is_nsfw": false,
"started_at": "2026-09-23T18:02:11.000Z"
}Rejected: carries-ended-fields
{
"stream_id": 4211,
"channel": {
"username": "alice",
"display_name": "Alice",
"url": "https://openvibe.live/@alice",
"subject": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}
},
"title": "Morning walk through Shinjuku",
"category": "irl",
"protocol": "webrtc",
"is_nsfw": false,
"started_at": "2026-09-23T18:02:11.000Z",
"ended_at": "2026-09-23T19:02:11.000Z",
"duration_seconds": 3600
}Rejected: live-user-id
{
"stream_id": 4211,
"channel": {
"username": "alice",
"display_name": "Alice",
"url": "https://openvibe.live/@alice",
"subject": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
},
"user_id": 501
},
"title": "Morning walk through Shinjuku",
"category": "irl",
"protocol": "webrtc",
"is_nsfw": false,
"started_at": "2026-09-23T18:02:11.000Z"
}Rejected: unknown-protocol
{
"stream_id": 4211,
"channel": {
"username": "alice",
"display_name": "Alice",
"url": "https://openvibe.live/@alice",
"subject": {
"type": "user",
"id": "usr_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}
},
"title": "Morning walk through Shinjuku",
"category": "irl",
"protocol": "srt",
"is_nsfw": false,
"started_at": "2026-09-23T18:02:11.000Z"
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('live.stream.started@1', value); // { valid, errors: [{ path, message }] }