openvibers/openvibe.contracts Commits
Contracts: the product at openre.stream is OpenRestream (owner, 2026-10-09) (#75)
Changes
@@@ -4,6 +4,13 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) thfrom `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,the notes were in the tag and commit messages (`git tag -n1`).++## 0.125.1 — 2026-10-09++++- The product at openre.stream is **OpenRestream** (owner, 2026-10-09): an open restreaming platform. Every name++ people read says so: `manifests/services/openre.json` (`name`, `site.name`, copy), the repository manifest (now++ `manifests/repositories/OpenRestream.json`, repository `OpenVibers/OpenRestream`, renamed on GitHub the same day),++ docs and schema descriptions. Ids are unchanged: service `openre`, `openre.*` capabilities and events.++## 0.125.0 — 2026-10-09- OpenVibe.News, OpenVibe.Reviews, OpenVibe.Trade, OpenVibe.Coupons and OpenRe.Stream are live: each serves its own@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/bot/pair-result.v1.json","title": "BotPairResult",-- "description": "bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRe configured there is no key: video is not_configured instead.",++ "description": "bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRestream configured there is no key: video is not_configured instead.","anyOf": [{"type": "object",@@@ -40,7 +40,7 @@"publish_key": {"type": "string","minLength": 1,-- "description": "The WHIP publish key, an ingest key OpenRe issued for the robot's stream: shown once."++ "description": "The WHIP publish key, an ingest key OpenRestream issued for the robot's stream: shown once."},"whip_url": {"type": "string",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/events/payloads/host.release.published.v1.json","title": "HostReleasePublishedPayload",-- "description": "host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRe, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.",++ "description": "host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRestream, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.","type": "object","required": ["service",@@@ -83,7 +83,7 @@"webrtc","rtmp"],-- "description": "How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp)."++ "description": "How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp)."},"is_nsfw": {"type": "boolean"@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/events/payloads/live.stream.started.v1.json","title": "LiveStreamStartedPayload",-- "description": "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.",++ "description": "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 OpenRestream 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.","type": "object","required": ["stream_id", "channel", "title", "category", "protocol", "is_nsfw", "started_at"],"additionalProperties": false,@@@ -23,7 +23,7 @@},"title": { "type": "string" },"category": { "type": ["string", "null"], "description": "null when the streamer chose none (the AI classifies the stream from what it shows)." },-- "protocol": { "enum": ["jsmpeg", "webrtc", "rtmp"], "description": "How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp)." },++ "protocol": { "enum": ["jsmpeg", "webrtc", "rtmp"], "description": "How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp)." },"is_nsfw": { "type": "boolean" },"started_at": { "type": ["string", "null"], "format": "date-time", "description": "UTC. null only for a row without a start time, which createStream never writes." }}@@@ -25,7 +25,7 @@},"slot_id": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",-- "description": "A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>)."++ "description": "A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>)."},"vod_id": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/destination.v1.json","title": "OpenreDestination",-- "description": "openre.destination@1: one restream destination of a stream on OpenRe.Stream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.",++ "description": "openre.destination@1: one restream destination of a stream on OpenRestream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.","type": "object","required": ["id",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/key-rotate-request.v1.json","title": "OpenreKeyRotateRequest",-- "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.",++ "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRestream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.","type": "object","properties": {"grace_seconds": {@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/key-rotate-result.v1.json","title": "OpenreKeyRotateResult",-- "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.",++ "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRestream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.","type": "object","required": ["key",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/output-read-result.v1.json","title": "OpenreOutputReadResult",-- "description": "openre.output-read-result@1: answers of openre.output.read on OpenRe.Stream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).",++ "description": "openre.output-read-result@1: answers of openre.output.read on OpenRestream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).","anyOf": [{"type": "object",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/output-write-request.v1.json","title": "OpenreOutputWriteRequest",-- "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRe.Stream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.",++ "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRestream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.","anyOf": [{"type": "object",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/output-write-result.v1.json","title": "OpenreOutputWriteResult",-- "description": "openre.output-write-result@1: answers of openre.output.write on OpenRe.Stream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).",++ "description": "openre.output-write-result@1: answers of openre.output.write on OpenRestream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).","anyOf": [{"type": "object",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/output.v1.json","title": "OpenreOutput",-- "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRe.Stream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.",++ "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRestream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.","type": "object","required": ["id",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/session-end-result.v1.json","title": "OpenreSessionEndResult",-- "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRe.Stream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).",++ "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRestream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).","type": "object","required": ["requested",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/session-read-result.v1.json","title": "OpenreSessionReadResult",-- "description": "openre.session-read-result@1: answers of openre.session.read on OpenRe.Stream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).",++ "description": "openre.session-read-result@1: answers of openre.session.read on OpenRestream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).","anyOf": [{"type": "object",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/stream-read-result.v1.json","title": "OpenreStreamReadResult",-- "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRe.Stream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.",++ "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRestream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.","anyOf": [{"type": "object",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/stream-write-request.v1.json","title": "OpenreStreamWriteRequest",-- "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRe.Stream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.",++ "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRestream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.","anyOf": [{"type": "object",@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/stream-write-result.v1.json","title": "OpenreStreamWriteResult",-- "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRe.Stream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.",++ "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRestream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.","type": "object","required": ["stream"@@@ -2,7 +2,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/stream.v1.json","title": "OpenreStream",-- "description": "openre.stream@1: one stream definition as OpenRe.Stream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.",++ "description": "openre.stream@1: one stream definition as OpenRestream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.","type": "object","required": ["id",@@@ -12,7 +12,7 @@ service id); **Runtime** is `STATUS.json.runtime`; **Database** is inferred from| Repository | Product | Authority it owns | Runtime | Database | Domain | SDK/Contracts pin | Deployment | Public/private | Current track ||---|---|---|---|---|---|---|---|---|---|| AFResume | — | — | — | — | — | — | — | — | — |--| OpenRe.Stream | OpenRe.Stream | openre.* | node 22 | PostgreSQL | openre.stream, ingest.openre.stream | contracts v0.76.0, sdk v0.26.0, shared v2.10.1 | deployed | internal | W7 |++| OpenRestream | OpenRestream | openre.* | node 22 | PostgreSQL | openre.stream, ingest.openre.stream | contracts v0.76.0, sdk v0.26.0, shared v2.10.1 | deployed | internal | W7 || OpenVibe.AI | OpenVibe.AI | ai.usage_summary | node 22 | PostgreSQL | ai.openvibe.services, ai.openvibe.network, openvibe.ai | contracts v0.86.0, sdk v0.26.0, shared v2.5.0 | deployed | live | W13 || OpenVibe.Billing | OpenVibe.Billing | billing.* | node >=22.0.0 | PostgreSQL | billing.openvibe.network | contracts v0.97.0, sdk v0.28.0, shared v2.9.0 | deployed | live | W8 || OpenVibe.Blog | Blog | blog.* | node 22 | PostgreSQL | openvibe.blog | contracts v0.97.0, sdk v0.26.0, shared v2.9.0, publishing v1.3.0 | deployed | live | W16 |@@@ -1,6 +1,6 @@--# ADR-009: Live versus OpenRe boundary++# ADR-009: Live versus OpenRestream boundary--**Status:** Accepted 2026-09-23. OpenRe.Stream deployed the same day (RTMP ingest + restream; WHIP, SFU and JSMPEG not yet ported). No slot has moved: per-slot cutover waits for the ingest DNS name, the public RTMP port and a broadcaster window.++**Status:** Accepted 2026-09-23. OpenRestream deployed the same day (RTMP ingest + restream; WHIP, SFU and JSMPEG not yet ported). No slot has moved: per-slot cutover waits for the ingest DNS name, the public RTMP port and a broadcaster window.## Context and current evidence@@@ -10,10 +10,10 @@## Decision--- **OpenRe.Stream owns transport:** stream definitions and keys, ingest sessions (RTMP, WHIP, WebRTC/SFU, JSMPEG), worker generations, restream destinations with health and logs, key rotation (`openre.key.rotate`), recording *requests* to Media, and the segment timeline.--- **Live owns presentation:** channels, discovery, watch pages, creator UX, chat embedding and moderation surfaces. Live asks OpenRe for sessions and playback descriptors; it never touches an encoder, socket or RTP port.++- **OpenRestream owns transport:** stream definitions and keys, ingest sessions (RTMP, WHIP, WebRTC/SFU, JSMPEG), worker generations, restream destinations with health and logs, key rotation (`openre.key.rotate`), recording *requests* to Media, and the segment timeline.++- **Live owns presentation:** channels, discovery, watch pages, creator UX, chat embedding and moderation surfaces. Live asks OpenRestream for sessions and playback descriptors; it never touches an encoder, socket or RTP port.- **Media owns recordings:** finalisation, storage and VOD objects stay in Media (ADR-006).--- Transport runs in worker processes separate from the OpenRe API. An API deploy starts a new worker generation for *new* sessions and lets old workers drain; no deploy of Live or the OpenRe API ends a live transport.++- Transport runs in worker processes separate from the OpenRestream API. An API deploy starts a new worker generation for *new* sessions and lets old workers drain; no deploy of Live or the OpenRestream API ends a live transport.- Lifecycle is published as events (`openre.session.started|ended`, `openre.output.failed`), not internal POSTs.## Alternatives considered@@@ -23,15 +23,15 @@## Migration consequences--OpenRe runs in parallel with Live's ingest and takes one protocol at a time (RTMP → WHIP → JSMPEG → SFU), each behind a per-channel switch. Each switch waits for a maintenance window agreed with the active broadcasters. Every stream key is rotated at the RTMP cutover.++OpenRestream runs in parallel with Live's ingest and takes one protocol at a time (RTMP → WHIP → JSMPEG → SFU), each behind a per-channel switch. Each switch waits for a maintenance window agreed with the active broadcasters. Every stream key is rotated at the RTMP cutover.## Rollback--Per protocol: flip the channel switch back to Live's in-process ingest. Live's ingest code stays until the last protocol has run on OpenRe for two weeks without a regression.++Per protocol: flip the channel switch back to Live's in-process ingest. Live's ingest code stays until the last protocol has run on OpenRestream for two weeks without a regression.## Acceptance tests- Deploying Live during a broadcast does not interrupt transport or recording.--- Deploying the OpenRe API does not end worker-owned transports.++- Deploying the OpenRestream API does not end worker-owned transports.- A failed restream destination never ends the source session.- Every stream key that existed before the cutover has been rotated.@@@ -131,7 +131,7 @@ There are two kinds of location, because most of what "near the user" buys is ch**Edge nodes are small, cheap machines in many places.** They run one agent with a few roles and hold no tenant data:- **probe**: ping, traceroute, DNS, TCP/UDP and HTTP checks toward a target;- **relay**: TURN for WebRTC calls, and game-server query relays;--- **ingest**: RTMP, SRT and WHIP accepted near the streamer, forwarded over the private network to the home region's OpenRe;++- **ingest**: RTMP, SRT and WHIP accepted near the streamer, forwarded over the private network to the home region's OpenRestream;- **cache**: media and page cache in front of R2 and origin.Edge nodes are listed in the registry with their location (city, country, coordinates, provider), roles, capacity and health. The same deploy controller (section 7) manages them.@@@ -43,7 +43,7 @@3. Switch reads and writes to PostgreSQL, keeping the SQLite file read-only for the N-1 window (ADR-016, 7 days) as the rollback.4. Then delete the SQLite file after a final backup.-- Order: Wiki, Blog, News, Reviews, Deals, Coupons, Trade, Tips, VIP, Search, Sources, Codes, Host, AI, Events, Chat, Community, Billing, Media, Tools, Games, OpenRe, Network, Live. Each migration is its own change, with its own rehearsal on a copy of the production data.++ Order: Wiki, Blog, News, Reviews, Deals, Coupons, Trade, Tips, VIP, Search, Sources, Codes, Host, AI, Events, Chat, Community, Billing, Media, Tools, Games, OpenRestream, Network, Live. Each migration is its own change, with its own rehearsal on a copy of the production data.7. **Sizing on the shared host**, until the data role has its own machine:- PostgreSQL: `shared_buffers` 1 GB, `effective_cache_size` 4 GB, `work_mem` 16 MB, `max_connections` 120, pooled behind PgBouncer;- Valkey: `maxmemory` 768 MB.@@@ -12,7 +12,7 @@ a Cozmo-based robot).- Chat commands (`!forward`, `!headup`, `!say`…) reached the robot with no permission check; Live fb3957f put them behindthe panel's rules as a stop-gap. Live also generates ~900 lines of Python per Cozmo owner (`routes.js`), becausebuttons are table rows rather than a profile.--- OpenRe's webrtc worker (75a5dd7) takes WHIP ingest and serves viewers; Media records; Events carries events; Network++- OpenRestream's webrtc worker (75a5dd7) takes WHIP ingest and serves viewers; Media records; Events carries events; Networkissues service tokens and delegated grants.- The owner's first robot, the Adeept ADR036, is a Raspberry Pi with Adeept's Robot HAT: a PCA9685 at I²C 0x5f drives thefour DC motors (channels 8–15) and the pan/tilt servos (0, 1); an ADS7830 at 0x48 reads battery voltage; ultrasonic,@@@ -43,8 +43,8 @@ a Cozmo-based robot).virtual environment with a systemd unit and the hardware watchdog.4. **Control runs over one outbound WebSocket per device; video over WHIP.** The device dials Bot(`wss://openvibe.bot/device`), authenticates with its credential, and keeps one connection for commands, telemetry and-- heartbeats; this works behind any home router and on an ESP32. The camera publishes to OpenRe over WHIP; viewers watch-- through OpenRe. Operators reach Bot over a WebSocket from the panel. A WebRTC data channel may be added later as a++ heartbeats; this works behind any home router and on an ESP32. The camera publishes to OpenRestream over WHIP; viewers watch++ through OpenRestream. Operators reach Bot over a WebSocket from the panel. A WebRTC data channel may be added later as asecond control transport when measured latency asks for it; the message set does not change.5. **One message set** (JSON, fields `v`, `seq`, `ts` on every frame): server→device `hello`, `config` (limits, heartbeat,the operator's allowed commands), `command` (`id` as an idempotency key, `kind` drive/actuator/ptz/say/display/halt,@@@ -93,7 +93,7 @@ a Cozmo-based robot).the `bot` service manifest and its events.- Network: a `bot` service principal; the `bot.robot.control` grant for Live and Chat (on behalf of viewers) and forActor agents (delegated).--- OpenRe: per-device publish keys for WHIP sessions created by Bot.++- OpenRestream: per-device publish keys for WHIP sessions created by Bot.- Live: the panel embed on channel pages, then the deletion in decision 10; Extensions `hardware/` becomes a pointer tothe Bot agent.@@@ -101,7 +101,7 @@ below is in `lib/ids.js` except `act`, `run` and `zon`, which are proposed and nCodes hosts no repositories, so `codes.repo` is gone. Media's index lists only its objects; its v1 vods and clips areprojections over objects (bigint ids) and are never listed. The person-owned resources — Bot robots and devices, Chat--rooms, Community spaces, OpenRe.Stream streams and Games characters — are step 8 phase 2, served like Network's++rooms, Community spaces, OpenRestream streams and Games characters — are step 8 phase 2, served like Network'suser-owned node principals: no OVRN, owner = user.Events' `queue` is future until Events stores a queue row; `act`, `run` and `zon` are proposed but are not in@@@ -12,7 +12,7 @@ Platform-wide decisions from the OpenVibe development roadmap (section 10). Each| [ADR-006](ADR-006-media-objects.md) | Media object, location and namespace model | Accepted 2026-09-22; implementation in progress (OpenVibe.Media Wave 4); amended 2026-09-24 (placement classes, local provider, infrequent access deferred) || [ADR-007](ADR-007-data-ownership.md) | Logical data ownership and database technology | Accepted 2026-09-22; amended 2026-09-24 (PgBouncer, replicas, SERIALIZABLE money paths, Redis non-authoritative) || [ADR-008](ADR-008-shared-packages.md) | Shared package publication and release manifests | Accepted 2026-09-22; implementation in progress (OpenVibe.Shared) |--| [ADR-009](ADR-009-live-openre-boundary.md) | Live versus OpenRe boundary | Accepted 2026-09-23; OpenRe deployed, no slot moved yet |++| [ADR-009](ADR-009-live-openre-boundary.md) | Live versus OpenRestream boundary | Accepted 2026-09-23; OpenRestream deployed, no slot moved yet || [ADR-010](ADR-010-chat-boundary.md) | Chat versus Live/Community boundary | Accepted and executed 2026-09-23 (Chat serves Live's chat) || [ADR-011](ADR-011-community-pastes.md) | Community paste and comment ownership migration | Accepted and executed 2026-09-22 || [ADR-012](ADR-012-economic-classification.md) | Billing vs loyalty, credits and currency classification | Accepted 2026-09-22; gates Waves 8-10; amended 2026-09-24 (transaction-type mapping, OpenCoins stays in Network, table substitution) |@@@ -1 +1 @@--{ "page_id": "pg_01JAB2C3D4E5F6G7H8J9K0MNPQ", "body": "Restreaming sends one encoder feed to several platforms. OpenRe.Stream does it server-side.", "expected_revision": 3, "workflow": { "id": "wiki.page_refresh", "run_id": "run_01JAB2C3D4E5F6G7H8J9K0MNPS", "model": "claude-sonnet-4-5" }, "note": "adds OpenRe" }++{ "page_id": "pg_01JAB2C3D4E5F6G7H8J9K0MNPQ", "body": "Restreaming sends one encoder feed to several platforms. OpenRestream does it server-side.", "expected_revision": 3, "workflow": { "id": "wiki.page_refresh", "run_id": "run_01JAB2C3D4E5F6G7H8J9K0MNPS", "model": "claude-sonnet-4-5" }, "note": "adds OpenRestream" }@@@ -1887,7 +1887,7 @@"slot_id": {"type": "string","pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",-- "description": "A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>)."++ "description": "A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>)."},"vod_id": {"type": "string",@@@ -25311,7 +25311,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/events/payloads/live.stream.started.v1.json","title": "LiveStreamStartedPayload",-- "description": "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.",++ "description": "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 OpenRestream 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.","type": "object","required": ["stream_id",@@@ -25390,7 +25390,7 @@"webrtc","rtmp"],-- "description": "How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp)."++ "description": "How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp)."},"is_nsfw": {"type": "boolean"@@@ -25495,7 +25495,7 @@"webrtc","rtmp"],-- "description": "How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp)."++ "description": "How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp)."},"is_nsfw": {"type": "boolean"@@@ -59917,7 +59917,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/destination.v1.json","title": "OpenreDestination",-- "description": "openre.destination@1: one restream destination of a stream on OpenRe.Stream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.",++ "description": "openre.destination@1: one restream destination of a stream on OpenRestream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.","type": "object","required": ["id",@@@ -60073,7 +60073,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/key-rotate-request.v1.json","title": "OpenreKeyRotateRequest",-- "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.",++ "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRestream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.","type": "object","properties": {"grace_seconds": {@@@ -60098,7 +60098,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/key-rotate-result.v1.json","title": "OpenreKeyRotateResult",-- "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.",++ "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRestream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.","type": "object","required": ["key",@@@ -60207,7 +60207,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/output-read-result.v1.json","title": "OpenreOutputReadResult",-- "description": "openre.output-read-result@1: answers of openre.output.read on OpenRe.Stream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).",++ "description": "openre.output-read-result@1: answers of openre.output.read on OpenRestream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).","anyOf": [{"type": "object",@@@ -60289,7 +60289,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/output-write-request.v1.json","title": "OpenreOutputWriteRequest",-- "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRe.Stream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.",++ "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRestream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.","anyOf": [{"type": "object",@@@ -60395,7 +60395,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/output-write-result.v1.json","title": "OpenreOutputWriteResult",-- "description": "openre.output-write-result@1: answers of openre.output.write on OpenRe.Stream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).",++ "description": "openre.output-write-result@1: answers of openre.output.write on OpenRestream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).","anyOf": [{"type": "object",@@@ -60473,7 +60473,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/output.v1.json","title": "OpenreOutput",-- "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRe.Stream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.",++ "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRestream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.","type": "object","required": ["id",@@@ -60572,7 +60572,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/session-end-result.v1.json","title": "OpenreSessionEndResult",-- "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRe.Stream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).",++ "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRestream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).","type": "object","required": ["requested",@@@ -60596,7 +60596,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/session-read-result.v1.json","title": "OpenreSessionReadResult",-- "description": "openre.session-read-result@1: answers of openre.session.read on OpenRe.Stream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).",++ "description": "openre.session-read-result@1: answers of openre.session.read on OpenRestream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).","anyOf": [{"type": "object",@@@ -60937,7 +60937,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/stream-read-result.v1.json","title": "OpenreStreamReadResult",-- "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRe.Stream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.",++ "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRestream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.","anyOf": [{"type": "object",@@@ -61036,7 +61036,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/stream-write-request.v1.json","title": "OpenreStreamWriteRequest",-- "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRe.Stream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.",++ "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRestream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.","anyOf": [{"type": "object",@@@ -61153,7 +61153,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/stream-write-result.v1.json","title": "OpenreStreamWriteResult",-- "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRe.Stream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.",++ "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRestream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.","type": "object","required": ["stream"@@@ -61197,7 +61197,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/openre/stream.v1.json","title": "OpenreStream",-- "description": "openre.stream@1: one stream definition as OpenRe.Stream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.",++ "description": "openre.stream@1: one stream definition as OpenRestream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.","type": "object","required": ["id",@@@ -62557,7 +62557,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/events/payloads/host.release.published.v1.json","title": "HostReleasePublishedPayload",-- "description": "host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRe, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.",++ "description": "host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRestream, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.","type": "object","required": ["service",@@@ -70783,7 +70783,7 @@"$schema": "https://json-schema.org/draft/2020-12/schema","$id": "https://openvibe.network/contracts/bot/pair-result.v1.json","title": "BotPairResult",-- "description": "bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRe configured there is no key: video is not_configured instead.",++ "description": "bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRestream configured there is no key: video is not_configured instead.","anyOf": [{"type": "object",@@@ -70821,7 +70821,7 @@"publish_key": {"type": "string","minLength": 1,-- "description": "The WHIP publish key, an ingest key OpenRe issued for the robot's stream: shown once."++ "description": "The WHIP publish key, an ingest key OpenRestream issued for the robot's stream: shown once."},"whip_url": {"type": "string",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Actor API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.AI API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Billing API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Blog API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Bot API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Chat API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Community API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Coupons API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Deals API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Events API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Food API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Games API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Host API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -129,7 +129,7 @@},{"service": "openre",-- "name": "OpenRe.Stream",++ "name": "OpenRestream","origin": "https://openre.stream","operations": 22,"capabilities": 7@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Inventory API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Live API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -1341,9 +1341,9 @@"schema": {"type": "string","pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",-- "description": "A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>)."++ "description": "A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>)."},-- "description": "A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>)."++ "description": "A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>)."},{"name": "vod_id",@@@ -2078,7 +2078,7 @@"slot_id": {"type": "string","pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",-- "description": "A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>)."++ "description": "A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>)."},"vod_id": {"type": "string",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Media API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Network API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.News API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -2,9 +2,9 @@"openapi": "3.1.0","jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {-- "title": "OpenRe.Stream API",-- "version": "0.125.0",-- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "title": "OpenRestream API",++ "version": "0.125.1",++ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -1478,7 +1478,7 @@},"openre.destination.v1": {"title": "OpenreDestination",-- "description": "openre.destination@1: one restream destination of a stream on OpenRe.Stream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.",++ "description": "openre.destination@1: one restream destination of a stream on OpenRestream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.","type": "object","required": ["id",@@@ -1627,7 +1627,7 @@},"openre.key-rotate-request.v1": {"title": "OpenreKeyRotateRequest",-- "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.",++ "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRestream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.","type": "object","properties": {"grace_seconds": {@@@ -1645,7 +1645,7 @@},"openre.key-rotate-result.v1": {"title": "OpenreKeyRotateResult",-- "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.",++ "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRestream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.","type": "object","required": ["key",@@@ -1747,7 +1747,7 @@},"openre.output-read-result.v1": {"title": "OpenreOutputReadResult",-- "description": "openre.output-read-result@1: answers of openre.output.read on OpenRe.Stream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).",++ "description": "openre.output-read-result@1: answers of openre.output.read on OpenRestream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).","anyOf": [{"type": "object",@@@ -1822,7 +1822,7 @@},"openre.output-write-request.v1": {"title": "OpenreOutputWriteRequest",-- "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRe.Stream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.",++ "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRestream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.","anyOf": [{"type": "object",@@@ -1921,7 +1921,7 @@},"openre.output-write-result.v1": {"title": "OpenreOutputWriteResult",-- "description": "openre.output-write-result@1: answers of openre.output.write on OpenRe.Stream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).",++ "description": "openre.output-write-result@1: answers of openre.output.write on OpenRestream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).","anyOf": [{"type": "object",@@@ -1992,7 +1992,7 @@},"openre.output.v1": {"title": "OpenreOutput",-- "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRe.Stream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.",++ "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRestream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.","type": "object","required": ["id",@@@ -2084,7 +2084,7 @@},"openre.session-end-result.v1": {"title": "OpenreSessionEndResult",-- "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRe.Stream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).",++ "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRestream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).","type": "object","required": ["requested",@@@ -2101,7 +2101,7 @@},"openre.session-read-result.v1": {"title": "OpenreSessionReadResult",-- "description": "openre.session-read-result@1: answers of openre.session.read on OpenRe.Stream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).",++ "description": "openre.session-read-result@1: answers of openre.session.read on OpenRestream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).","anyOf": [{"type": "object",@@@ -2435,7 +2435,7 @@},"openre.stream-read-result.v1": {"title": "OpenreStreamReadResult",-- "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRe.Stream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.",++ "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRestream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.","anyOf": [{"type": "object",@@@ -2527,7 +2527,7 @@},"openre.stream-write-request.v1": {"title": "OpenreStreamWriteRequest",-- "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRe.Stream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.",++ "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRestream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.","anyOf": [{"type": "object",@@@ -2637,7 +2637,7 @@},"openre.stream-write-result.v1": {"title": "OpenreStreamWriteResult",-- "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRe.Stream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.",++ "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRestream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.","type": "object","required": ["stream"@@@ -2674,7 +2674,7 @@},"openre.stream.v1": {"title": "OpenreStream",-- "description": "openre.stream@1: one stream definition as OpenRe.Stream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.",++ "description": "openre.stream@1: one stream definition as OpenRestream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.","type": "object","required": ["id",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Reviews API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Run API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Search API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Services API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Sources API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Tips API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Tools API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Trade API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.VIP API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Watch API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Wiki API",-- "version": "0.125.0",-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",++ "version": "0.125.1",++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.","license": {"name": "MIT","identifier": "MIT"@@@ -4110,7 +4110,7 @@ export interface LineageResolveRequest {*/stream_id?: string;/**-- * A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>).++ * A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>).*/slot_id?: string;/**@@@ -31808,7 +31808,7 @@ export interface EventsUsageRecordedPayload {/** [email protected] (owner: live) *//**-- * 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.++ * 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 OpenRestream 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.*/export interface LiveStreamStartedPayload {/**@@@ -31842,7 +31842,7 @@ export interface LiveStreamStartedPayload {*/category: string | null;/**-- * How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp).++ * How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp).*/protocol: "jsmpeg" | "webrtc" | "rtmp";is_nsfw: boolean;@@@ -31888,7 +31888,7 @@ export interface LiveStreamEndedPayload {*/category: string | null;/**-- * How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp).++ * How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp).*/protocol: "jsmpeg" | "webrtc" | "rtmp";is_nsfw: boolean;@@@ -53620,7 +53620,7 @@ export type SpaceThreadReadResult =/** [email protected] (owner: openre) *//**-- * openre.destination@1: one restream destination of a stream on OpenRe.Stream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.++ * openre.destination@1: one restream destination of a stream on OpenRestream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.*/export interface OpenreDestination {id: string;@@@ -53652,7 +53652,7 @@ export interface OpenreDestination {/** [email protected] (owner: openre) *//**-- * openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.++ * openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRestream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.*/export interface OpenreKeyRotateRequest {/**@@@ -53664,7 +53664,7 @@ export interface OpenreKeyRotateRequest {/** [email protected] (owner: openre) *//**-- * openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.++ * openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRestream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.*/export interface OpenreKeyRotateResult {key: {@@@ -53697,7 +53697,7 @@ export interface OpenreKeyRotateResult {/** [email protected] (owner: openre) *//**-- * openre.output-read-result@1: answers of openre.output.read on OpenRe.Stream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).++ * openre.output-read-result@1: answers of openre.output.read on OpenRestream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).*/export type OpenreOutputReadResult =| {@@@ -53720,7 +53720,7 @@ export type OpenreOutputReadResult =/** [email protected] (owner: openre) *//**-- * openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRe.Stream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.++ * openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRestream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.*/export type OpenreOutputWriteRequest =| {@@@ -53742,7 +53742,7 @@ export type OpenreOutputWriteRequest =/** [email protected] (owner: openre) *//**-- * openre.output-write-result@1: answers of openre.output.write on OpenRe.Stream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).++ * openre.output-write-result@1: answers of openre.output.write on OpenRestream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).*/export type OpenreOutputWriteResult =| {@@@ -53765,7 +53765,7 @@ export type OpenreOutputWriteResult =/** [email protected] (owner: openre) *//**-- * openre.output@1: one restream output (a destination running for a live session) on OpenRe.Stream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.++ * openre.output@1: one restream output (a destination running for a live session) on OpenRestream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.*/export interface OpenreOutput {id: string;@@@ -53789,7 +53789,7 @@ export interface OpenreOutput {/** [email protected] (owner: openre) *//**-- * openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRe.Stream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).++ * openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRestream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).*/export interface OpenreSessionEndResult {requested: boolean;@@@ -53798,7 +53798,7 @@ export interface OpenreSessionEndResult {/** [email protected] (owner: openre) *//**-- * openre.session-read-result@1: answers of openre.session.read on OpenRe.Stream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).++ * openre.session-read-result@1: answers of openre.session.read on OpenRestream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).*/export type OpenreSessionReadResult =| {@@@ -53878,7 +53878,7 @@ export type OpenreSessionReadResult =/** [email protected] (owner: openre) *//**-- * openre.stream-read-result@1: answers of openre.stream.read on OpenRe.Stream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.++ * openre.stream-read-result@1: answers of openre.stream.read on OpenRestream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.*/export type OpenreStreamReadResult =| {@@@ -53901,7 +53901,7 @@ export type OpenreStreamReadResult =/** [email protected] (owner: openre) *//**-- * openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRe.Stream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.++ * openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRestream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.*/export type OpenreStreamWriteRequest =| {@@@ -54278,7 +54278,7 @@ export type OpenreStreamWriteRequest =/** [email protected] (owner: openre) *//**-- * openre.stream-write-result@1: answers of openre.stream.write on OpenRe.Stream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.++ * openre.stream-write-result@1: answers of openre.stream.write on OpenRestream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.*/export interface OpenreStreamWriteResult {stream: OpenreStream;@@@ -54295,7 +54295,7 @@ export interface OpenreStreamWriteResult {/** [email protected] (owner: openre) *//**-- * openre.stream@1: one stream definition as OpenRe.Stream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.++ * openre.stream@1: one stream definition as OpenRestream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.*/export interface OpenreStream {id: string;@@@ -54686,7 +54686,7 @@ export interface HostDeployActivatedPayload {/** [email protected] (owner: host) *//**-- * host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRe, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.++ * host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRestream, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.*/export interface HostReleasePublishedPayload {/**@@@ -57922,7 +57922,7 @@ export interface BotPairRequest {/** [email protected] (owner: bot) *//**-- * bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRe configured there is no key: video is not_configured instead.++ * bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRestream configured there is no key: video is not_configured instead.*/export type BotPairResult =| {@@@ -57934,7 +57934,7 @@ export type BotPairResult =*/credential?: string;/**-- * The WHIP publish key, an ingest key OpenRe issued for the robot's stream: shown once.++ * The WHIP publish key, an ingest key OpenRestream issued for the robot's stream: shown once.*/publish_key: string;/**@@@ -70,7 +70,7 @@ before anyone relies on either.| OpenVibe.Trade | AGPL-3.0-only | AGPL-3.0 | consistent || OpenVibe.VIP | AGPL-3.0-only | AGPL-3.0 | consistent || OpenVibe.Wiki | AGPL-3.0-only | AGPL-3.0 | consistent |--| OpenRe.Stream | AGPL-3.0-only | AGPL-3.0 | consistent |++| OpenRestream | AGPL-3.0-only | AGPL-3.0 | consistent |Dependency review: every repository pins its OpenVibe packages to release tags, CI runs the tests and thepin-drift check, and gitleaks scans history. A licence review of third-party dependencies is part of WS-R@@@ -215,7 +215,7 @@{"id": "staff.site.view","minRole": "admin",-- "description": "Read operations data: diagnostics, statistics, all streams, storage, analytics, OpenRe status, money state and AI usage.",++ "description": "Read operations data: diagnostics, statistics, all streams, storage, analytics, OpenRestream status, money state and AI usage.","gates": {"live": ["admin/routes.js:52 → 55,67,305,483,522,569,969,1025,1125",@@@ -39,7 +39,7 @@},{"question": "Which sites does it cover?",-- "answer": "Every OpenVibe product site, live or coming, from OpenVibe.Live to OpenRe.Stream. Each one has its own page with its questions and where it lives."++ "answer": "Every OpenVibe product site, live or coming, from OpenVibe.Live to OpenRestream. Each one has its own page with its questions and where it lives."}],"keywords": "openvibe help, openvibe support, help center, support tickets, troubleshooting",@@@ -36,7 +36,7 @@"note": "Streams, recordings and clips live on OpenVibe.Live today."},{-- "label": "OpenRe.Stream",++ "label": "OpenRestream","url": "https://openre.stream","note": "Restreaming to many platforms is the sibling product."}ddeleted file mode 100644@@@ -1,26 +0,0 @@--{-- "name": "OpenRe.Stream",-- "repository": "OpenVibers/OpenRe.Stream",-- "service": "openre",-- "product": "OpenRe.Stream",-- "stage": "alpha",-- "version": "0.1.0",-- "runtime": "node 22",-- "database": "PostgreSQL",-- "migrations": 3,-- "authority": [-- "openre.*"-- ],-- "domains": [-- "openre.stream",-- "ingest.openre.stream"-- ],-- "pins": {-- "openvibe-contracts": "v0.76.0",-- "openvibe-sdk": "v0.26.0",-- "openvibe-shared": "v2.10.1"-- },-- "deployed": true,-- "exposure": "internal",-- "track": "W7"--}nnew file mode 100644@@@ -0,0 +1,26 @@++{++ "name": "OpenRestream",++ "repository": "OpenVibers/OpenRestream",++ "service": "openre",++ "product": "OpenRestream",++ "stage": "alpha",++ "version": "0.1.0",++ "runtime": "node 22",++ "database": "PostgreSQL",++ "migrations": 3,++ "authority": [++ "openre.*"++ ],++ "domains": [++ "openre.stream",++ "ingest.openre.stream"++ ],++ "pins": {++ "openvibe-contracts": "v0.76.0",++ "openvibe-sdk": "v0.26.0",++ "openvibe-shared": "v2.10.1"++ },++ "deployed": true,++ "exposure": "internal",++ "track": "W7"++}@@@ -4,9 +4,9 @@"openvibe-contracts": ">=0.13.0 <1.0.0"},"id": "openre",-- "name": "OpenRe.Stream",++ "name": "OpenRestream","status": "alpha",-- "repository": "OpenVibers/OpenRe.Stream",++ "repository": "OpenVibers/OpenRestream","domains": ["openre.stream","ingest.openre.stream"@@@ -20,7 +20,7 @@"publicSite": "service"},"site": {-- "name": "OpenRe.Stream",++ "name": "OpenRestream","icon": "stream","tagline": "Restream anywhere","what": "Ingest once and send the stream to every platform at once; keys, destinations and output health in one place.",@@@ -28,7 +28,7 @@"position": 18,"tld": "stream","accent": "#ef4444",-- "description": "OpenRe.Stream is OpenVibe's open streaming engine, split out of OpenVibe.Live. Go live from a web browser with no OBS, no downloads and no follower minimum, or send RTMP or WHIP from any encoder, and restream to Twitch, YouTube, Kick and any RTMP, RTMPS or SRT destination. Browser broadcasts start on OpenVibe.Live today, and move to OpenRe.Stream ingest channel by channel.",++ "description": "OpenRestream is OpenVibe's open streaming engine, split out of OpenVibe.Live. Go live from a web browser with no OBS, no downloads and no follower minimum, or send RTMP or WHIP from any encoder, and restream to Twitch, YouTube, Kick and any RTMP, RTMPS or SRT destination. Browser broadcasts start on OpenVibe.Live today, and move to OpenRestream ingest channel by channel.","pillars": [{"title": "Browser go-live",@@@ -88,9 +88,9 @@"url": "https://openvibe.live/docs/go-live-in-your-browser"}},-- "launch": "the stream slots to move from OpenVibe.Live's ingest to OpenRe.Stream, one at a time; no stream uses it yet",++ "launch": "the stream slots to move from OpenVibe.Live's ingest to OpenRestream, one at a time; no stream uses it yet","relationships": {-- "plannedRepo": "OpenRe.Stream",++ "plannedRepo": "OpenRestream","meanwhile": [{"label": "Go live on OpenVibe.Live",@@@ -1,6 +1,6 @@{"name": "openvibe-contracts",-- "version": "0.125.0",++ "version": "0.125.1","description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.","main": "index.js","types": "generated/typescript/index.d.ts",
@@ -4,6 +4,13 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
@@ -4,6 +4,13 @@ All notable changes to `openvibe-contracts`. Releases are git tags (`vX.Y.Z`) th
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
from `https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/<tag>`. Before v0.30.0,
the notes were in the tag and commit messages (`git tag -n1`).
the notes were in the tag and commit messages (`git tag -n1`).
+## 0.125.1 — 2026-10-09
+
+- The product at openre.stream is **OpenRestream** (owner, 2026-10-09): an open restreaming platform. Every name
+ people read says so: `manifests/services/openre.json` (`name`, `site.name`, copy), the repository manifest (now
+ `manifests/repositories/OpenRestream.json`, repository `OpenVibers/OpenRestream`, renamed on GitHub the same day),
+ docs and schema descriptions. Ids are unchanged: service `openre`, `openre.*` capabilities and events.
+
## 0.125.0 — 2026-10-09
## 0.125.0 — 2026-10-09
- OpenVibe.News, OpenVibe.Reviews, OpenVibe.Trade, OpenVibe.Coupons and OpenRe.Stream are live: each serves its own
- OpenVibe.News, OpenVibe.Reviews, OpenVibe.Trade, OpenVibe.Coupons and OpenRe.Stream are live: each serves its own
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/bot/pair-result.v1.json",
"$id": "https://openvibe.network/contracts/bot/pair-result.v1.json",
"title": "BotPairResult",
"title": "BotPairResult",
- "description": "bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRe configured there is no key: video is not_configured instead.",
+ "description": "bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRestream configured there is no key: video is not_configured instead.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -40,7 +40,7 @@
@@ -40,7 +40,7 @@
"publish_key": {
"publish_key": {
"type": "string",
"type": "string",
"minLength": 1,
"minLength": 1,
- "description": "The WHIP publish key, an ingest key OpenRe issued for the robot's stream: shown once."
+ "description": "The WHIP publish key, an ingest key OpenRestream issued for the robot's stream: shown once."
},
},
"whip_url": {
"whip_url": {
"type": "string",
"type": "string",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/events/payloads/host.release.published.v1.json",
"$id": "https://openvibe.network/contracts/events/payloads/host.release.published.v1.json",
"title": "HostReleasePublishedPayload",
"title": "HostReleasePublishedPayload",
- "description": "host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRe, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.",
+ "description": "host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRestream, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.",
"type": "object",
"type": "object",
"required": [
"required": [
"service",
"service",
@@ -83,7 +83,7 @@
@@ -83,7 +83,7 @@
"webrtc",
"webrtc",
"rtmp"
"rtmp"
],
],
- "description": "How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp)."
+ "description": "How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp)."
},
},
"is_nsfw": {
"is_nsfw": {
"type": "boolean"
"type": "boolean"
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/events/payloads/live.stream.started.v1.json",
"$id": "https://openvibe.network/contracts/events/payloads/live.stream.started.v1.json",
"title": "LiveStreamStartedPayload",
"title": "LiveStreamStartedPayload",
- "description": "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.",
+ "description": "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 OpenRestream 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.",
"type": "object",
"type": "object",
"required": ["stream_id", "channel", "title", "category", "protocol", "is_nsfw", "started_at"],
"required": ["stream_id", "channel", "title", "category", "protocol", "is_nsfw", "started_at"],
"additionalProperties": false,
"additionalProperties": false,
@@ -23,7 +23,7 @@
@@ -23,7 +23,7 @@
},
},
"title": { "type": "string" },
"title": { "type": "string" },
"category": { "type": ["string", "null"], "description": "null when the streamer chose none (the AI classifies the stream from what it shows)." },
"category": { "type": ["string", "null"], "description": "null when the streamer chose none (the AI classifies the stream from what it shows)." },
- "protocol": { "enum": ["jsmpeg", "webrtc", "rtmp"], "description": "How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp)." },
+ "protocol": { "enum": ["jsmpeg", "webrtc", "rtmp"], "description": "How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp)." },
"is_nsfw": { "type": "boolean" },
"is_nsfw": { "type": "boolean" },
"started_at": { "type": ["string", "null"], "format": "date-time", "description": "UTC. null only for a row without a start time, which createStream never writes." }
"started_at": { "type": ["string", "null"], "format": "date-time", "description": "UTC. null only for a row without a start time, which createStream never writes." }
}
}
@@ -25,7 +25,7 @@
@@ -25,7 +25,7 @@
},
},
"slot_id": {
"slot_id": {
"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
- "description": "A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>)."
+ "description": "A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>)."
},
},
"vod_id": {
"vod_id": {
"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/destination.v1.json",
"$id": "https://openvibe.network/contracts/openre/destination.v1.json",
"title": "OpenreDestination",
"title": "OpenreDestination",
- "description": "openre.destination@1: one restream destination of a stream on OpenRe.Stream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.",
+ "description": "openre.destination@1: one restream destination of a stream on OpenRestream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.",
"type": "object",
"type": "object",
"required": [
"required": [
"id",
"id",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/key-rotate-request.v1.json",
"$id": "https://openvibe.network/contracts/openre/key-rotate-request.v1.json",
"title": "OpenreKeyRotateRequest",
"title": "OpenreKeyRotateRequest",
- "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.",
+ "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRestream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.",
"type": "object",
"type": "object",
"properties": {
"properties": {
"grace_seconds": {
"grace_seconds": {
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/key-rotate-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/key-rotate-result.v1.json",
"title": "OpenreKeyRotateResult",
"title": "OpenreKeyRotateResult",
- "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.",
+ "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRestream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.",
"type": "object",
"type": "object",
"required": [
"required": [
"key",
"key",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/output-read-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/output-read-result.v1.json",
"title": "OpenreOutputReadResult",
"title": "OpenreOutputReadResult",
- "description": "openre.output-read-result@1: answers of openre.output.read on OpenRe.Stream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).",
+ "description": "openre.output-read-result@1: answers of openre.output.read on OpenRestream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/output-write-request.v1.json",
"$id": "https://openvibe.network/contracts/openre/output-write-request.v1.json",
"title": "OpenreOutputWriteRequest",
"title": "OpenreOutputWriteRequest",
- "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRe.Stream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.",
+ "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRestream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/output-write-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/output-write-result.v1.json",
"title": "OpenreOutputWriteResult",
"title": "OpenreOutputWriteResult",
- "description": "openre.output-write-result@1: answers of openre.output.write on OpenRe.Stream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).",
+ "description": "openre.output-write-result@1: answers of openre.output.write on OpenRestream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/output.v1.json",
"$id": "https://openvibe.network/contracts/openre/output.v1.json",
"title": "OpenreOutput",
"title": "OpenreOutput",
- "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRe.Stream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.",
+ "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRestream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.",
"type": "object",
"type": "object",
"required": [
"required": [
"id",
"id",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/session-end-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/session-end-result.v1.json",
"title": "OpenreSessionEndResult",
"title": "OpenreSessionEndResult",
- "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRe.Stream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).",
+ "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRestream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).",
"type": "object",
"type": "object",
"required": [
"required": [
"requested",
"requested",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/session-read-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/session-read-result.v1.json",
"title": "OpenreSessionReadResult",
"title": "OpenreSessionReadResult",
- "description": "openre.session-read-result@1: answers of openre.session.read on OpenRe.Stream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).",
+ "description": "openre.session-read-result@1: answers of openre.session.read on OpenRestream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/stream-read-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/stream-read-result.v1.json",
"title": "OpenreStreamReadResult",
"title": "OpenreStreamReadResult",
- "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRe.Stream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.",
+ "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRestream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/stream-write-request.v1.json",
"$id": "https://openvibe.network/contracts/openre/stream-write-request.v1.json",
"title": "OpenreStreamWriteRequest",
"title": "OpenreStreamWriteRequest",
- "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRe.Stream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.",
+ "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRestream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/stream-write-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/stream-write-result.v1.json",
"title": "OpenreStreamWriteResult",
"title": "OpenreStreamWriteResult",
- "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRe.Stream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.",
+ "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRestream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.",
"type": "object",
"type": "object",
"required": [
"required": [
"stream"
"stream"
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/stream.v1.json",
"$id": "https://openvibe.network/contracts/openre/stream.v1.json",
"title": "OpenreStream",
"title": "OpenreStream",
- "description": "openre.stream@1: one stream definition as OpenRe.Stream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.",
+ "description": "openre.stream@1: one stream definition as OpenRestream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.",
"type": "object",
"type": "object",
"required": [
"required": [
"id",
"id",
@@ -12,7 +12,7 @@ service id); **Runtime** is `STATUS.json.runtime`; **Database** is inferred from
@@ -12,7 +12,7 @@ service id); **Runtime** is `STATUS.json.runtime`; **Database** is inferred from
| Repository | Product | Authority it owns | Runtime | Database | Domain | SDK/Contracts pin | Deployment | Public/private | Current track |
| Repository | Product | Authority it owns | Runtime | Database | Domain | SDK/Contracts pin | Deployment | Public/private | Current track |
|---|---|---|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|---|---|---|
| AFResume | — | — | — | — | — | — | — | — | — |
| AFResume | — | — | — | — | — | — | — | — | — |
-| OpenRe.Stream | OpenRe.Stream | openre.* | node 22 | PostgreSQL | openre.stream, ingest.openre.stream | contracts v0.76.0, sdk v0.26.0, shared v2.10.1 | deployed | internal | W7 |
+| OpenRestream | OpenRestream | openre.* | node 22 | PostgreSQL | openre.stream, ingest.openre.stream | contracts v0.76.0, sdk v0.26.0, shared v2.10.1 | deployed | internal | W7 |
| OpenVibe.AI | OpenVibe.AI | ai.usage_summary | node 22 | PostgreSQL | ai.openvibe.services, ai.openvibe.network, openvibe.ai | contracts v0.86.0, sdk v0.26.0, shared v2.5.0 | deployed | live | W13 |
| OpenVibe.AI | OpenVibe.AI | ai.usage_summary | node 22 | PostgreSQL | ai.openvibe.services, ai.openvibe.network, openvibe.ai | contracts v0.86.0, sdk v0.26.0, shared v2.5.0 | deployed | live | W13 |
| OpenVibe.Billing | OpenVibe.Billing | billing.* | node >=22.0.0 | PostgreSQL | billing.openvibe.network | contracts v0.97.0, sdk v0.28.0, shared v2.9.0 | deployed | live | W8 |
| OpenVibe.Billing | OpenVibe.Billing | billing.* | node >=22.0.0 | PostgreSQL | billing.openvibe.network | contracts v0.97.0, sdk v0.28.0, shared v2.9.0 | deployed | live | W8 |
| OpenVibe.Blog | Blog | blog.* | node 22 | PostgreSQL | openvibe.blog | contracts v0.97.0, sdk v0.26.0, shared v2.9.0, publishing v1.3.0 | deployed | live | W16 |
| OpenVibe.Blog | Blog | blog.* | node 22 | PostgreSQL | openvibe.blog | contracts v0.97.0, sdk v0.26.0, shared v2.9.0, publishing v1.3.0 | deployed | live | W16 |
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
-# ADR-009: Live versus OpenRe boundary
+# ADR-009: Live versus OpenRestream boundary
-**Status:** Accepted 2026-09-23. OpenRe.Stream deployed the same day (RTMP ingest + restream; WHIP, SFU and JSMPEG not yet ported). No slot has moved: per-slot cutover waits for the ingest DNS name, the public RTMP port and a broadcaster window.
+**Status:** Accepted 2026-09-23. OpenRestream deployed the same day (RTMP ingest + restream; WHIP, SFU and JSMPEG not yet ported). No slot has moved: per-slot cutover waits for the ingest DNS name, the public RTMP port and a broadcaster window.
## Context and current evidence
## Context and current evidence
@@ -10,10 +10,10 @@
@@ -10,10 +10,10 @@
## Decision
## Decision
-- **OpenRe.Stream owns transport:** stream definitions and keys, ingest sessions (RTMP, WHIP, WebRTC/SFU, JSMPEG), worker generations, restream destinations with health and logs, key rotation (`openre.key.rotate`), recording *requests* to Media, and the segment timeline.
-- **Live owns presentation:** channels, discovery, watch pages, creator UX, chat embedding and moderation surfaces. Live asks OpenRe for sessions and playback descriptors; it never touches an encoder, socket or RTP port.
+- **OpenRestream owns transport:** stream definitions and keys, ingest sessions (RTMP, WHIP, WebRTC/SFU, JSMPEG), worker generations, restream destinations with health and logs, key rotation (`openre.key.rotate`), recording *requests* to Media, and the segment timeline.
+- **Live owns presentation:** channels, discovery, watch pages, creator UX, chat embedding and moderation surfaces. Live asks OpenRestream for sessions and playback descriptors; it never touches an encoder, socket or RTP port.
- **Media owns recordings:** finalisation, storage and VOD objects stay in Media (ADR-006).
- **Media owns recordings:** finalisation, storage and VOD objects stay in Media (ADR-006).
-- Transport runs in worker processes separate from the OpenRe API. An API deploy starts a new worker generation for *new* sessions and lets old workers drain; no deploy of Live or the OpenRe API ends a live transport.
+- Transport runs in worker processes separate from the OpenRestream API. An API deploy starts a new worker generation for *new* sessions and lets old workers drain; no deploy of Live or the OpenRestream API ends a live transport.
- Lifecycle is published as events (`openre.session.started|ended`, `openre.output.failed`), not internal POSTs.
- Lifecycle is published as events (`openre.session.started|ended`, `openre.output.failed`), not internal POSTs.
## Alternatives considered
## Alternatives considered
@@ -23,15 +23,15 @@
@@ -23,15 +23,15 @@
## Migration consequences
## Migration consequences
-OpenRe runs in parallel with Live's ingest and takes one protocol at a time (RTMP → WHIP → JSMPEG → SFU), each behind a per-channel switch. Each switch waits for a maintenance window agreed with the active broadcasters. Every stream key is rotated at the RTMP cutover.
+OpenRestream runs in parallel with Live's ingest and takes one protocol at a time (RTMP → WHIP → JSMPEG → SFU), each behind a per-channel switch. Each switch waits for a maintenance window agreed with the active broadcasters. Every stream key is rotated at the RTMP cutover.
## Rollback
## Rollback
-Per protocol: flip the channel switch back to Live's in-process ingest. Live's ingest code stays until the last protocol has run on OpenRe for two weeks without a regression.
+Per protocol: flip the channel switch back to Live's in-process ingest. Live's ingest code stays until the last protocol has run on OpenRestream for two weeks without a regression.
## Acceptance tests
## Acceptance tests
- Deploying Live during a broadcast does not interrupt transport or recording.
- Deploying Live during a broadcast does not interrupt transport or recording.
-- Deploying the OpenRe API does not end worker-owned transports.
+- Deploying the OpenRestream API does not end worker-owned transports.
- A failed restream destination never ends the source session.
- A failed restream destination never ends the source session.
- Every stream key that existed before the cutover has been rotated.
- Every stream key that existed before the cutover has been rotated.
@@ -131,7 +131,7 @@ There are two kinds of location, because most of what "near the user" buys is ch
@@ -131,7 +131,7 @@ There are two kinds of location, because most of what "near the user" buys is ch
**Edge nodes are small, cheap machines in many places.** They run one agent with a few roles and hold no tenant data:
**Edge nodes are small, cheap machines in many places.** They run one agent with a few roles and hold no tenant data:
- **probe**: ping, traceroute, DNS, TCP/UDP and HTTP checks toward a target;
- **probe**: ping, traceroute, DNS, TCP/UDP and HTTP checks toward a target;
- **relay**: TURN for WebRTC calls, and game-server query relays;
- **relay**: TURN for WebRTC calls, and game-server query relays;
-- **ingest**: RTMP, SRT and WHIP accepted near the streamer, forwarded over the private network to the home region's OpenRe;
+- **ingest**: RTMP, SRT and WHIP accepted near the streamer, forwarded over the private network to the home region's OpenRestream;
- **cache**: media and page cache in front of R2 and origin.
- **cache**: media and page cache in front of R2 and origin.
Edge nodes are listed in the registry with their location (city, country, coordinates, provider), roles, capacity and health. The same deploy controller (section 7) manages them.
Edge nodes are listed in the registry with their location (city, country, coordinates, provider), roles, capacity and health. The same deploy controller (section 7) manages them.
@@ -43,7 +43,7 @@
@@ -43,7 +43,7 @@
3. Switch reads and writes to PostgreSQL, keeping the SQLite file read-only for the N-1 window (ADR-016, 7 days) as the rollback.
3. Switch reads and writes to PostgreSQL, keeping the SQLite file read-only for the N-1 window (ADR-016, 7 days) as the rollback.
4. Then delete the SQLite file after a final backup.
4. Then delete the SQLite file after a final backup.
- Order: Wiki, Blog, News, Reviews, Deals, Coupons, Trade, Tips, VIP, Search, Sources, Codes, Host, AI, Events, Chat, Community, Billing, Media, Tools, Games, OpenRe, Network, Live. Each migration is its own change, with its own rehearsal on a copy of the production data.
+ Order: Wiki, Blog, News, Reviews, Deals, Coupons, Trade, Tips, VIP, Search, Sources, Codes, Host, AI, Events, Chat, Community, Billing, Media, Tools, Games, OpenRestream, Network, Live. Each migration is its own change, with its own rehearsal on a copy of the production data.
7. **Sizing on the shared host**, until the data role has its own machine:
7. **Sizing on the shared host**, until the data role has its own machine:
- PostgreSQL: `shared_buffers` 1 GB, `effective_cache_size` 4 GB, `work_mem` 16 MB, `max_connections` 120, pooled behind PgBouncer;
- PostgreSQL: `shared_buffers` 1 GB, `effective_cache_size` 4 GB, `work_mem` 16 MB, `max_connections` 120, pooled behind PgBouncer;
- Valkey: `maxmemory` 768 MB.
- Valkey: `maxmemory` 768 MB.
@@ -12,7 +12,7 @@ a Cozmo-based robot).
@@ -12,7 +12,7 @@ a Cozmo-based robot).
- Chat commands (`!forward`, `!headup`, `!say`…) reached the robot with no permission check; Live fb3957f put them behind
- Chat commands (`!forward`, `!headup`, `!say`…) reached the robot with no permission check; Live fb3957f put them behind
the panel's rules as a stop-gap. Live also generates ~900 lines of Python per Cozmo owner (`routes.js`), because
the panel's rules as a stop-gap. Live also generates ~900 lines of Python per Cozmo owner (`routes.js`), because
buttons are table rows rather than a profile.
buttons are table rows rather than a profile.
-- OpenRe's webrtc worker (75a5dd7) takes WHIP ingest and serves viewers; Media records; Events carries events; Network
+- OpenRestream's webrtc worker (75a5dd7) takes WHIP ingest and serves viewers; Media records; Events carries events; Network
issues service tokens and delegated grants.
issues service tokens and delegated grants.
- The owner's first robot, the Adeept ADR036, is a Raspberry Pi with Adeept's Robot HAT: a PCA9685 at I²C 0x5f drives the
- The owner's first robot, the Adeept ADR036, is a Raspberry Pi with Adeept's Robot HAT: a PCA9685 at I²C 0x5f drives the
four DC motors (channels 8–15) and the pan/tilt servos (0, 1); an ADS7830 at 0x48 reads battery voltage; ultrasonic,
four DC motors (channels 8–15) and the pan/tilt servos (0, 1); an ADS7830 at 0x48 reads battery voltage; ultrasonic,
@@ -43,8 +43,8 @@ a Cozmo-based robot).
@@ -43,8 +43,8 @@ a Cozmo-based robot).
virtual environment with a systemd unit and the hardware watchdog.
virtual environment with a systemd unit and the hardware watchdog.
4. **Control runs over one outbound WebSocket per device; video over WHIP.** The device dials Bot
4. **Control runs over one outbound WebSocket per device; video over WHIP.** The device dials Bot
(`wss://openvibe.bot/device`), authenticates with its credential, and keeps one connection for commands, telemetry and
(`wss://openvibe.bot/device`), authenticates with its credential, and keeps one connection for commands, telemetry and
- heartbeats; this works behind any home router and on an ESP32. The camera publishes to OpenRe over WHIP; viewers watch
- through OpenRe. Operators reach Bot over a WebSocket from the panel. A WebRTC data channel may be added later as a
+ heartbeats; this works behind any home router and on an ESP32. The camera publishes to OpenRestream over WHIP; viewers watch
+ through OpenRestream. Operators reach Bot over a WebSocket from the panel. A WebRTC data channel may be added later as a
second control transport when measured latency asks for it; the message set does not change.
second control transport when measured latency asks for it; the message set does not change.
5. **One message set** (JSON, fields `v`, `seq`, `ts` on every frame): server→device `hello`, `config` (limits, heartbeat,
5. **One message set** (JSON, fields `v`, `seq`, `ts` on every frame): server→device `hello`, `config` (limits, heartbeat,
the operator's allowed commands), `command` (`id` as an idempotency key, `kind` drive/actuator/ptz/say/display/halt,
the operator's allowed commands), `command` (`id` as an idempotency key, `kind` drive/actuator/ptz/say/display/halt,
@@ -93,7 +93,7 @@ a Cozmo-based robot).
@@ -93,7 +93,7 @@ a Cozmo-based robot).
the `bot` service manifest and its events.
the `bot` service manifest and its events.
- Network: a `bot` service principal; the `bot.robot.control` grant for Live and Chat (on behalf of viewers) and for
- Network: a `bot` service principal; the `bot.robot.control` grant for Live and Chat (on behalf of viewers) and for
Actor agents (delegated).
Actor agents (delegated).
-- OpenRe: per-device publish keys for WHIP sessions created by Bot.
+- OpenRestream: per-device publish keys for WHIP sessions created by Bot.
- Live: the panel embed on channel pages, then the deletion in decision 10; Extensions `hardware/` becomes a pointer to
- Live: the panel embed on channel pages, then the deletion in decision 10; Extensions `hardware/` becomes a pointer to
the Bot agent.
the Bot agent.
@@ -101,7 +101,7 @@ below is in `lib/ids.js` except `act`, `run` and `zon`, which are proposed and n
@@ -101,7 +101,7 @@ below is in `lib/ids.js` except `act`, `run` and `zon`, which are proposed and n
Codes hosts no repositories, so `codes.repo` is gone. Media's index lists only its objects; its v1 vods and clips are
Codes hosts no repositories, so `codes.repo` is gone. Media's index lists only its objects; its v1 vods and clips are
projections over objects (bigint ids) and are never listed. The person-owned resources — Bot robots and devices, Chat
projections over objects (bigint ids) and are never listed. The person-owned resources — Bot robots and devices, Chat
-rooms, Community spaces, OpenRe.Stream streams and Games characters — are step 8 phase 2, served like Network's
+rooms, Community spaces, OpenRestream streams and Games characters — are step 8 phase 2, served like Network's
user-owned node principals: no OVRN, owner = user.
user-owned node principals: no OVRN, owner = user.
Events' `queue` is future until Events stores a queue row; `act`, `run` and `zon` are proposed but are not in
Events' `queue` is future until Events stores a queue row; `act`, `run` and `zon` are proposed but are not in
@@ -12,7 +12,7 @@ Platform-wide decisions from the OpenVibe development roadmap (section 10). Each
@@ -12,7 +12,7 @@ Platform-wide decisions from the OpenVibe development roadmap (section 10). Each
| [ADR-006](ADR-006-media-objects.md) | Media object, location and namespace model | Accepted 2026-09-22; implementation in progress (OpenVibe.Media Wave 4); amended 2026-09-24 (placement classes, local provider, infrequent access deferred) |
| [ADR-006](ADR-006-media-objects.md) | Media object, location and namespace model | Accepted 2026-09-22; implementation in progress (OpenVibe.Media Wave 4); amended 2026-09-24 (placement classes, local provider, infrequent access deferred) |
| [ADR-007](ADR-007-data-ownership.md) | Logical data ownership and database technology | Accepted 2026-09-22; amended 2026-09-24 (PgBouncer, replicas, SERIALIZABLE money paths, Redis non-authoritative) |
| [ADR-007](ADR-007-data-ownership.md) | Logical data ownership and database technology | Accepted 2026-09-22; amended 2026-09-24 (PgBouncer, replicas, SERIALIZABLE money paths, Redis non-authoritative) |
| [ADR-008](ADR-008-shared-packages.md) | Shared package publication and release manifests | Accepted 2026-09-22; implementation in progress (OpenVibe.Shared) |
| [ADR-008](ADR-008-shared-packages.md) | Shared package publication and release manifests | Accepted 2026-09-22; implementation in progress (OpenVibe.Shared) |
-| [ADR-009](ADR-009-live-openre-boundary.md) | Live versus OpenRe boundary | Accepted 2026-09-23; OpenRe deployed, no slot moved yet |
+| [ADR-009](ADR-009-live-openre-boundary.md) | Live versus OpenRestream boundary | Accepted 2026-09-23; OpenRestream deployed, no slot moved yet |
| [ADR-010](ADR-010-chat-boundary.md) | Chat versus Live/Community boundary | Accepted and executed 2026-09-23 (Chat serves Live's chat) |
| [ADR-010](ADR-010-chat-boundary.md) | Chat versus Live/Community boundary | Accepted and executed 2026-09-23 (Chat serves Live's chat) |
| [ADR-011](ADR-011-community-pastes.md) | Community paste and comment ownership migration | Accepted and executed 2026-09-22 |
| [ADR-011](ADR-011-community-pastes.md) | Community paste and comment ownership migration | Accepted and executed 2026-09-22 |
| [ADR-012](ADR-012-economic-classification.md) | Billing vs loyalty, credits and currency classification | Accepted 2026-09-22; gates Waves 8-10; amended 2026-09-24 (transaction-type mapping, OpenCoins stays in Network, table substitution) |
| [ADR-012](ADR-012-economic-classification.md) | Billing vs loyalty, credits and currency classification | Accepted 2026-09-22; gates Waves 8-10; amended 2026-09-24 (transaction-type mapping, OpenCoins stays in Network, table substitution) |
@@ -1 +1 @@
@@ -1 +1 @@
-{ "page_id": "pg_01JAB2C3D4E5F6G7H8J9K0MNPQ", "body": "Restreaming sends one encoder feed to several platforms. OpenRe.Stream does it server-side.", "expected_revision": 3, "workflow": { "id": "wiki.page_refresh", "run_id": "run_01JAB2C3D4E5F6G7H8J9K0MNPS", "model": "claude-sonnet-4-5" }, "note": "adds OpenRe" }
+{ "page_id": "pg_01JAB2C3D4E5F6G7H8J9K0MNPQ", "body": "Restreaming sends one encoder feed to several platforms. OpenRestream does it server-side.", "expected_revision": 3, "workflow": { "id": "wiki.page_refresh", "run_id": "run_01JAB2C3D4E5F6G7H8J9K0MNPS", "model": "claude-sonnet-4-5" }, "note": "adds OpenRestream" }
@@ -1887,7 +1887,7 @@
@@ -1887,7 +1887,7 @@
"slot_id": {
"slot_id": {
"type": "string",
"type": "string",
"pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
"pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
- "description": "A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>)."
+ "description": "A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>)."
},
},
"vod_id": {
"vod_id": {
"type": "string",
"type": "string",
@@ -25311,7 +25311,7 @@
@@ -25311,7 +25311,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/events/payloads/live.stream.started.v1.json",
"$id": "https://openvibe.network/contracts/events/payloads/live.stream.started.v1.json",
"title": "LiveStreamStartedPayload",
"title": "LiveStreamStartedPayload",
- "description": "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.",
+ "description": "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 OpenRestream 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.",
"type": "object",
"type": "object",
"required": [
"required": [
"stream_id",
"stream_id",
@@ -25390,7 +25390,7 @@
@@ -25390,7 +25390,7 @@
"webrtc",
"webrtc",
"rtmp"
"rtmp"
],
],
- "description": "How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp)."
+ "description": "How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp)."
},
},
"is_nsfw": {
"is_nsfw": {
"type": "boolean"
"type": "boolean"
@@ -25495,7 +25495,7 @@
@@ -25495,7 +25495,7 @@
"webrtc",
"webrtc",
"rtmp"
"rtmp"
],
],
- "description": "How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp)."
+ "description": "How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp)."
},
},
"is_nsfw": {
"is_nsfw": {
"type": "boolean"
"type": "boolean"
@@ -59917,7 +59917,7 @@
@@ -59917,7 +59917,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/destination.v1.json",
"$id": "https://openvibe.network/contracts/openre/destination.v1.json",
"title": "OpenreDestination",
"title": "OpenreDestination",
- "description": "openre.destination@1: one restream destination of a stream on OpenRe.Stream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.",
+ "description": "openre.destination@1: one restream destination of a stream on OpenRestream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.",
"type": "object",
"type": "object",
"required": [
"required": [
"id",
"id",
@@ -60073,7 +60073,7 @@
@@ -60073,7 +60073,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/key-rotate-request.v1.json",
"$id": "https://openvibe.network/contracts/openre/key-rotate-request.v1.json",
"title": "OpenreKeyRotateRequest",
"title": "OpenreKeyRotateRequest",
- "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.",
+ "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRestream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.",
"type": "object",
"type": "object",
"properties": {
"properties": {
"grace_seconds": {
"grace_seconds": {
@@ -60098,7 +60098,7 @@
@@ -60098,7 +60098,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/key-rotate-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/key-rotate-result.v1.json",
"title": "OpenreKeyRotateResult",
"title": "OpenreKeyRotateResult",
- "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.",
+ "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRestream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.",
"type": "object",
"type": "object",
"required": [
"required": [
"key",
"key",
@@ -60207,7 +60207,7 @@
@@ -60207,7 +60207,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/output-read-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/output-read-result.v1.json",
"title": "OpenreOutputReadResult",
"title": "OpenreOutputReadResult",
- "description": "openre.output-read-result@1: answers of openre.output.read on OpenRe.Stream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).",
+ "description": "openre.output-read-result@1: answers of openre.output.read on OpenRestream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -60289,7 +60289,7 @@
@@ -60289,7 +60289,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/output-write-request.v1.json",
"$id": "https://openvibe.network/contracts/openre/output-write-request.v1.json",
"title": "OpenreOutputWriteRequest",
"title": "OpenreOutputWriteRequest",
- "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRe.Stream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.",
+ "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRestream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -60395,7 +60395,7 @@
@@ -60395,7 +60395,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/output-write-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/output-write-result.v1.json",
"title": "OpenreOutputWriteResult",
"title": "OpenreOutputWriteResult",
- "description": "openre.output-write-result@1: answers of openre.output.write on OpenRe.Stream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).",
+ "description": "openre.output-write-result@1: answers of openre.output.write on OpenRestream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -60473,7 +60473,7 @@
@@ -60473,7 +60473,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/output.v1.json",
"$id": "https://openvibe.network/contracts/openre/output.v1.json",
"title": "OpenreOutput",
"title": "OpenreOutput",
- "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRe.Stream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.",
+ "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRestream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.",
"type": "object",
"type": "object",
"required": [
"required": [
"id",
"id",
@@ -60572,7 +60572,7 @@
@@ -60572,7 +60572,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/session-end-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/session-end-result.v1.json",
"title": "OpenreSessionEndResult",
"title": "OpenreSessionEndResult",
- "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRe.Stream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).",
+ "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRestream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).",
"type": "object",
"type": "object",
"required": [
"required": [
"requested",
"requested",
@@ -60596,7 +60596,7 @@
@@ -60596,7 +60596,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/session-read-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/session-read-result.v1.json",
"title": "OpenreSessionReadResult",
"title": "OpenreSessionReadResult",
- "description": "openre.session-read-result@1: answers of openre.session.read on OpenRe.Stream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).",
+ "description": "openre.session-read-result@1: answers of openre.session.read on OpenRestream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -60937,7 +60937,7 @@
@@ -60937,7 +60937,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/stream-read-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/stream-read-result.v1.json",
"title": "OpenreStreamReadResult",
"title": "OpenreStreamReadResult",
- "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRe.Stream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.",
+ "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRestream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -61036,7 +61036,7 @@
@@ -61036,7 +61036,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/stream-write-request.v1.json",
"$id": "https://openvibe.network/contracts/openre/stream-write-request.v1.json",
"title": "OpenreStreamWriteRequest",
"title": "OpenreStreamWriteRequest",
- "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRe.Stream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.",
+ "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRestream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -61153,7 +61153,7 @@
@@ -61153,7 +61153,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/stream-write-result.v1.json",
"$id": "https://openvibe.network/contracts/openre/stream-write-result.v1.json",
"title": "OpenreStreamWriteResult",
"title": "OpenreStreamWriteResult",
- "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRe.Stream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.",
+ "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRestream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.",
"type": "object",
"type": "object",
"required": [
"required": [
"stream"
"stream"
@@ -61197,7 +61197,7 @@
@@ -61197,7 +61197,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/openre/stream.v1.json",
"$id": "https://openvibe.network/contracts/openre/stream.v1.json",
"title": "OpenreStream",
"title": "OpenreStream",
- "description": "openre.stream@1: one stream definition as OpenRe.Stream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.",
+ "description": "openre.stream@1: one stream definition as OpenRestream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.",
"type": "object",
"type": "object",
"required": [
"required": [
"id",
"id",
@@ -62557,7 +62557,7 @@
@@ -62557,7 +62557,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/events/payloads/host.release.published.v1.json",
"$id": "https://openvibe.network/contracts/events/payloads/host.release.published.v1.json",
"title": "HostReleasePublishedPayload",
"title": "HostReleasePublishedPayload",
- "description": "host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRe, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.",
+ "description": "host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRestream, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.",
"type": "object",
"type": "object",
"required": [
"required": [
"service",
"service",
@@ -70783,7 +70783,7 @@
@@ -70783,7 +70783,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://openvibe.network/contracts/bot/pair-result.v1.json",
"$id": "https://openvibe.network/contracts/bot/pair-result.v1.json",
"title": "BotPairResult",
"title": "BotPairResult",
- "description": "bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRe configured there is no key: video is not_configured instead.",
+ "description": "bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRestream configured there is no key: video is not_configured instead.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -70821,7 +70821,7 @@
@@ -70821,7 +70821,7 @@
"publish_key": {
"publish_key": {
"type": "string",
"type": "string",
"minLength": 1,
"minLength": 1,
- "description": "The WHIP publish key, an ingest key OpenRe issued for the robot's stream: shown once."
+ "description": "The WHIP publish key, an ingest key OpenRestream issued for the robot's stream: shown once."
},
},
"whip_url": {
"whip_url": {
"type": "string",
"type": "string",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Actor API",
"title": "OpenVibe.Actor API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Actor as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.AI API",
"title": "OpenVibe.AI API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Billing API",
"title": "OpenVibe.Billing API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Blog API",
"title": "OpenVibe.Blog API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Bot API",
"title": "OpenVibe.Bot API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Bot as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Chat API",
"title": "OpenVibe.Chat API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Community API",
"title": "OpenVibe.Community API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Coupons API",
"title": "OpenVibe.Coupons API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Deals API",
"title": "OpenVibe.Deals API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Events API",
"title": "OpenVibe.Events API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Food API",
"title": "OpenVibe.Food API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Food as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Games API",
"title": "OpenVibe.Games API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Host API",
"title": "OpenVibe.Host API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -129,7 +129,7 @@
@@ -129,7 +129,7 @@
},
},
{
{
"service": "openre",
"service": "openre",
- "name": "OpenRe.Stream",
+ "name": "OpenRestream",
"origin": "https://openre.stream",
"origin": "https://openre.stream",
"operations": 22,
"operations": 22,
"capabilities": 7
"capabilities": 7
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Inventory API",
"title": "OpenVibe.Inventory API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Inventory as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Live API",
"title": "OpenVibe.Live API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -1341,9 +1341,9 @@
@@ -1341,9 +1341,9 @@
"schema": {
"schema": {
"type": "string",
"type": "string",
"pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
"pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
- "description": "A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>)."
+ "description": "A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>)."
},
},
- "description": "A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>)."
+ "description": "A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>)."
},
},
{
{
"name": "vod_id",
"name": "vod_id",
@@ -2078,7 +2078,7 @@
@@ -2078,7 +2078,7 @@
"slot_id": {
"slot_id": {
"type": "string",
"type": "string",
"pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
"pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$",
- "description": "A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>)."
+ "description": "A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>)."
},
},
"vod_id": {
"vod_id": {
"type": "string",
"type": "string",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Media API",
"title": "OpenVibe.Media API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Network API",
"title": "OpenVibe.Network API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.News API",
"title": "OpenVibe.News API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -2,9 +2,9 @@
@@ -2,9 +2,9 @@
"openapi": "3.1.0",
"openapi": "3.1.0",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
- "title": "OpenRe.Stream API",
- "version": "0.125.0",
- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "title": "OpenRestream API",
+ "version": "0.125.1",
+ "description": "Routes of OpenRestream as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -1478,7 +1478,7 @@
@@ -1478,7 +1478,7 @@
},
},
"openre.destination.v1": {
"openre.destination.v1": {
"title": "OpenreDestination",
"title": "OpenreDestination",
- "description": "openre.destination@1: one restream destination of a stream on OpenRe.Stream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.",
+ "description": "openre.destination@1: one restream destination of a stream on OpenRestream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.",
"type": "object",
"type": "object",
"required": [
"required": [
"id",
"id",
@@ -1627,7 +1627,7 @@
@@ -1627,7 +1627,7 @@
},
},
"openre.key-rotate-request.v1": {
"openre.key-rotate-request.v1": {
"title": "OpenreKeyRotateRequest",
"title": "OpenreKeyRotateRequest",
- "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.",
+ "description": "openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRestream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.",
"type": "object",
"type": "object",
"properties": {
"properties": {
"grace_seconds": {
"grace_seconds": {
@@ -1645,7 +1645,7 @@
@@ -1645,7 +1645,7 @@
},
},
"openre.key-rotate-result.v1": {
"openre.key-rotate-result.v1": {
"title": "OpenreKeyRotateResult",
"title": "OpenreKeyRotateResult",
- "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.",
+ "description": "openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRestream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.",
"type": "object",
"type": "object",
"required": [
"required": [
"key",
"key",
@@ -1747,7 +1747,7 @@
@@ -1747,7 +1747,7 @@
},
},
"openre.output-read-result.v1": {
"openre.output-read-result.v1": {
"title": "OpenreOutputReadResult",
"title": "OpenreOutputReadResult",
- "description": "openre.output-read-result@1: answers of openre.output.read on OpenRe.Stream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).",
+ "description": "openre.output-read-result@1: answers of openre.output.read on OpenRestream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -1822,7 +1822,7 @@
@@ -1822,7 +1822,7 @@
},
},
"openre.output-write-request.v1": {
"openre.output-write-request.v1": {
"title": "OpenreOutputWriteRequest",
"title": "OpenreOutputWriteRequest",
- "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRe.Stream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.",
+ "description": "openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRestream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -1921,7 +1921,7 @@
@@ -1921,7 +1921,7 @@
},
},
"openre.output-write-result.v1": {
"openre.output-write-result.v1": {
"title": "OpenreOutputWriteResult",
"title": "OpenreOutputWriteResult",
- "description": "openre.output-write-result@1: answers of openre.output.write on OpenRe.Stream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).",
+ "description": "openre.output-write-result@1: answers of openre.output.write on OpenRestream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -1992,7 +1992,7 @@
@@ -1992,7 +1992,7 @@
},
},
"openre.output.v1": {
"openre.output.v1": {
"title": "OpenreOutput",
"title": "OpenreOutput",
- "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRe.Stream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.",
+ "description": "openre.output@1: one restream output (a destination running for a live session) on OpenRestream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.",
"type": "object",
"type": "object",
"required": [
"required": [
"id",
"id",
@@ -2084,7 +2084,7 @@
@@ -2084,7 +2084,7 @@
},
},
"openre.session-end-result.v1": {
"openre.session-end-result.v1": {
"title": "OpenreSessionEndResult",
"title": "OpenreSessionEndResult",
- "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRe.Stream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).",
+ "description": "openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRestream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).",
"type": "object",
"type": "object",
"required": [
"required": [
"requested",
"requested",
@@ -2101,7 +2101,7 @@
@@ -2101,7 +2101,7 @@
},
},
"openre.session-read-result.v1": {
"openre.session-read-result.v1": {
"title": "OpenreSessionReadResult",
"title": "OpenreSessionReadResult",
- "description": "openre.session-read-result@1: answers of openre.session.read on OpenRe.Stream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).",
+ "description": "openre.session-read-result@1: answers of openre.session.read on OpenRestream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -2435,7 +2435,7 @@
@@ -2435,7 +2435,7 @@
},
},
"openre.stream-read-result.v1": {
"openre.stream-read-result.v1": {
"title": "OpenreStreamReadResult",
"title": "OpenreStreamReadResult",
- "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRe.Stream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.",
+ "description": "openre.stream-read-result@1: answers of openre.stream.read on OpenRestream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -2527,7 +2527,7 @@
@@ -2527,7 +2527,7 @@
},
},
"openre.stream-write-request.v1": {
"openre.stream-write-request.v1": {
"title": "OpenreStreamWriteRequest",
"title": "OpenreStreamWriteRequest",
- "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRe.Stream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.",
+ "description": "openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRestream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.",
"anyOf": [
"anyOf": [
{
{
"type": "object",
"type": "object",
@@ -2637,7 +2637,7 @@
@@ -2637,7 +2637,7 @@
},
},
"openre.stream-write-result.v1": {
"openre.stream-write-result.v1": {
"title": "OpenreStreamWriteResult",
"title": "OpenreStreamWriteResult",
- "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRe.Stream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.",
+ "description": "openre.stream-write-result@1: answers of openre.stream.write on OpenRestream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.",
"type": "object",
"type": "object",
"required": [
"required": [
"stream"
"stream"
@@ -2674,7 +2674,7 @@
@@ -2674,7 +2674,7 @@
},
},
"openre.stream.v1": {
"openre.stream.v1": {
"title": "OpenreStream",
"title": "OpenreStream",
- "description": "openre.stream@1: one stream definition as OpenRe.Stream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.",
+ "description": "openre.stream@1: one stream definition as OpenRestream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.",
"type": "object",
"type": "object",
"required": [
"required": [
"id",
"id",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Reviews API",
"title": "OpenVibe.Reviews API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Run API",
"title": "OpenVibe.Run API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Run as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Search API",
"title": "OpenVibe.Search API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Services API",
"title": "OpenVibe.Services API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Services as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Sources API",
"title": "OpenVibe.Sources API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Tips API",
"title": "OpenVibe.Tips API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Tools API",
"title": "OpenVibe.Tools API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Trade API",
"title": "OpenVibe.Trade API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.VIP API",
"title": "OpenVibe.VIP API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Watch API",
"title": "OpenVibe.Watch API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Watch as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Wiki API",
"title": "OpenVibe.Wiki API",
- "version": "0.125.0",
- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.125.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
+ "version": "0.125.1",
+ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.125.1): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -4110,7 +4110,7 @@ export interface LineageResolveRequest {
@@ -4110,7 +4110,7 @@ export interface LineageResolveRequest {
*/
*/
stream_id?: string;
stream_id?: string;
/**
/**
- * A persistent stream slot (Live: managed_streams.id; OpenRe stream definitions refer to it as live:managed_stream:<id>).
+ * A persistent stream slot (Live: managed_streams.id; OpenRestream stream definitions refer to it as live:managed_stream:<id>).
*/
*/
slot_id?: string;
slot_id?: string;
/**
/**
@@ -31808,7 +31808,7 @@ export interface EventsUsageRecordedPayload {
@@ -31808,7 +31808,7 @@ export interface EventsUsageRecordedPayload {
/** [email protected] (owner: live) */
/** [email protected] (owner: live) */
/**
/**
- * 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.
+ * 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 OpenRestream 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.
*/
*/
export interface LiveStreamStartedPayload {
export interface LiveStreamStartedPayload {
/**
/**
@@ -31842,7 +31842,7 @@ export interface LiveStreamStartedPayload {
@@ -31842,7 +31842,7 @@ export interface LiveStreamStartedPayload {
*/
*/
category: string | null;
category: string | null;
/**
/**
- * How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp).
+ * How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp).
*/
*/
protocol: "jsmpeg" | "webrtc" | "rtmp";
protocol: "jsmpeg" | "webrtc" | "rtmp";
is_nsfw: boolean;
is_nsfw: boolean;
@@ -31888,7 +31888,7 @@ export interface LiveStreamEndedPayload {
@@ -31888,7 +31888,7 @@ export interface LiveStreamEndedPayload {
*/
*/
category: string | null;
category: string | null;
/**
/**
- * How the stream is ingested (WHIP is webrtc; OpenRe and RTMP are rtmp).
+ * How the stream is ingested (WHIP is webrtc; OpenRestream and RTMP are rtmp).
*/
*/
protocol: "jsmpeg" | "webrtc" | "rtmp";
protocol: "jsmpeg" | "webrtc" | "rtmp";
is_nsfw: boolean;
is_nsfw: boolean;
@@ -53620,7 +53620,7 @@ export type SpaceThreadReadResult =
@@ -53620,7 +53620,7 @@ export type SpaceThreadReadResult =
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.destination@1: one restream destination of a stream on OpenRe.Stream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.
+ * openre.destination@1: one restream destination of a stream on OpenRestream (server/store/outputs.js publicDest). The stream key and SRT passphrase are write-only: only whether they are set and a hint of the key are shown.
*/
*/
export interface OpenreDestination {
export interface OpenreDestination {
id: string;
id: string;
@@ -53652,7 +53652,7 @@ export interface OpenreDestination {
@@ -53652,7 +53652,7 @@ export interface OpenreDestination {
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.
+ * openre.key-rotate-request@1: the body of POST /api/v1/streams/:id/keys/rotate on OpenRestream (openre.key.rotate). grace_seconds (0 by default, at most 7 days) keeps the old key working that long; end_sessions true also ends the stream's open sessions. An empty body rotates with no grace.
*/
*/
export interface OpenreKeyRotateRequest {
export interface OpenreKeyRotateRequest {
/**
/**
@@ -53664,7 +53664,7 @@ export interface OpenreKeyRotateRequest {
@@ -53664,7 +53664,7 @@ export interface OpenreKeyRotateRequest {
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRe.Stream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.
+ * openre.key-rotate-result@1: the answer of POST /api/v1/streams/:id/keys/rotate on OpenRestream: the new key (shown once, Cache-Control no-store), the keys it retired (grace or revoked), when the grace ends, how many sessions were asked to end, and the ingest endpoints. openre.key.rotated is announced.
*/
*/
export interface OpenreKeyRotateResult {
export interface OpenreKeyRotateResult {
key: {
key: {
@@ -53697,7 +53697,7 @@ export interface OpenreKeyRotateResult {
@@ -53697,7 +53697,7 @@ export interface OpenreKeyRotateResult {
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.output-read-result@1: answers of openre.output.read on OpenRe.Stream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).
+ * openre.output-read-result@1: answers of openre.output.read on OpenRestream. GET /api/v1/streams/:id/destinations → { destinations }; GET /api/v1/sessions/:id/outputs → { outputs } (with health); GET /api/v1/destinations/:id/logs and GET /api/v1/outputs/:id/logs?limit= → { logs } (newest first, at most 500).
*/
*/
export type OpenreOutputReadResult =
export type OpenreOutputReadResult =
| {
| {
@@ -53720,7 +53720,7 @@ export type OpenreOutputReadResult =
@@ -53720,7 +53720,7 @@ export type OpenreOutputReadResult =
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRe.Stream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.
+ * openre.output-write-request@1: the body of POST /api/v1/streams/:id/destinations (platform and server_url required) and PATCH /api/v1/destinations/:id (fields left out keep their value) on OpenRestream (openre.output.write). server_url must pass the destination URL rules (rtmp, rtmps or srt, public hosts); stream_key (at most 512 characters, no spaces) and srt_passphrase (10 to 79 characters) are sealed and never read back — __keep__ leaves them unchanged, empty clears them. Numbers out of range become null: srt_latency_ms 20-8000, custom_video_bitrate 500-50000, custom_audio_bitrate 32-512, custom_fps 15-120; an unknown custom_encoder_preset becomes null. DELETE /api/v1/destinations/:id and POST /api/v1/destinations/:id/test|start|stop take no body.
*/
*/
export type OpenreOutputWriteRequest =
export type OpenreOutputWriteRequest =
| {
| {
@@ -53742,7 +53742,7 @@ export type OpenreOutputWriteRequest =
@@ -53742,7 +53742,7 @@ export type OpenreOutputWriteRequest =
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.output-write-result@1: answers of openre.output.write on OpenRe.Stream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).
+ * openre.output-write-result@1: answers of openre.output.write on OpenRestream. POST …/destinations → 201 { destination }; PATCH /api/v1/destinations/:id → { destination }; DELETE → 204 with no body (409 openre.destination_running while it still runs); POST …/test → { ok, checks } (URL rules, DNS, TCP reachability; each check { check, ok, detail }); POST …/start → { output } (for the stream's live session; 409 when held, disabled, keyless or not live); POST …/stop → { stopping } (outputs asked to stop).
*/
*/
export type OpenreOutputWriteResult =
export type OpenreOutputWriteResult =
| {
| {
@@ -53765,7 +53765,7 @@ export type OpenreOutputWriteResult =
@@ -53765,7 +53765,7 @@ export type OpenreOutputWriteResult =
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.output@1: one restream output (a destination running for a live session) on OpenRe.Stream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.
+ * openre.output@1: one restream output (a destination running for a live session) on OpenRestream (server/store/outputs.js publicOutput), with its desired and actual state, restarts and progress.
*/
*/
export interface OpenreOutput {
export interface OpenreOutput {
id: string;
id: string;
@@ -53789,7 +53789,7 @@ export interface OpenreOutput {
@@ -53789,7 +53789,7 @@ export interface OpenreOutput {
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRe.Stream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).
+ * openre.session-end-result@1: the answer of POST /api/v1/sessions/:id/end on OpenRestream (openre.session.end): 202 { requested: true, state } when the owning worker was asked to disconnect the encoder, 409 { requested: false, state } when the session could not be ended (already ending or over).
*/
*/
export interface OpenreSessionEndResult {
export interface OpenreSessionEndResult {
requested: boolean;
requested: boolean;
@@ -53798,7 +53798,7 @@ export interface OpenreSessionEndResult {
@@ -53798,7 +53798,7 @@ export interface OpenreSessionEndResult {
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.session-read-result@1: answers of openre.session.read on OpenRe.Stream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).
+ * openre.session-read-result@1: answers of openre.session.read on OpenRestream. GET /api/v1/sessions?stream_id=&state=&limit=&before= → { sessions } (the owner's; a service sees those of the subject it acts for); GET /api/v1/sessions/:id → { session } with transitions, outputs, recording and playback; GET /api/v1/sessions/:id/playback → { playback } (where to watch: flv and rtmp URLs, internal loopback and public); GET /api/v1/workers → { workers } (worker generations; staff and services only).
*/
*/
export type OpenreSessionReadResult =
export type OpenreSessionReadResult =
| {
| {
@@ -53878,7 +53878,7 @@ export type OpenreSessionReadResult =
@@ -53878,7 +53878,7 @@ export type OpenreSessionReadResult =
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.stream-read-result@1: answers of openre.stream.read on OpenRe.Stream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.
+ * openre.stream-read-result@1: answers of openre.stream.read on OpenRestream. GET /api/v1/streams[?external_ref=<service>:<type>:<id>&limit=] → { streams } (the owner's, or the one bound to that external reference; staff may ask for all); GET /api/v1/streams/:id → { stream }; GET /api/v1/streams/:id/keys → { keys } (metadata only, never a key). Another owner's or an archived stream is 404 openre.stream_not_found.
*/
*/
export type OpenreStreamReadResult =
export type OpenreStreamReadResult =
| {
| {
@@ -53901,7 +53901,7 @@ export type OpenreStreamReadResult =
@@ -53901,7 +53901,7 @@ export type OpenreStreamReadResult =
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRe.Stream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.
+ * openre.stream-write-request@1: the body of POST /api/v1/streams and PATCH /api/v1/streams/:id on OpenRestream (openre.stream.write). A person creates streams for themselves; a service names the owner with X-OV-Subject (or owner_subject, which must then match). title is cleaned and cut to 140 characters (Untitled stream when blank), description to 2000; protocols is a non-empty subset of rtmp, whip, webrtc, jsmpeg; external_refs (create only, at most 10, each bound to one stream) link it to another service's record, e.g. { service: live, type: managed_stream, id: 12 }; state (update only) is active or disabled. Fields left out keep their value. DELETE /api/v1/streams/:id (archive; refused while live) takes no body. Refusals are 400 openre.invalid_* and 409 openre.ref_taken / openre.stream_live.
*/
*/
export type OpenreStreamWriteRequest =
export type OpenreStreamWriteRequest =
| {
| {
@@ -54278,7 +54278,7 @@ export type OpenreStreamWriteRequest =
@@ -54278,7 +54278,7 @@ export type OpenreStreamWriteRequest =
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.stream-write-result@1: answers of openre.stream.write on OpenRe.Stream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.
+ * openre.stream-write-result@1: answers of openre.stream.write on OpenRestream. POST /api/v1/streams → 201 { stream, key } where key is the first ingest key, shown once (Cache-Control no-store); PATCH /api/v1/streams/:id → { stream }; DELETE /api/v1/streams/:id → 204 with no body.
*/
*/
export interface OpenreStreamWriteResult {
export interface OpenreStreamWriteResult {
stream: OpenreStream;
stream: OpenreStream;
@@ -54295,7 +54295,7 @@ export interface OpenreStreamWriteResult {
@@ -54295,7 +54295,7 @@ export interface OpenreStreamWriteResult {
/** [email protected] (owner: openre) */
/** [email protected] (owner: openre) */
/**
/**
- * openre.stream@1: one stream definition as OpenRe.Stream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.
+ * openre.stream@1: one stream definition as OpenRestream's API shows it (server/api/v1.js publicDefinition): the owner's stream with its protocols, recording and playback settings, ingest endpoints, key metadata (hints only, never a key) and the open session if any.
*/
*/
export interface OpenreStream {
export interface OpenreStream {
id: string;
id: string;
@@ -54686,7 +54686,7 @@ export interface HostDeployActivatedPayload {
@@ -54686,7 +54686,7 @@ export interface HostDeployActivatedPayload {
/** [email protected] (owner: host) */
/** [email protected] (owner: host) */
/**
/**
- * host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRe, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.
+ * host.release.published v1 (roadmap WS-P task 9, ADR-016 amendment 1). A network service's release went live. OpenVibe.Host's operator plane (lib/announce.js) publishes it after `ovhost deploy|rollback <service>` went live and for `ovhost announce <service>` (services deployed by their own scripts: Live, Tools, Sites, OpenRestream, Games). Envelope: subject { type: release, id: <service>:<release> }, visibility public (signed-out browsers get it over Events realtime), priority low, actor service:host. Open tabs whose /release.json names `service` (openvibe-shared release-watch 1.17.0, topics=host.release.published) check it when `release` is not the one they run. It carries identifiers only, never what changed. At most one per service and release unless an operator forces it; a retry reuses the event_id. Tenant sites' activations are host.deploy.activated, not this.
*/
*/
export interface HostReleasePublishedPayload {
export interface HostReleasePublishedPayload {
/**
/**
@@ -57922,7 +57922,7 @@ export interface BotPairRequest {
@@ -57922,7 +57922,7 @@ export interface BotPairRequest {
/** [email protected] (owner: bot) */
/** [email protected] (owner: bot) */
/**
/**
- * bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRe configured there is no key: video is not_configured instead.
+ * bot.pair-result@1: the 201 answers of OpenVibe.Bot's pairing routes (server/api/v1.js). POST /api/v1/pair → { device_id, credential, publish_key, whip_url?, robot_id, profile }; POST /api/v1/devices/bind (a Network node token) → the same without credential. The credential, the publish key and the WHIP URL are shown once and never again. Without OpenRestream configured there is no key: video is not_configured instead.
*/
*/
export type BotPairResult =
export type BotPairResult =
| {
| {
@@ -57934,7 +57934,7 @@ export type BotPairResult =
@@ -57934,7 +57934,7 @@ export type BotPairResult =
*/
*/
credential?: string;
credential?: string;
/**
/**
- * The WHIP publish key, an ingest key OpenRe issued for the robot's stream: shown once.
+ * The WHIP publish key, an ingest key OpenRestream issued for the robot's stream: shown once.
*/
*/
publish_key: string;
publish_key: string;
/**
/**
@@ -70,7 +70,7 @@ before anyone relies on either.
@@ -70,7 +70,7 @@ before anyone relies on either.
| OpenVibe.Trade | AGPL-3.0-only | AGPL-3.0 | consistent |
| OpenVibe.Trade | AGPL-3.0-only | AGPL-3.0 | consistent |
| OpenVibe.VIP | AGPL-3.0-only | AGPL-3.0 | consistent |
| OpenVibe.VIP | AGPL-3.0-only | AGPL-3.0 | consistent |
| OpenVibe.Wiki | AGPL-3.0-only | AGPL-3.0 | consistent |
| OpenVibe.Wiki | AGPL-3.0-only | AGPL-3.0 | consistent |
-| OpenRe.Stream | AGPL-3.0-only | AGPL-3.0 | consistent |
+| OpenRestream | AGPL-3.0-only | AGPL-3.0 | consistent |
Dependency review: every repository pins its OpenVibe packages to release tags, CI runs the tests and the
Dependency review: every repository pins its OpenVibe packages to release tags, CI runs the tests and the
pin-drift check, and gitleaks scans history. A licence review of third-party dependencies is part of WS-R
pin-drift check, and gitleaks scans history. A licence review of third-party dependencies is part of WS-R
@@ -215,7 +215,7 @@
@@ -215,7 +215,7 @@
{
{
"id": "staff.site.view",
"id": "staff.site.view",
"minRole": "admin",
"minRole": "admin",
- "description": "Read operations data: diagnostics, statistics, all streams, storage, analytics, OpenRe status, money state and AI usage.",
+ "description": "Read operations data: diagnostics, statistics, all streams, storage, analytics, OpenRestream status, money state and AI usage.",
"gates": {
"gates": {
"live": [
"live": [
"admin/routes.js:52 → 55,67,305,483,522,569,969,1025,1125",
"admin/routes.js:52 → 55,67,305,483,522,569,969,1025,1125",
@@ -39,7 +39,7 @@
@@ -39,7 +39,7 @@
},
},
{
{
"question": "Which sites does it cover?",
"question": "Which sites does it cover?",
- "answer": "Every OpenVibe product site, live or coming, from OpenVibe.Live to OpenRe.Stream. Each one has its own page with its questions and where it lives."
+ "answer": "Every OpenVibe product site, live or coming, from OpenVibe.Live to OpenRestream. Each one has its own page with its questions and where it lives."
}
}
],
],
"keywords": "openvibe help, openvibe support, help center, support tickets, troubleshooting",
"keywords": "openvibe help, openvibe support, help center, support tickets, troubleshooting",
@@ -36,7 +36,7 @@
@@ -36,7 +36,7 @@
"note": "Streams, recordings and clips live on OpenVibe.Live today."
"note": "Streams, recordings and clips live on OpenVibe.Live today."
},
},
{
{
- "label": "OpenRe.Stream",
+ "label": "OpenRestream",
"url": "https://openre.stream",
"url": "https://openre.stream",
"note": "Restreaming to many platforms is the sibling product."
"note": "Restreaming to many platforms is the sibling product."
}
}
deleted file mode 100644
deleted file mode 100644
@@ -1,26 +0,0 @@
@@ -1,26 +0,0 @@
-{
- "name": "OpenRe.Stream",
- "repository": "OpenVibers/OpenRe.Stream",
- "service": "openre",
- "product": "OpenRe.Stream",
- "stage": "alpha",
- "version": "0.1.0",
- "runtime": "node 22",
- "database": "PostgreSQL",
- "migrations": 3,
- "authority": [
- "openre.*"
- ],
- "domains": [
- "openre.stream",
- "ingest.openre.stream"
- ],
- "pins": {
- "openvibe-contracts": "v0.76.0",
- "openvibe-sdk": "v0.26.0",
- "openvibe-shared": "v2.10.1"
- },
- "deployed": true,
- "exposure": "internal",
- "track": "W7"
-}
new file mode 100644
new file mode 100644
@@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
+{
+ "name": "OpenRestream",
+ "repository": "OpenVibers/OpenRestream",
+ "service": "openre",
+ "product": "OpenRestream",
+ "stage": "alpha",
+ "version": "0.1.0",
+ "runtime": "node 22",
+ "database": "PostgreSQL",
+ "migrations": 3,
+ "authority": [
+ "openre.*"
+ ],
+ "domains": [
+ "openre.stream",
+ "ingest.openre.stream"
+ ],
+ "pins": {
+ "openvibe-contracts": "v0.76.0",
+ "openvibe-sdk": "v0.26.0",
+ "openvibe-shared": "v2.10.1"
+ },
+ "deployed": true,
+ "exposure": "internal",
+ "track": "W7"
+}
@@ -4,9 +4,9 @@
@@ -4,9 +4,9 @@
"openvibe-contracts": ">=0.13.0 <1.0.0"
"openvibe-contracts": ">=0.13.0 <1.0.0"
},
},
"id": "openre",
"id": "openre",
- "name": "OpenRe.Stream",
+ "name": "OpenRestream",
"status": "alpha",
"status": "alpha",
- "repository": "OpenVibers/OpenRe.Stream",
+ "repository": "OpenVibers/OpenRestream",
"domains": [
"domains": [
"openre.stream",
"openre.stream",
"ingest.openre.stream"
"ingest.openre.stream"
@@ -20,7 +20,7 @@
@@ -20,7 +20,7 @@
"publicSite": "service"
"publicSite": "service"
},
},
"site": {
"site": {
- "name": "OpenRe.Stream",
+ "name": "OpenRestream",
"icon": "stream",
"icon": "stream",
"tagline": "Restream anywhere",
"tagline": "Restream anywhere",
"what": "Ingest once and send the stream to every platform at once; keys, destinations and output health in one place.",
"what": "Ingest once and send the stream to every platform at once; keys, destinations and output health in one place.",
@@ -28,7 +28,7 @@
@@ -28,7 +28,7 @@
"position": 18,
"position": 18,
"tld": "stream",
"tld": "stream",
"accent": "#ef4444",
"accent": "#ef4444",
- "description": "OpenRe.Stream is OpenVibe's open streaming engine, split out of OpenVibe.Live. Go live from a web browser with no OBS, no downloads and no follower minimum, or send RTMP or WHIP from any encoder, and restream to Twitch, YouTube, Kick and any RTMP, RTMPS or SRT destination. Browser broadcasts start on OpenVibe.Live today, and move to OpenRe.Stream ingest channel by channel.",
+ "description": "OpenRestream is OpenVibe's open streaming engine, split out of OpenVibe.Live. Go live from a web browser with no OBS, no downloads and no follower minimum, or send RTMP or WHIP from any encoder, and restream to Twitch, YouTube, Kick and any RTMP, RTMPS or SRT destination. Browser broadcasts start on OpenVibe.Live today, and move to OpenRestream ingest channel by channel.",
"pillars": [
"pillars": [
{
{
"title": "Browser go-live",
"title": "Browser go-live",
@@ -88,9 +88,9 @@
@@ -88,9 +88,9 @@
"url": "https://openvibe.live/docs/go-live-in-your-browser"
"url": "https://openvibe.live/docs/go-live-in-your-browser"
}
}
},
},
- "launch": "the stream slots to move from OpenVibe.Live's ingest to OpenRe.Stream, one at a time; no stream uses it yet",
+ "launch": "the stream slots to move from OpenVibe.Live's ingest to OpenRestream, one at a time; no stream uses it yet",
"relationships": {
"relationships": {
- "plannedRepo": "OpenRe.Stream",
+ "plannedRepo": "OpenRestream",
"meanwhile": [
"meanwhile": [
{
{
"label": "Go live on OpenVibe.Live",
"label": "Go live on OpenVibe.Live",
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.125.0",
+ "version": "0.125.1",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"main": "index.js",
"types": "generated/typescript/index.d.ts",
"types": "generated/typescript/index.d.ts",