From 8c49bd072e6b39a5a8f7e2aaae15bc47e8095ca9 Mon Sep 17 00:00:00 2001 From: Tomasz Mazur <47872060+AHGIJMKLKKZNPJKQR@users.noreply.github.com> Date: Mon, 30 Mar 2026 14:37:08 +0200 Subject: [PATCH 01/10] Add scalar viewer for fishjam api --- .yarnrc.yml | 5 ++ docs/api/reference.md | 2 +- docusaurus.config.ts | 40 +++++++++++- package.json | 2 + yarn.lock | 137 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 183 insertions(+), 3 deletions(-) diff --git a/.yarnrc.yml b/.yarnrc.yml index 3186f3f0..dc612810 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -1 +1,6 @@ +approvedGitRepositories: + - "**" + +enableScripts: true + nodeLinker: node-modules diff --git a/docs/api/reference.md b/docs/api/reference.md index 4d4a4810..a9ea6f47 100644 --- a/docs/api/reference.md +++ b/docs/api/reference.md @@ -23,7 +23,7 @@ The notifications can be configured using Webhook or Websocket. ### REST API -[Server OpenAPI](https://github.com/fishjam-cloud/documentation/tree/main/static/api/fishjam-server-openapi.yaml) +[Server REST API Reference](/api/rest) ### Protobufs diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 53ac287c..bc79bed3 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -1,6 +1,7 @@ import type { Config } from "@docusaurus/types"; import type * as Preset from "@docusaurus/preset-classic"; import type { UserThemeConfig as DocSearchThemeConfig } from "@docsearch/docusaurus-adapter"; +import type { ScalarOptions } from "@scalar/docusaurus"; import { BundledLanguage, bundledLanguages } from "shiki"; import type { MDXPlugin } from "@docusaurus/mdx-loader"; import rehypeShiki, { RehypeShikiOptions } from "@shikijs/rehype"; @@ -13,7 +14,6 @@ import { transformerNotationFocus, } from "@shikijs/transformers"; -import { rendererClassic, transformerTwoslash } from "@shikijs/twoslash"; import { NormalizedSidebar, NormalizedSidebarItem, @@ -23,6 +23,33 @@ import { import { llmsRootContent } from "./src/content/llms-root-content"; import { createRedirects } from "./redirects"; +const hasBrokenLocalStorage = + typeof globalThis.localStorage === "object" && + typeof globalThis.localStorage?.getItem !== "function"; + +if (hasBrokenLocalStorage) { + const storage = new Map(); + globalThis.localStorage = { + getItem: (key: string) => storage.get(key) ?? null, + setItem: (key: string, value: string) => { + storage.set(key, value); + }, + removeItem: (key: string) => { + storage.delete(key); + }, + clear: () => { + storage.clear(); + }, + key: (index: number) => Array.from(storage.keys())[index] ?? null, + get length() { + return storage.size; + }, + } as Storage; +} + +const { rendererClassic, transformerTwoslash } = + require("@shikijs/twoslash"); + function isErrorFromVersionedDocs(options: { meta?: { __raw?: string } }) { if (options.meta?.__raw?.includes("loc=")) { const locMatch = options.meta.__raw.match(/loc=([^\s]+)/); @@ -313,6 +340,17 @@ const config: Config = { plugins: [ ["@docusaurus/plugin-client-redirects", { createRedirects }], "@docsearch/docusaurus-adapter", + [ + "@scalar/docusaurus", + { + label: "Server REST API", + route: "/api/rest", + showNavLink: false, + configuration: { + url: "/docs/api/fishjam-server-openapi.yaml", + }, + } as ScalarOptions, + ], [ "docusaurus-plugin-typedoc", { diff --git a/package.json b/package.json index 199de478..e3c28a1e 100644 --- a/package.json +++ b/package.json @@ -31,11 +31,13 @@ "@docusaurus/preset-classic": "^3.10.0", "@docusaurus/remark-plugin-npm2yarn": "^3.10.0", "@docusaurus/theme-mermaid": "^3.10.0", + "@docusaurus/utils": "^3.9.2", "@fastify/env": "^5.0.2", "@fishjam-cloud/js-server-sdk": "link:./packages/js-server-sdk/packages/js-server-sdk", "@fishjam-cloud/react-client": "link:./packages/web-client-sdk/packages/react-client", "@fishjam-cloud/react-native-client": "link:./packages/web-client-sdk/packages/mobile-client", "@mdx-js/react": "^3.1.0", + "@scalar/docusaurus": "^0.8.5", "@shikijs/rehype": "^3.6.0", "@shikijs/transformers": "^3.6.0", "@swmansion/smelter": "^0.2.1", diff --git a/yarn.lock b/yarn.lock index c57bef2a..e8e47259 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3041,6 +3041,16 @@ __metadata: languageName: node linkType: hard +"@docusaurus/logger@npm:3.9.2": + version: 3.9.2 + resolution: "@docusaurus/logger@npm:3.9.2" + dependencies: + chalk: "npm:^4.1.2" + tslib: "npm:^2.6.0" + checksum: 10c0/a21e0796873386a9be56f25906092a5d67c9bba5e52abf88e4c3c69d7c1e21467c04b3650c2ff2b9a803507aa4946c4173612791a87f04480d63ed87207b124a + languageName: node + linkType: hard + "@docusaurus/mdx-loader@npm:3.10.0": version: 3.10.0 resolution: "@docusaurus/mdx-loader@npm:3.10.0" @@ -3496,6 +3506,27 @@ __metadata: languageName: node linkType: hard +"@docusaurus/types@npm:3.9.2": + version: 3.9.2 + resolution: "@docusaurus/types@npm:3.9.2" + dependencies: + "@mdx-js/mdx": "npm:^3.0.0" + "@types/history": "npm:^4.7.11" + "@types/mdast": "npm:^4.0.2" + "@types/react": "npm:*" + commander: "npm:^5.1.0" + joi: "npm:^17.9.2" + react-helmet-async: "npm:@slorber/react-helmet-async@1.3.0" + utility-types: "npm:^3.10.0" + webpack: "npm:^5.95.0" + webpack-merge: "npm:^5.9.0" + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + checksum: 10c0/e50a9931e97944d39375a97a45ded13bc35baf3c9c14fe66d30944ebe1203df7748a7631291f937bef1a7a98db73c23505620cd8f03d109fbbdfa83725fb2857 + languageName: node + linkType: hard + "@docusaurus/utils-common@npm:3.10.0": version: 3.10.0 resolution: "@docusaurus/utils-common@npm:3.10.0" @@ -3506,6 +3537,16 @@ __metadata: languageName: node linkType: hard +"@docusaurus/utils-common@npm:3.9.2": + version: 3.9.2 + resolution: "@docusaurus/utils-common@npm:3.9.2" + dependencies: + "@docusaurus/types": "npm:3.9.2" + tslib: "npm:^2.6.0" + checksum: 10c0/0e34186ca66cf3c537935d998cfb2ce59beaad31ccb9b41c2288618f386d72dc4359e15e8cb012525211d1f1d753fc439d6c7e9701d6ac801e1121cfa3223d69 + languageName: node + linkType: hard + "@docusaurus/utils-validation@npm:3.10.0": version: 3.10.0 resolution: "@docusaurus/utils-validation@npm:3.10.0" @@ -3551,6 +3592,35 @@ __metadata: languageName: node linkType: hard +"@docusaurus/utils@npm:^3.9.2": + version: 3.9.2 + resolution: "@docusaurus/utils@npm:3.9.2" + dependencies: + "@docusaurus/logger": "npm:3.9.2" + "@docusaurus/types": "npm:3.9.2" + "@docusaurus/utils-common": "npm:3.9.2" + escape-string-regexp: "npm:^4.0.0" + execa: "npm:5.1.1" + file-loader: "npm:^6.2.0" + fs-extra: "npm:^11.1.1" + github-slugger: "npm:^1.5.0" + globby: "npm:^11.1.0" + gray-matter: "npm:^4.0.3" + jiti: "npm:^1.20.0" + js-yaml: "npm:^4.1.0" + lodash: "npm:^4.17.21" + micromatch: "npm:^4.0.5" + p-queue: "npm:^6.6.2" + prompts: "npm:^2.4.2" + resolve-pathname: "npm:^3.0.0" + tslib: "npm:^2.6.0" + url-loader: "npm:^4.1.1" + utility-types: "npm:^3.10.0" + webpack: "npm:^5.88.1" + checksum: 10c0/9796b2e7bc93e47cb27ce81185264c6390b56cd9e68831f6013e4418af512a736f1baf9b97e5df8d646ef4da0650151512abf598f5d58793a3e6c0833c80e06a + languageName: node + linkType: hard + "@dual-bundle/import-meta-resolve@npm:^4.1.0": version: 4.1.0 resolution: "@dual-bundle/import-meta-resolve@npm:4.1.0" @@ -6327,6 +6397,37 @@ __metadata: languageName: node linkType: hard +"@scalar/docusaurus@npm:^0.8.5": + version: 0.8.5 + resolution: "@scalar/docusaurus@npm:0.8.5" + dependencies: + "@scalar/types": "npm:0.7.5" + peerDependencies: + "@docusaurus/utils": ^3.9.2 + react: ^18.0.0 || ^19.0.0 + checksum: 10c0/019aee5e8ef65bad8dcaa3c16fe71da70bcc599c40c3cec4699de888b7e5f5029ce949f27700de13b66d749ebcc1e5aa91195b6ab9a75041e4c4efd6c80e9b09 + languageName: node + linkType: hard + +"@scalar/helpers@npm:0.4.2": + version: 0.4.2 + resolution: "@scalar/helpers@npm:0.4.2" + checksum: 10c0/78c98e50bd63922dc1a212a60c5bfc23e26851c82113989fea5eece4cd67832347b65fc712ee2738545a96ad328b007f40f99eb4f8c4172008c13a34afa52d15 + languageName: node + linkType: hard + +"@scalar/types@npm:0.7.5": + version: 0.7.5 + resolution: "@scalar/types@npm:0.7.5" + dependencies: + "@scalar/helpers": "npm:0.4.2" + nanoid: "npm:^5.1.6" + type-fest: "npm:^5.3.1" + zod: "npm:^4.3.5" + checksum: 10c0/ce986503cae7d18615205bfafea2fc94ebe676962313cd5c81a4a4a2a83b8a73b25295690baa2dc96f8095c98fa4e148734f56c46895e300de4ffb462c3eb6b1 + languageName: node + linkType: hard + "@shikijs/core@npm:3.7.0": version: 3.7.0 resolution: "@shikijs/core@npm:3.7.0" @@ -11364,7 +11465,7 @@ __metadata: languageName: node linkType: hard -"execa@npm:^5.1.1": +"execa@npm:5.1.1, execa@npm:^5.1.1": version: 5.1.1 resolution: "execa@npm:5.1.1" dependencies: @@ -11803,12 +11904,14 @@ __metadata: "@docusaurus/theme-mermaid": "npm:^3.10.0" "@docusaurus/tsconfig": "npm:^3.10.0" "@docusaurus/types": "npm:^3.10.0" + "@docusaurus/utils": "npm:^3.9.2" "@fastify/env": "npm:^5.0.2" "@fishjam-cloud/js-server-sdk": "link:./packages/js-server-sdk/packages/js-server-sdk" "@fishjam-cloud/react-client": "link:./packages/web-client-sdk/packages/react-client" "@fishjam-cloud/react-native-client": "link:./packages/web-client-sdk/packages/mobile-client" "@google/genai": "npm:^1.35.0" "@mdx-js/react": "npm:^3.1.0" + "@scalar/docusaurus": "npm:^0.8.5" "@shikijs/rehype": "npm:^3.6.0" "@shikijs/transformers": "npm:^3.6.0" "@shikijs/twoslash": "npm:^3.6.0" @@ -15828,6 +15931,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:^5.1.6": + version: 5.1.7 + resolution: "nanoid@npm:5.1.7" + bin: + nanoid: bin/nanoid.js + checksum: 10c0/c5523bcb11031d2e8f4eb2ba96f99cd63cbe7f6776748035b4f292c6d524902b142b18a1bf0992e0039f9f925ef51154119bb19ee021766ec0a542d07dc51a82 + languageName: node + linkType: hard + "negotiator@npm:0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" @@ -20044,6 +20156,13 @@ __metadata: languageName: node linkType: hard +"tagged-tag@npm:^1.0.0": + version: 1.0.0 + resolution: "tagged-tag@npm:1.0.0" + checksum: 10c0/91d25c9ffb86a91f20522cefb2cbec9b64caa1febe27ad0df52f08993ff60888022d771e868e6416cf2e72dab68449d2139e8709ba009b74c6c7ecd4000048d1 + languageName: node + linkType: hard + "tapable@npm:^2.0.0, tapable@npm:^2.1.1, tapable@npm:^2.2.0, tapable@npm:^2.2.1": version: 2.2.2 resolution: "tapable@npm:2.2.2" @@ -20347,6 +20466,15 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^5.3.1": + version: 5.5.0 + resolution: "type-fest@npm:5.5.0" + dependencies: + tagged-tag: "npm:^1.0.0" + checksum: 10c0/60bf79a8df45abf99490e3204eceb5cf7f915413f8a69fb578c75cab37ddcb7d29ee21f185f0e1617323ac0b2a441e001b8dc691e220d0b087e9c29ea205538c + languageName: node + linkType: hard + "type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -21345,6 +21473,13 @@ __metadata: languageName: node linkType: hard +"zod@npm:^4.3.5": + version: 4.3.6 + resolution: "zod@npm:4.3.6" + checksum: 10c0/860d25a81ab41d33aa25f8d0d07b091a04acb426e605f396227a796e9e800c44723ed96d0f53a512b57be3d1520f45bf69c0cb3b378a232a00787a2609625307 + languageName: node + linkType: hard + "zwitch@npm:^2.0.0, zwitch@npm:^2.0.4": version: 2.0.4 resolution: "zwitch@npm:2.0.4" From 6735929a98d15a872ee0554a3267c4d56726cd30 Mon Sep 17 00:00:00 2001 From: Tomasz Mazur <47872060+AHGIJMKLKKZNPJKQR@users.noreply.github.com> Date: Tue, 5 May 2026 17:59:31 +0200 Subject: [PATCH 02/10] Add API reference viewer --- docusaurus.config.ts | 24 +++++++++++++++--- src/css/custom.css | 45 ++++++++++++++++++++++++++++++++++ src/theme/NavbarItem/index.tsx | 21 ++++++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 src/theme/NavbarItem/index.tsx diff --git a/docusaurus.config.ts b/docusaurus.config.ts index bc79bed3..c66da1bc 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -268,6 +268,21 @@ const config: Config = { src: "img/logo.svg", }, items: [ + { + type: "doc", + docId: "index", + label: "Docs", + position: "left", + }, + { + to: "/api/rest", + label: "API Reference", + position: "left", + }, + { + type: "docsVersionDropdown", + position: "right", + }, { href: "https://fishjam.io/app/", label: "Fishjam Dashboard", @@ -278,9 +293,6 @@ const config: Config = { label: "GitHub", position: "right", }, - { - type: "docsVersionDropdown", - }, ], }, docsearch: { @@ -348,6 +360,12 @@ const config: Config = { showNavLink: false, configuration: { url: "/docs/api/fishjam-server-openapi.yaml", + hideSearch: true, + persistAuth: true, + defaultOpenFirstTag: false, + authentication: { + preferredSecurityScheme: "management_token" + } }, } as ScalarOptions, ], diff --git a/src/css/custom.css b/src/css/custom.css index 1e898b15..e05c3eec 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -28,15 +28,19 @@ --ifm-color-primary-lightest: #4fddbf; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); } + html[data-theme="light"] body { color: #221f1c; } + html[data-theme="light"] footer.footer { background-color: #fcf4e4; } + html[data-theme="light"] nav.navbar--fixed-top { background-color: #fcf4e4; } + html[data-theme="light"] header.heroBanner_src-pages-index-module { background-color: #9bdcfb; color: #221f1c; @@ -64,6 +68,10 @@ html[data-theme="light"] header.heroBanner_src-pages-index-module { vertical-align: middle; } +.scalar-api-reference .badge { + text-transform: unset; +} + .badge--web { background-color: #3578e5; color: white; @@ -114,3 +122,40 @@ extra spacing keeps it from overlapping with cookies button */ } @import url("./_shiki.css"); + +/* Align the Scalar API reference typography with the rest of the docs. */ +:root { + --scalar-font-size-1: var(--ifm-h3-font-size); + --scalar-font-size-2: var(--ifm-h4-font-size); + --scalar-font-size-3: 0.9375rem; + --scalar-font-size-4: 0.9rem; + --scalar-font-size-5: 0.85rem; + --scalar-font-size-6: 0.8rem; + --scalar-font-size-7: 0.75rem; + + --scalar-paragraph: 0.9375rem; + --scalar-small: 0.9rem; + --scalar-mini: 0.75rem; + + --scalar-heading-1: var(--ifm-h1-font-size); + --scalar-heading-2: var(--ifm-h2-font-size); + --scalar-heading-3: var(--ifm-h3-font-size); + --scalar-heading-4: var(--ifm-h4-font-size); + --scalar-heading-5: var(--ifm-h5-font-size); + --scalar-heading-6: var(--ifm-h6-font-size); + + --scalar-font: var(--ifm-font-family-base); + --scalar-font-code: var(--ifm-font-family-monospace); +} + +/* .scalar-api-reference h1.section-header-label { */ +/* font-size: var(--ifm-h1-font-size); */ +/* } */ +/**/ +/* .scalar-api-reference h2.section-header-label { */ +/* font-size: var(--ifm-h2-font-size); */ +/* } */ +/**/ +/* .scalar-api-reference h3.section-header-label { */ +/* font-size: var(--ifm-h3-font-size); */ +/* } */ diff --git a/src/theme/NavbarItem/index.tsx b/src/theme/NavbarItem/index.tsx new file mode 100644 index 00000000..f08f36aa --- /dev/null +++ b/src/theme/NavbarItem/index.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import { useLocation } from "@docusaurus/router"; +import OriginalNavbarItem from "@theme-original/NavbarItem"; + +type NavbarItemProps = React.ComponentProps; + +export default function NavbarItemWrapper( + props: NavbarItemProps, +): React.JSX.Element | null { + const { pathname } = useLocation(); + const isDocsVersionDropdown = props.type === "docsVersionDropdown"; + const isApiReferencePage = /\/api\/rest(?:\/|$)/.test(pathname); + + // The Scalar REST reference is unversioned, so hiding the docs version dropdown + // here avoids sending users back to Docs when they attempt to switch versions. + if (isDocsVersionDropdown && isApiReferencePage) { + return null; + } + + return ; +} From a095fc88b1566dd2ca99925cb856cfa330095c6e Mon Sep 17 00:00:00 2001 From: Tomasz Mazur <47872060+AHGIJMKLKKZNPJKQR@users.noreply.github.com> Date: Tue, 5 May 2026 17:59:44 +0200 Subject: [PATCH 03/10] Add uv to package managers --- .yarnrc.yml | 5 ----- docs/how-to/backend/server-setup.mdx | 16 ++++++++++++---- docs/tutorials/backend-quick-start.mdx | 16 ++++++++++++++++ .../how-to/backend/server-setup.mdx | 16 ++++++++++++---- .../tutorials/backend-quick-start.mdx | 16 ++++++++++++++++ .../how-to/backend/server-setup.mdx | 16 ++++++++++++---- .../tutorials/backend-quick-start.mdx | 16 ++++++++++++++++ .../how-to/backend/server-setup.mdx | 16 ++++++++++++---- .../tutorials/backend-quick-start.mdx | 16 ++++++++++++++++ 9 files changed, 112 insertions(+), 21 deletions(-) diff --git a/.yarnrc.yml b/.yarnrc.yml index dc612810..3186f3f0 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -1,6 +1 @@ -approvedGitRepositories: - - "**" - -enableScripts: true - nodeLinker: node-modules diff --git a/docs/how-to/backend/server-setup.mdx b/docs/how-to/backend/server-setup.mdx index d572b336..8d303cba 100644 --- a/docs/how-to/backend/server-setup.mdx +++ b/docs/how-to/backend/server-setup.mdx @@ -14,7 +14,7 @@ Install the SDK for the language of your choice. We provide libraries for [**Nod It's also possible to use the bare REST API, in this case you can skip this step. - + ```bash npm install @fishjam-cloud/js-server-sdk @@ -22,7 +22,7 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash yarn add @fishjam-cloud/js-server-sdk @@ -30,7 +30,7 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash pip install fishjam-server-sdk @@ -38,13 +38,21 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash poetry add fishjam-server-sdk ``` + + + + ```bash + uv add fishjam-server-sdk + ``` + + ## Setup your client diff --git a/docs/tutorials/backend-quick-start.mdx b/docs/tutorials/backend-quick-start.mdx index 6475e95c..353d467e 100644 --- a/docs/tutorials/backend-quick-start.mdx +++ b/docs/tutorials/backend-quick-start.mdx @@ -114,6 +114,14 @@ A simple backend server that can create rooms, add peers, and generate tokens fo ``` + + + + ```bash + uv add fishjam-server-sdk + ``` + + @@ -395,6 +403,14 @@ Build a simple HTTP endpoint that your client apps can call: ``` + + + + ```bash + uv add fastapi[standard] + ``` + + diff --git a/versioned_docs/version-0.24.0/how-to/backend/server-setup.mdx b/versioned_docs/version-0.24.0/how-to/backend/server-setup.mdx index 77a75a88..1e4cad5f 100644 --- a/versioned_docs/version-0.24.0/how-to/backend/server-setup.mdx +++ b/versioned_docs/version-0.24.0/how-to/backend/server-setup.mdx @@ -13,7 +13,7 @@ Install the SDK for the language of your choice. We provide libraries for [**Nod It's also possible to use the bare REST API, in this case you can skip this step. - + ```bash npm install @fishjam-cloud/js-server-sdk @@ -21,7 +21,7 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash yarn add @fishjam-cloud/js-server-sdk @@ -29,7 +29,7 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash pip install fishjam-server-sdk @@ -37,13 +37,21 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash poetry add fishjam-server-sdk ``` + + + + ```bash + uv add fishjam-server-sdk + ``` + + ## Setup your client diff --git a/versioned_docs/version-0.24.0/tutorials/backend-quick-start.mdx b/versioned_docs/version-0.24.0/tutorials/backend-quick-start.mdx index 0087c9a2..724f427b 100644 --- a/versioned_docs/version-0.24.0/tutorials/backend-quick-start.mdx +++ b/versioned_docs/version-0.24.0/tutorials/backend-quick-start.mdx @@ -113,6 +113,14 @@ A simple backend server that can create rooms, add peers, and generate tokens fo ``` + + + + ```bash + uv add fishjam-server-sdk + ``` + + @@ -394,6 +402,14 @@ Build a simple HTTP endpoint that your client apps can call: ``` + + + + ```bash + uv add fastapi[standard] + ``` + + diff --git a/versioned_docs/version-0.25.0/how-to/backend/server-setup.mdx b/versioned_docs/version-0.25.0/how-to/backend/server-setup.mdx index 84903f39..26f62786 100644 --- a/versioned_docs/version-0.25.0/how-to/backend/server-setup.mdx +++ b/versioned_docs/version-0.25.0/how-to/backend/server-setup.mdx @@ -13,7 +13,7 @@ Install the SDK for the language of your choice. We provide libraries for [**Nod It's also possible to use the bare REST API, in this case you can skip this step. - + ```bash npm install @fishjam-cloud/js-server-sdk @@ -21,7 +21,7 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash yarn add @fishjam-cloud/js-server-sdk @@ -29,7 +29,7 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash pip install fishjam-server-sdk @@ -37,13 +37,21 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash poetry add fishjam-server-sdk ``` + + + + ```bash + uv add fishjam-server-sdk + ``` + + ## Setup your client diff --git a/versioned_docs/version-0.25.0/tutorials/backend-quick-start.mdx b/versioned_docs/version-0.25.0/tutorials/backend-quick-start.mdx index 0087c9a2..e589a1d6 100644 --- a/versioned_docs/version-0.25.0/tutorials/backend-quick-start.mdx +++ b/versioned_docs/version-0.25.0/tutorials/backend-quick-start.mdx @@ -113,6 +113,14 @@ A simple backend server that can create rooms, add peers, and generate tokens fo ``` + + + + ```bash + uv add fishjam-server-sdk + ``` + + @@ -394,6 +402,14 @@ Build a simple HTTP endpoint that your client apps can call: ``` + + + + ```bash + uv add fastapi[standard] + ``` + + diff --git a/versioned_docs/version-0.26.0/how-to/backend/server-setup.mdx b/versioned_docs/version-0.26.0/how-to/backend/server-setup.mdx index d572b336..8d303cba 100644 --- a/versioned_docs/version-0.26.0/how-to/backend/server-setup.mdx +++ b/versioned_docs/version-0.26.0/how-to/backend/server-setup.mdx @@ -14,7 +14,7 @@ Install the SDK for the language of your choice. We provide libraries for [**Nod It's also possible to use the bare REST API, in this case you can skip this step. - + ```bash npm install @fishjam-cloud/js-server-sdk @@ -22,7 +22,7 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash yarn add @fishjam-cloud/js-server-sdk @@ -30,7 +30,7 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash pip install fishjam-server-sdk @@ -38,13 +38,21 @@ It's also possible to use the bare REST API, in this case you can skip this step - + ```bash poetry add fishjam-server-sdk ``` + + + + ```bash + uv add fishjam-server-sdk + ``` + + ## Setup your client diff --git a/versioned_docs/version-0.26.0/tutorials/backend-quick-start.mdx b/versioned_docs/version-0.26.0/tutorials/backend-quick-start.mdx index 6475e95c..0c423d2b 100644 --- a/versioned_docs/version-0.26.0/tutorials/backend-quick-start.mdx +++ b/versioned_docs/version-0.26.0/tutorials/backend-quick-start.mdx @@ -114,6 +114,14 @@ A simple backend server that can create rooms, add peers, and generate tokens fo ``` + + + + ```bash + uv add fishjam-server-sdk + ``` + + @@ -395,6 +403,14 @@ Build a simple HTTP endpoint that your client apps can call: ``` + + + + ```bash + uv add fastapi[standard] + ``` + + From 1a0fc1cf5b2497957bc90715bf8335a54203a196 Mon Sep 17 00:00:00 2001 From: Tomasz Mazur <47872060+AHGIJMKLKKZNPJKQR@users.noreply.github.com> Date: Tue, 5 May 2026 18:29:02 +0200 Subject: [PATCH 04/10] Remove commented css --- src/css/custom.css | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/css/custom.css b/src/css/custom.css index e05c3eec..c28f4eaa 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -147,15 +147,3 @@ extra spacing keeps it from overlapping with cookies button */ --scalar-font: var(--ifm-font-family-base); --scalar-font-code: var(--ifm-font-family-monospace); } - -/* .scalar-api-reference h1.section-header-label { */ -/* font-size: var(--ifm-h1-font-size); */ -/* } */ -/**/ -/* .scalar-api-reference h2.section-header-label { */ -/* font-size: var(--ifm-h2-font-size); */ -/* } */ -/**/ -/* .scalar-api-reference h3.section-header-label { */ -/* font-size: var(--ifm-h3-font-size); */ -/* } */ From 10baee61e8411a546e9aca29e3f4c7d8ce3328ae Mon Sep 17 00:00:00 2001 From: Tomasz Mazur <47872060+AHGIJMKLKKZNPJKQR@users.noreply.github.com> Date: Tue, 5 May 2026 18:38:22 +0200 Subject: [PATCH 05/10] Format --- docs/tutorials/backend-quick-start.mdx | 2 +- docusaurus.config.ts | 7 +++---- .../version-0.25.0/tutorials/backend-quick-start.mdx | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/tutorials/backend-quick-start.mdx b/docs/tutorials/backend-quick-start.mdx index 353d467e..0c423d2b 100644 --- a/docs/tutorials/backend-quick-start.mdx +++ b/docs/tutorials/backend-quick-start.mdx @@ -403,7 +403,7 @@ Build a simple HTTP endpoint that your client apps can call: ``` - + ```bash diff --git a/docusaurus.config.ts b/docusaurus.config.ts index c66da1bc..32c16ba5 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -47,8 +47,7 @@ if (hasBrokenLocalStorage) { } as Storage; } -const { rendererClassic, transformerTwoslash } = - require("@shikijs/twoslash"); +const { rendererClassic, transformerTwoslash } = require("@shikijs/twoslash"); function isErrorFromVersionedDocs(options: { meta?: { __raw?: string } }) { if (options.meta?.__raw?.includes("loc=")) { @@ -364,8 +363,8 @@ const config: Config = { persistAuth: true, defaultOpenFirstTag: false, authentication: { - preferredSecurityScheme: "management_token" - } + preferredSecurityScheme: "management_token", + }, }, } as ScalarOptions, ], diff --git a/versioned_docs/version-0.25.0/tutorials/backend-quick-start.mdx b/versioned_docs/version-0.25.0/tutorials/backend-quick-start.mdx index e589a1d6..724f427b 100644 --- a/versioned_docs/version-0.25.0/tutorials/backend-quick-start.mdx +++ b/versioned_docs/version-0.25.0/tutorials/backend-quick-start.mdx @@ -402,7 +402,7 @@ Build a simple HTTP endpoint that your client apps can call: ``` - + ```bash From f5c1f628a8b9dc5efae11439b9aec2be3615ccf8 Mon Sep 17 00:00:00 2001 From: Tomasz Mazur <47872060+AHGIJMKLKKZNPJKQR@users.noreply.github.com> Date: Tue, 5 May 2026 18:54:26 +0200 Subject: [PATCH 06/10] Bump utils version --- package.json | 2 +- yarn.lock | 46 +++++++++++++++++++++++----------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index e3c28a1e..7ef0fc47 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "@docusaurus/preset-classic": "^3.10.0", "@docusaurus/remark-plugin-npm2yarn": "^3.10.0", "@docusaurus/theme-mermaid": "^3.10.0", - "@docusaurus/utils": "^3.9.2", + "@docusaurus/utils": "^3.10.0", "@fastify/env": "^5.0.2", "@fishjam-cloud/js-server-sdk": "link:./packages/js-server-sdk/packages/js-server-sdk", "@fishjam-cloud/react-client": "link:./packages/web-client-sdk/packages/react-client", diff --git a/yarn.lock b/yarn.lock index e8e47259..edee125b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3041,13 +3041,13 @@ __metadata: languageName: node linkType: hard -"@docusaurus/logger@npm:3.9.2": - version: 3.9.2 - resolution: "@docusaurus/logger@npm:3.9.2" +"@docusaurus/logger@npm:3.10.1": + version: 3.10.1 + resolution: "@docusaurus/logger@npm:3.10.1" dependencies: chalk: "npm:^4.1.2" tslib: "npm:^2.6.0" - checksum: 10c0/a21e0796873386a9be56f25906092a5d67c9bba5e52abf88e4c3c69d7c1e21467c04b3650c2ff2b9a803507aa4946c4173612791a87f04480d63ed87207b124a + checksum: 10c0/c78c676de0cf11ba5737abe8d13ebb67c4fdd8019ac8512ee18b34c27fdd5aaf32b703da3596271592be8615094507754791ac16587a24146f3830e1558a24c3 languageName: node linkType: hard @@ -3506,9 +3506,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/types@npm:3.9.2": - version: 3.9.2 - resolution: "@docusaurus/types@npm:3.9.2" +"@docusaurus/types@npm:3.10.1": + version: 3.10.1 + resolution: "@docusaurus/types@npm:3.10.1" dependencies: "@mdx-js/mdx": "npm:^3.0.0" "@types/history": "npm:^4.7.11" @@ -3523,7 +3523,7 @@ __metadata: peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/e50a9931e97944d39375a97a45ded13bc35baf3c9c14fe66d30944ebe1203df7748a7631291f937bef1a7a98db73c23505620cd8f03d109fbbdfa83725fb2857 + checksum: 10c0/63cc1d92ec775fb0e58f156b4edc7075612943a94d15d4648b60effcbc34c70a1092569d66d552878779b48d5111abe2fc154ba6a3bca2af0383550c9f9a015b languageName: node linkType: hard @@ -3537,13 +3537,13 @@ __metadata: languageName: node linkType: hard -"@docusaurus/utils-common@npm:3.9.2": - version: 3.9.2 - resolution: "@docusaurus/utils-common@npm:3.9.2" +"@docusaurus/utils-common@npm:3.10.1": + version: 3.10.1 + resolution: "@docusaurus/utils-common@npm:3.10.1" dependencies: - "@docusaurus/types": "npm:3.9.2" + "@docusaurus/types": "npm:3.10.1" tslib: "npm:^2.6.0" - checksum: 10c0/0e34186ca66cf3c537935d998cfb2ce59beaad31ccb9b41c2288618f386d72dc4359e15e8cb012525211d1f1d753fc439d6c7e9701d6ac801e1121cfa3223d69 + checksum: 10c0/1dde7a5c538a2cbe9eba46c9a3991a773e2d9d5b9c489cb010f9284c33cba7d494c1300557f850fa6a6e857747ca835b91f6036b02a726e13d296d7a65f8d8db languageName: node linkType: hard @@ -3592,15 +3592,15 @@ __metadata: languageName: node linkType: hard -"@docusaurus/utils@npm:^3.9.2": - version: 3.9.2 - resolution: "@docusaurus/utils@npm:3.9.2" +"@docusaurus/utils@npm:^3.10.0": + version: 3.10.1 + resolution: "@docusaurus/utils@npm:3.10.1" dependencies: - "@docusaurus/logger": "npm:3.9.2" - "@docusaurus/types": "npm:3.9.2" - "@docusaurus/utils-common": "npm:3.9.2" + "@docusaurus/logger": "npm:3.10.1" + "@docusaurus/types": "npm:3.10.1" + "@docusaurus/utils-common": "npm:3.10.1" escape-string-regexp: "npm:^4.0.0" - execa: "npm:5.1.1" + execa: "npm:^5.1.1" file-loader: "npm:^6.2.0" fs-extra: "npm:^11.1.1" github-slugger: "npm:^1.5.0" @@ -3617,7 +3617,7 @@ __metadata: url-loader: "npm:^4.1.1" utility-types: "npm:^3.10.0" webpack: "npm:^5.88.1" - checksum: 10c0/9796b2e7bc93e47cb27ce81185264c6390b56cd9e68831f6013e4418af512a736f1baf9b97e5df8d646ef4da0650151512abf598f5d58793a3e6c0833c80e06a + checksum: 10c0/97d51da30035ef34eced1dbc937f829309a8165a07a9c66d87c5deec03fb62150cbc70b2763ffdec0286b21f1be53f4011a036e4265cb971a892f0ab12172e0a languageName: node linkType: hard @@ -11465,7 +11465,7 @@ __metadata: languageName: node linkType: hard -"execa@npm:5.1.1, execa@npm:^5.1.1": +"execa@npm:^5.1.1": version: 5.1.1 resolution: "execa@npm:5.1.1" dependencies: @@ -11904,7 +11904,7 @@ __metadata: "@docusaurus/theme-mermaid": "npm:^3.10.0" "@docusaurus/tsconfig": "npm:^3.10.0" "@docusaurus/types": "npm:^3.10.0" - "@docusaurus/utils": "npm:^3.9.2" + "@docusaurus/utils": "npm:^3.10.0" "@fastify/env": "npm:^5.0.2" "@fishjam-cloud/js-server-sdk": "link:./packages/js-server-sdk/packages/js-server-sdk" "@fishjam-cloud/react-client": "link:./packages/web-client-sdk/packages/react-client" From dbdc0248e20f914afe13687ed409f07788ca4eff Mon Sep 17 00:00:00 2001 From: Tomasz Mazur <47872060+AHGIJMKLKKZNPJKQR@users.noreply.github.com> Date: Wed, 6 May 2026 16:27:04 +0200 Subject: [PATCH 07/10] Remove debug --- docusaurus.config.ts | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 32c16ba5..2b95c7ac 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -5,7 +5,6 @@ import type { ScalarOptions } from "@scalar/docusaurus"; import { BundledLanguage, bundledLanguages } from "shiki"; import type { MDXPlugin } from "@docusaurus/mdx-loader"; import rehypeShiki, { RehypeShikiOptions } from "@shikijs/rehype"; -import { removeTwoslashNotations } from "twoslash"; import { transformerMetaHighlight, transformerNotationDiff, @@ -14,6 +13,7 @@ import { transformerNotationFocus, } from "@shikijs/transformers"; +import { rendererClassic, transformerTwoslash } from "@shikijs/twoslash"; import { NormalizedSidebar, NormalizedSidebarItem, @@ -23,31 +23,6 @@ import { import { llmsRootContent } from "./src/content/llms-root-content"; import { createRedirects } from "./redirects"; -const hasBrokenLocalStorage = - typeof globalThis.localStorage === "object" && - typeof globalThis.localStorage?.getItem !== "function"; - -if (hasBrokenLocalStorage) { - const storage = new Map(); - globalThis.localStorage = { - getItem: (key: string) => storage.get(key) ?? null, - setItem: (key: string, value: string) => { - storage.set(key, value); - }, - removeItem: (key: string) => { - storage.delete(key); - }, - clear: () => { - storage.clear(); - }, - key: (index: number) => Array.from(storage.keys())[index] ?? null, - get length() { - return storage.size; - }, - } as Storage; -} - -const { rendererClassic, transformerTwoslash } = require("@shikijs/twoslash"); function isErrorFromVersionedDocs(options: { meta?: { __raw?: string } }) { if (options.meta?.__raw?.includes("loc=")) { From c4e02b4a254e788a31c9adde1b313b6eccd24208 Mon Sep 17 00:00:00 2001 From: Tomasz Mazur <47872060+AHGIJMKLKKZNPJKQR@users.noreply.github.com> Date: Wed, 6 May 2026 16:35:41 +0200 Subject: [PATCH 08/10] Format --- docusaurus.config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 2b95c7ac..1006d5fd 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -23,7 +23,6 @@ import { import { llmsRootContent } from "./src/content/llms-root-content"; import { createRedirects } from "./redirects"; - function isErrorFromVersionedDocs(options: { meta?: { __raw?: string } }) { if (options.meta?.__raw?.includes("loc=")) { const locMatch = options.meta.__raw.match(/loc=([^\s]+)/); From e1391b16fe5dc9dedc5e1d27ad121e93003a1a78 Mon Sep 17 00:00:00 2001 From: Tomasz Mazur <47872060+AHGIJMKLKKZNPJKQR@users.noreply.github.com> Date: Wed, 6 May 2026 16:41:20 +0200 Subject: [PATCH 09/10] Simplify NavbarItem --- src/theme/NavbarItem/index.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/theme/NavbarItem/index.tsx b/src/theme/NavbarItem/index.tsx index f08f36aa..cac1dc3c 100644 --- a/src/theme/NavbarItem/index.tsx +++ b/src/theme/NavbarItem/index.tsx @@ -9,10 +9,9 @@ export default function NavbarItemWrapper( ): React.JSX.Element | null { const { pathname } = useLocation(); const isDocsVersionDropdown = props.type === "docsVersionDropdown"; - const isApiReferencePage = /\/api\/rest(?:\/|$)/.test(pathname); + const isApiReferencePage = pathname.startsWith("/api/rest"); - // The Scalar REST reference is unversioned, so hiding the docs version dropdown - // here avoids sending users back to Docs when they attempt to switch versions. + // The Scalar REST reference is unversioned, so we hide the version dropdown if (isDocsVersionDropdown && isApiReferencePage) { return null; } From f7d23370eaa325d9a58e36fe560c2e11db2e8f55 Mon Sep 17 00:00:00 2001 From: Tomasz Mazur <47872060+AHGIJMKLKKZNPJKQR@users.noreply.github.com> Date: Thu, 7 May 2026 12:42:04 +0200 Subject: [PATCH 10/10] Update openapi --- static/api/fishjam-server-openapi.yaml | 664 ++++++++++++++----------- 1 file changed, 374 insertions(+), 290 deletions(-) diff --git a/static/api/fishjam-server-openapi.yaml b/static/api/fishjam-server-openapi.yaml index 6c0383c1..5170fcd0 100644 --- a/static/api/fishjam-server-openapi.yaml +++ b/static/api/fishjam-server-openapi.yaml @@ -8,7 +8,7 @@ components: data: properties: token: - $ref: "#/components/schemas/AuthToken" + $ref: '#/components/schemas/AuthToken' required: - token type: object @@ -21,16 +21,16 @@ components: description: Options specific to the Agent peer properties: output: - $ref: "#/components/schemas/AgentOutput" + $ref: '#/components/schemas/AgentOutput' subscribeMode: - $ref: "#/components/schemas/SubscribeMode" + $ref: '#/components/schemas/SubscribeMode' title: PeerOptionsAgent type: object RoomDetailsResponse: description: Response containing room details properties: data: - $ref: "#/components/schemas/Room" + $ref: '#/components/schemas/Room' required: - data title: RoomDetailsResponse @@ -41,22 +41,21 @@ components: data: properties: room: - $ref: "#/components/schemas/Room" + $ref: '#/components/schemas/Room' required: - room - - fishjam_address type: object required: - data title: RoomCreateDetailsResponse type: object Room: - description: Description of the room state + description: State of a room properties: compositionInfo: - $ref: "#/components/schemas/CompositionInfo" + $ref: '#/components/schemas/CompositionInfo' config: - $ref: "#/components/schemas/RoomConfig" + $ref: '#/components/schemas/RoomConfig' id: description: Room ID example: room-1 @@ -64,7 +63,7 @@ components: peers: description: List of all peers items: - $ref: "#/components/schemas/Peer" + $ref: '#/components/schemas/Peer' type: array required: - id @@ -104,6 +103,11 @@ components: description: Restrics stream to audio only nullable: true type: boolean + batchWebhookNotifications: + default: false + description: If true, webhook notifications for this stream are coalesced into a single NotificationBatch per HTTP send instead of one request per notification. VAD notifications are unaffected. + nullable: false + type: boolean public: default: false description: True if livestream viewers can omit specifying a token. @@ -138,11 +142,11 @@ components: data: properties: peer: - $ref: "#/components/schemas/Peer" + $ref: '#/components/schemas/Peer' peer_websocket_url: - $ref: "#/components/schemas/WebsocketURL" + $ref: '#/components/schemas/WebsocketURL' token: - $ref: "#/components/schemas/AuthToken" + $ref: '#/components/schemas/AuthToken' required: - peer - token @@ -155,7 +159,7 @@ components: description: Response containing streamer details properties: data: - $ref: "#/components/schemas/Streamer" + $ref: '#/components/schemas/Streamer' required: - data title: StreamerDetailsResponse @@ -187,7 +191,7 @@ components: properties: data: items: - $ref: "#/components/schemas/Stream" + $ref: '#/components/schemas/Stream' type: array required: - data @@ -197,9 +201,9 @@ components: additionalProperties: false description: Peer-specific options oneOf: - - $ref: "#/components/schemas/PeerOptionsWebRTC" - - $ref: "#/components/schemas/PeerOptionsAgent" - - $ref: "#/components/schemas/PeerOptionsVapi" + - $ref: '#/components/schemas/PeerOptionsWebRTC' + - $ref: '#/components/schemas/PeerOptionsAgent' + - $ref: '#/components/schemas/PeerOptionsVapi' title: PeerOptions type: object Streamer: @@ -209,11 +213,13 @@ components: description: Assigned streamer id type: string status: + description: Streamer connection status enum: - connected - disconnected type: string token: + description: Token streamer should authorize with example: 5cdac726-57a3-4ecb-b1d5-72a3d62ec242 type: string required: @@ -234,7 +240,7 @@ components: description: Response containing viewer details properties: data: - $ref: "#/components/schemas/Viewer" + $ref: '#/components/schemas/Viewer' required: - data title: ViewerDetailsResponse @@ -283,15 +289,16 @@ components: description: Peer configuration properties: options: - $ref: "#/components/schemas/PeerOptions" + $ref: '#/components/schemas/PeerOptions' type: - $ref: "#/components/schemas/PeerType" + $ref: '#/components/schemas/PeerType' required: - options - type title: PeerConfig type: object TrackMetadata: + description: Metadata attached to the track by the peer example: source: camera nullable: true @@ -322,12 +329,12 @@ components: peers: description: List of peer IDs this peer subscribes to items: - $ref: "#/components/schemas/PeerID" + $ref: '#/components/schemas/PeerID' type: array tracks: description: List of track IDs this peer subscribes to items: - $ref: "#/components/schemas/TrackID" + $ref: '#/components/schemas/TrackID' type: array required: - peers @@ -340,9 +347,10 @@ components: title: WebsocketURL type: string ViewerToken: - description: Token for authorizing broadcaster viewer connection + description: Viewer authorization token properties: token: + description: Token viewer should authorize with example: 5cdac726-57a3-4ecb-b1d5-72a3d62ec242 type: string required: @@ -356,6 +364,7 @@ components: description: Assigned viewer id type: string token: + description: Token viewer should authorize with example: 5cdac726-57a3-4ecb-b1d5-72a3d62ec242 type: string required: @@ -372,6 +381,11 @@ components: additionalProperties: false description: Room configuration properties: + batchWebhookNotifications: + default: false + description: If true, webhook notifications for this room are coalesced into a single NotificationBatch per HTTP send instead of one request per notification. VAD notifications are unaffected. + nullable: false + type: boolean maxPeers: description: Maximum amount of peers allowed into the room example: 10 @@ -384,9 +398,9 @@ components: nullable: false type: boolean roomType: - $ref: "#/components/schemas/RoomType" + $ref: '#/components/schemas/RoomType' videoCodec: - $ref: "#/components/schemas/VideoCodec" + $ref: '#/components/schemas/VideoCodec' webhookUrl: description: URL where Fishjam notifications will be sent example: https://backend.address.com/fishjam-notifications-endpoint @@ -406,22 +420,22 @@ components: description: Describes peer status properties: id: - $ref: "#/components/schemas/PeerID" + $ref: '#/components/schemas/PeerID' metadata: - $ref: "#/components/schemas/PeerMetadata" + $ref: '#/components/schemas/PeerMetadata' status: - $ref: "#/components/schemas/PeerStatus" + $ref: '#/components/schemas/PeerStatus' subscribeMode: - $ref: "#/components/schemas/SubscribeMode" + $ref: '#/components/schemas/SubscribeMode' subscriptions: - $ref: "#/components/schemas/Subscriptions" + $ref: '#/components/schemas/Subscriptions' tracks: description: List of all peer's tracks items: - $ref: "#/components/schemas/Track" + $ref: '#/components/schemas/Track' type: array type: - $ref: "#/components/schemas/PeerType" + $ref: '#/components/schemas/PeerType' required: - id - type @@ -443,7 +457,7 @@ components: forwardings: description: List of active track forwardings items: - $ref: "#/components/schemas/TrackForwardingInfo" + $ref: '#/components/schemas/TrackForwardingInfo' type: array required: - compositionUrl @@ -451,6 +465,7 @@ components: title: CompositionInfo type: object TrackType: + description: Media type carried by the track enum: - audio - video @@ -468,7 +483,7 @@ components: pattern: ^[a-zA-Z0-9-]+$ type: string subscribeMode: - $ref: "#/components/schemas/SubscribeMode" + $ref: '#/components/schemas/SubscribeMode' required: - apiKey - callId @@ -478,7 +493,7 @@ components: description: Response containing stream details properties: data: - $ref: "#/components/schemas/Stream" + $ref: '#/components/schemas/Stream' required: - data title: StreamDetailsResponse @@ -488,9 +503,9 @@ components: description: Options specific to the WebRTC peer properties: metadata: - $ref: "#/components/schemas/WebRTCMetadata" + $ref: '#/components/schemas/WebRTCMetadata' subscribeMode: - $ref: "#/components/schemas/SubscribeMode" + $ref: '#/components/schemas/SubscribeMode' title: PeerOptionsWebRTC type: object RoomsListingResponse: @@ -498,14 +513,14 @@ components: properties: data: items: - $ref: "#/components/schemas/Room" + $ref: '#/components/schemas/Room' type: array required: - data title: RoomsListingResponse type: object Stream: - description: Describes stream status + description: State of a stream properties: audioOnly: description: True if stream is restricted to audio only @@ -514,16 +529,17 @@ components: description: Assigned stream id type: string public: + description: True if livestream viewers can omit specifying a token. type: boolean streamers: description: List of all streamers items: - $ref: "#/components/schemas/Streamer" + $ref: '#/components/schemas/Streamer' type: array viewers: description: List of all viewers items: - $ref: "#/components/schemas/Viewer" + $ref: '#/components/schemas/Viewer' type: array required: - id @@ -533,9 +549,10 @@ components: title: Stream type: object StreamerToken: - description: Token for authorizing broadcaster streamer connection + description: Streamer authorization token properties: token: + description: Token streamer should authorize with example: 5cdac726-57a3-4ecb-b1d5-72a3d62ec242 type: string required: @@ -543,14 +560,14 @@ components: title: StreamerToken type: object Track: - description: Describes media track of a Peer + description: Media track of a Peer properties: id: - $ref: "#/components/schemas/TrackID" + $ref: '#/components/schemas/TrackID' metadata: - $ref: "#/components/schemas/TrackMetadata" + $ref: '#/components/schemas/TrackMetadata' type: - $ref: "#/components/schemas/TrackType" + $ref: '#/components/schemas/TrackType' title: Track type: object AgentOutput: @@ -558,9 +575,9 @@ components: description: Output audio options properties: audioFormat: - $ref: "#/components/schemas/AudioFormat" + $ref: '#/components/schemas/AudioFormat' audioSampleRate: - $ref: "#/components/schemas/AudioSampleRate" + $ref: '#/components/schemas/AudioSampleRate' title: AgentOutput type: object AudioFormat: @@ -572,90 +589,106 @@ components: title: AudioFormat type: string securitySchemes: - authorization: + management_token: scheme: bearer type: http info: - license: - name: Apache 2.0 - url: https://www.apache.org/licenses/LICENSE-2.0 - title: Fishjam Media Server + contact: + email: contact@fishjam.io + name: Fishjam Support + description: | + API for managing Fishjam real-time media resources. + + ## Authentication + ## + Credentials (Fishjam ID, Fishjam Management Token) can be obtained at https://fishjam.io/app. + All requests require HTTP Bearer authorization using the Fishjam Management Token. + + ## Fishjam SDKs + ## + For TypeScript and Python users, we provide SDKs that simplify using this API. + We recommend using them instead of manually consuming the API in these languages. + + You can learn more about our SDKs in our [SDK Docs](http://fishjam.swmansion.com/docs/how-to/backend/server-setup) + title: Fishjam API version: 0.26.4 openapi: 3.0.0 paths: /livestream: get: callbacks: {} + description: List all livestreams. operationId: get_all_streams parameters: [] responses: - "200": + '200': content: application/json: schema: - $ref: "#/components/schemas/StreamsListingResponse" + $ref: '#/components/schemas/StreamsListingResponse' description: Success - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Show information about all streams + - management_token: [] + summary: List all streams tags: - - stream + - Streams post: callbacks: {} + description: Create a new livestream with the given configuration. operationId: create_stream parameters: [] requestBody: content: application/json: schema: - $ref: "#/components/schemas/StreamConfig" - description: Stream configuration + $ref: '#/components/schemas/StreamConfig' required: false responses: - "201": + '201': content: application/json: schema: - $ref: "#/components/schemas/StreamDetailsResponse" + $ref: '#/components/schemas/StreamDetailsResponse' description: Stream created successfully - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request structure - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Creates stream + - management_token: [] + summary: Create a stream tags: - - stream + - Streams /livestream/{stream_id}: delete: callbacks: {} + description: Delete a stream by id and disconnect all of its streamers and viewers. operationId: delete_stream parameters: - description: Stream ID @@ -665,27 +698,28 @@ paths: schema: type: string responses: - "204": + '204': description: Successfully deleted stream - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Deletes stream + - management_token: [] + summary: Delete a stream tags: - - stream + - Streams get: callbacks: {} + description: Get a stream by id. operationId: get_stream parameters: - description: Stream ID @@ -695,38 +729,39 @@ paths: schema: type: string responses: - "200": + '200': content: application/json: schema: - $ref: "#/components/schemas/StreamDetailsResponse" + $ref: '#/components/schemas/StreamDetailsResponse' description: Success - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Stream doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Shows information about the stream + - management_token: [] + summary: Get a stream tags: - - stream + - Streams /livestream/{stream_id}/streamer: post: callbacks: {} + description: Create a streamer for a stream and return its credentials. operationId: create_streamer parameters: - description: Stream id @@ -736,38 +771,39 @@ paths: schema: type: string responses: - "201": + '201': content: application/json: schema: - $ref: "#/components/schemas/StreamerDetailsResponse" + $ref: '#/components/schemas/StreamerDetailsResponse' description: Streamer successfully created - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Stream doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Creates streamer + - management_token: [] + summary: Create a streamer tags: - - streamer + - Streamers /livestream/{stream_id}/streamer/{streamer_id}: delete: callbacks: {} + description: Delete a streamer from a stream and revoke its token. operationId: delete_streamer parameters: - description: Stream id @@ -783,28 +819,29 @@ paths: schema: type: string responses: - "204": + '204': description: Streamer successfully deleted - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Deletes streamer + - management_token: [] + summary: Delete a streamer tags: - - streamer + - Streamers /livestream/{stream_id}/viewer: post: callbacks: {} + description: Create a viewer for a stream and return its credentials. operationId: create_viewer parameters: - description: Stream id @@ -814,38 +851,39 @@ paths: schema: type: string responses: - "201": + '201': content: application/json: schema: - $ref: "#/components/schemas/ViewerDetailsResponse" + $ref: '#/components/schemas/ViewerDetailsResponse' description: Viewer successfully created - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Stream doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Creates viewer + - management_token: [] + summary: Create a viewer tags: - - viewer + - Viewers /livestream/{stream_id}/viewer/{viewer_id}: delete: callbacks: {} + description: Delete a viewer from a stream and revoke its token. operationId: delete_viewer parameters: - description: Stream id @@ -861,98 +899,100 @@ paths: schema: type: string responses: - "204": + '204': description: Viewer successfully deleted - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Deletes viewer + - management_token: [] + summary: Delete a viewer tags: - - viewer + - Viewers /room: get: callbacks: {} + description: List all rooms and livestreams. operationId: get_all_rooms parameters: [] responses: - "200": + '200': content: application/json: schema: - $ref: "#/components/schemas/RoomsListingResponse" + $ref: '#/components/schemas/RoomsListingResponse' description: Success - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized security: - - authorization: [] - summary: Show information about all rooms + - management_token: [] + summary: List all rooms tags: - - room + - Rooms post: callbacks: {} + description: Create a new room with the given configuration. operationId: create_room parameters: [] requestBody: content: application/json: schema: - $ref: "#/components/schemas/RoomConfig" - description: Room configuration + $ref: '#/components/schemas/RoomConfig' required: false responses: - "201": + '201': content: application/json: schema: - $ref: "#/components/schemas/RoomCreateDetailsResponse" + $ref: '#/components/schemas/RoomCreateDetailsResponse' description: Room successfully created - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request structure - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "402": + '402': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Usage quota exceeded for free tier - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Creates a room + - management_token: [] + summary: Create a room tags: - - room + - Rooms /room/{room_id}: delete: callbacks: {} + description: Delete a room by id and disconnect all of its peers. operationId: delete_room parameters: - description: Room id @@ -962,39 +1002,40 @@ paths: schema: type: string responses: - "204": + '204': description: Successfully deleted room - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Room doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Delete the room + - management_token: [] + summary: Delete a room tags: - - room + - Rooms get: callbacks: {} + description: Get a room by id. operationId: get_room parameters: - description: Room ID @@ -1004,44 +1045,45 @@ paths: schema: type: string responses: - "200": + '200': content: application/json: schema: - $ref: "#/components/schemas/RoomDetailsResponse" + $ref: '#/components/schemas/RoomDetailsResponse' description: Success - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Room doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Shows information about the room + - management_token: [] + summary: Get a room tags: - - room + - Rooms /room/{room_id}/peer: post: callbacks: {} + description: Add a peer to a room and return its connection token. operationId: add_peer parameters: - description: Room id @@ -1054,60 +1096,60 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/PeerConfig" - description: Peer specification + $ref: '#/components/schemas/PeerConfig' required: false responses: - "201": + '201': content: application/json: schema: - $ref: "#/components/schemas/PeerDetailsResponse" + $ref: '#/components/schemas/PeerDetailsResponse' description: Peer successfully created - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request body structure - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "402": + '402': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Usage quota exceeded for free tier - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Room doesn't exist - "409": + '409': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Request conflict - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Create peer + - management_token: [] + summary: Create a peer tags: - - room + - Rooms /room/{room_id}/peer/{id}: delete: callbacks: {} + description: Remove a peer from a room and disconnect it. operationId: delete_peer parameters: - description: Room id @@ -1123,40 +1165,41 @@ paths: schema: type: string responses: - "204": + '204': description: Peer successfully deleted - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request body structure - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Room ID or Peer ID references a resource that doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Delete peer + - management_token: [] + summary: Delete a peer tags: - - room + - Rooms /room/{room_id}/peer/{id}/refresh_token: post: callbacks: {} + description: Issue a fresh connection token for an existing peer. operationId: refresh_token parameters: - description: Room id @@ -1172,44 +1215,45 @@ paths: schema: type: string responses: - "201": + '201': content: application/json: schema: - $ref: "#/components/schemas/PeerRefreshTokenResponse" + $ref: '#/components/schemas/PeerRefreshTokenResponse' description: Token successfully created - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request body structure - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Room ID or Peer ID references a resource that doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Refresh peer token + - management_token: [] + summary: Refresh a peer token tags: - - room + - Rooms /room/{room_id}/peer/{id}/subscribe_peer: post: callbacks: {} + description: Subscribe a peer to all current and future tracks published by another peer in the same room. operationId: subscribe_peer parameters: - description: Room id @@ -1231,40 +1275,41 @@ paths: schema: type: string responses: - "200": + '200': description: Peer successfully subscribed to another peer's tracks - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request body structure - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Room ID or Peer ID references a resource that doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Subscribe peer to another peer's tracks + - management_token: [] + summary: Subscribe a peer to another peer's tracks tags: - - room + - Rooms /room/{room_id}/peer/{id}/subscribe_tracks: post: callbacks: {} + description: Subscribe a peer to a specific list of track IDs in the same room. operationId: subscribe_tracks parameters: - description: Room id @@ -1287,7 +1332,7 @@ paths: track_ids: description: List of track IDs to subscribe to items: - $ref: "#/components/schemas/TrackID" + $ref: '#/components/schemas/TrackID' type: array required: - track_ids @@ -1295,40 +1340,41 @@ paths: description: Track IDs required: false responses: - "200": + '200': description: Peer successfully subscribed to tracks - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request body structure - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Room ID or Peer ID references a resource that doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Subscribe peer to specific tracks + - management_token: [] + summary: Subscribe a peer to specific tracks tags: - - room + - Rooms /room/{room_id}/streamer: post: callbacks: {} + description: Issue a fresh streamer token. operationId: generate_streamer_token parameters: - description: ID of the stream. @@ -1338,44 +1384,45 @@ paths: schema: type: string responses: - "201": + '201': content: application/json: schema: - $ref: "#/components/schemas/StreamerToken" + $ref: '#/components/schemas/StreamerToken' description: Token successfully created - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request body structure - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Room doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Generate a token that can be used by a streamer to start streaming + - management_token: [] + summary: Create a streamer token tags: - - streamer + - Streamers /room/{room_id}/track_forwardings: post: callbacks: {} + description: Forward a room's tracks into an external composition. operationId: create_track_forwarding parameters: - description: Room id @@ -1388,38 +1435,38 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/TrackForwarding" - description: Track forwardings + $ref: '#/components/schemas/TrackForwarding' required: true responses: - "201": + '201': description: Track forwardings added successfully - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Room doesn't exist security: - - authorization: [] - summary: Creates a track forwarding in a room + - management_token: [] + summary: Create a track forwarding tags: - - track_forwarding + - Track Forwardings /room/{room_id}/viewer: post: callbacks: {} + description: Issue a fresh viewer token. operationId: generate_viewer_token parameters: - description: ID of the stream. @@ -1429,46 +1476,83 @@ paths: schema: type: string responses: - "201": + '201': content: application/json: schema: - $ref: "#/components/schemas/ViewerToken" + $ref: '#/components/schemas/ViewerToken' description: Token successfully created - "400": + '400': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Invalid request body structure - "401": + '401': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Unauthorized - "404": + '404': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Room doesn't exist - "503": + '503': content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: '#/components/schemas/Error' description: Service temporarily unavailable security: - - authorization: [] - summary: Generates token that a viewer can use to watch a livestream + - management_token: [] + summary: Create a viewer token tags: - - viewer + - Viewers security: [] servers: - url: https://fishjam.io/api/v1/connect/{fishjamId} variables: fishjamId: - default: "" - description: Id of user's Fishjam instance -tags: [] + default: '' + description: Fishjam ID +tags: + - description: | + WebRTC rooms for videoconferencing. Each room hosts one or + more **peers** that exchange media through Fishjam. + + These endpoints cover the room lifecycle and per-room peer management — + adding and removing peers, refreshing peer tokens, and configuring + subscription policies between peers. For one-to-many scenarios, + see **Streams**. + name: Rooms + - description: | + WebRTC livestreams for broadcasting scenarios. + A stream holds the configuration for a one-to-many session and owns the + **streamers** that publish to it and the **Viewers** that consume it. + name: Streams + - description: | + A **streamer** represents a single publisher session for a stream and + carries an ephemeral token that Fishjam verifies before accepting + media. Use these endpoints to provision a streamer, revoke one, or issue a + fresh streamer token scoped to a livestream. + name: Streamers + - description: | + A **viewer** represents a single consumer session for a stream, identified + by an ephemeral token that Fishjam verifies on subscribe. These + endpoints provision and revoke viewers and issue viewer tokens for a + livestream room. + + The endpoints in this section are only applicable to private livestreams. + Public livestreams can be viewed anonymously, without creating a viewer resource. + name: Viewers + - description: | + Forward media tracks from a room's peers into a **composition**. + Useful for compositing room media into a single output for recording, transcoding, + or downstream broadcast. + + Only the `"all"` selector is currently supported, which forwards every + active track in the room. + name: Track Forwardings