Utviklere

Alt du kan gjøre fra «Min side» kan du også gjøre med HTTP. Du henter status på strømmen din, bytter strømnøkler, styrer restream og «straks tilbake», setter grensene for automatisk scenebytte, og starter eller stopper OBS-boksen din — fra dine egne skript, fra en bot, eller fra et kontrollpanel du bygger selv.

Base-URL: https://panel.streamsky.no/api/v1

Autentisering: Authorization: Bearer <nøkkelen din>

Format: JSON inn og JSON ut (Content-Type: application/json)

Lag en nøkkel: logg inn på streamsky.no → Min side → Utviklere

1. Kom i gang

Nøkler lager du selv under Min side → Utviklere. Du gir nøkkelen en etikett du kjenner igjen, velger tilgangsnivå, og får se selve verdien én eneste gang. Vi lagrer aldri verdien i klartekst, så mister du den, lager du bare en ny og tilbakekaller den gamle.

Nøkkelen er knyttet til kontoen din. Du ser og styrer bare dine egne strømmer og bokser — du trenger aldri oppgi hvem du er i forespørselen, for det vet vi allerede.

Første kall, for å se hva du har:

curl -s https://panel.streamsky.no/api/v1/streams \
  -H "Authorization: Bearer $STREAMSKY_KEY"

Svaret ser slik ut (med et lesenivå-tilgangsnivå, altså uten publiseringsdetaljer):

{
  "streams": [
    {
      "name": "ss-1234",
      "label": "IRL-linja mi",
      "owner": "deg@example.no",
      "plan": "active",
      "status": "active",
      "expiresAt": null,
      "live": true,
      "urls": { "srtHost": "srt.streamsky.no", "srtPort": "8890", "srtlaPort": "5050" }
    }
  ]
}

💡 Legg nøkkelen i en miljøvariabel i stedet for rett i skriptet (export STREAMSKY_KEY=…). Da havner den ikke i kommandohistorikken din, og ikke i et skript du senere deler.

2. Tilgangsnivå

En nøkkel har ett eller begge av to tilgangsnivåer. Velg alltid det laveste som holder: har boten din bare behov for å vise bitrate i en chat, skal den ikke kunne bytte nøklene dine.

NivåGir deg
read Lesing: liste strømmer og bokser, hente helse, se restream-kanaler, lese innstillingene for automatisk scenebytte og overlays. Publiseringsdetaljene dine returneres ikke — du får verten og portene, ikke lenkene som inneholder nøkkelen din.
write Alt read gir, pluss endring: bytte strømnøkler, legge til / endre / slette restream-kanaler, slå restream og «straks tilbake» av og på, endre scenebytte, styre boksen og laste inn overlays og OBS-oppsett. Bare write får se publiseringslenkene med nøkkelen din i.

Mangler nøkkelen nivået et kall krever, svarer vi 403 — vi utfører aldri halve operasjonen.

3. Feilkoder

Alle feil kommer som JSON med et error-felt du kan vise videre til deg selv eller brukerne dine. Statuskoden er den som forteller deg hva du skal gjøre.

KodeBetyrHva du gjør
400Forespørselen mangler eller har ugyldige felter.Les error — den sier hvilket felt det gjelder.
401Nøkkelen mangler, er skrevet feil, eller er tilbakekalt.Sjekk Authorization-headeren. Er nøkkelen slettet, lag en ny.
403Nøkkelen mangler tilgangsnivået — eller funksjonen krever et produkt du ikke har.Lag en nøkkel med write, eller les error: noen funksjoner krever både SRT-linje og OBS-boks.
404Finnes ikke på kontoen din.Hent lista på nytt. Vi svarer likt enten navnet ikke finnes eller tilhører noen andre — med vilje.
409Kolliderer med noe som allerede er der.Du har nådd taket for restream-kanaler eller overlays, eller boksen må startes først.
423Abonnementet er ikke aktivt akkurat nå.Gjenoppta abonnementet i portalen. Å slå av restream — én kanal eller hele funksjonen — går alltid.
429For mange kall på kort tid.Vent litt og prøv igjen. Se grensene.

4. Strømmene dine

Plassholdere i stiene skrives med kolon: :navn er navnet på strømmen slik det står i name-feltet, og :id er referansen på en restream-kanal eller en boks.

KallNivåGjør
GET /streamsreadLister alle strømmene dine.
GET /streams/:navnreadÉn strøm.
GET /streams/:navn/healthreadLive-status: om du er på lufta, oppetid, spor, antall seere, mottatte byte, bitrate, forsinkelse og pakketap.
POST /streams/:navn/rotatewriteBytter publiserings- og avspillingsnøklene. Se advarselen under.

Helse

curl -s https://panel.streamsky.no/api/v1/streams/ss-1234/health \
  -H "Authorization: Bearer $STREAMSKY_KEY"
{
  "ok": true,
  "live": true,
  "uptimeSince": "2026-08-18T09:41:12Z",
  "readers": 2,
  "bytesReceived": 184320512,
  "health": { "rttMs": 34, "mbpsIn": 5.8, "lossPct": 0.02 },
  "brb": false,
  "status": "active",
  "restreamOn": true,
  "restreamAllowed": true,
  "destinations": []
}

Vi returnerer bytesReceived rått i stedet for en ferdig utregnet bitrate: poller du med jevne mellomrom, regner du differansen selv og slipper å holde en åpen forbindelse mot oss.

Bytt strømnøkler

curl -s -X POST https://panel.streamsky.no/api/v1/streams/ss-1234/rotate \
  -H "Authorization: Bearer $STREAMSKY_KEY"

Dette bryter en pågående sending. De gamle lenkene slutter å virke med én gang, og du må lime inn den nye i OBS eller BELABOX før du kan gå live igjen. Har du en OBS-boks koblet til strømmen, oppdaterer vi den automatisk — feltet boxUpdated i svaret sier hvilken. Sender du akkurat nå, får du 423 hvis abonnementet ikke er aktivt; ellers får du de nye lenkene i svaret.

5. Restream

Restream vil si at vi tar imot sendingen din én gang og sender en kopi videre til hver kanal du har satt opp — Twitch, YouTube, Facebook, Kick, din egen RTMP-adresse, eller en ren SRT-adresse. Kopiene går ut fra datasenteret vårt, ikke fra maskinen din, så du laster opp én gang uansett hvor mange kanaler du bruker. Restream er en egen tjeneste som legges til på abonnementet — får du 403 med needsRestream: true, er det fordi den ikke er bestilt. (Automatisk scenebytte er noe annet: den krever OBS-boks, og svarer needsBox: true.)

Det er to brytere, og de gjør ikke det samme. PATCH …/restream er hovedbryteren for hele funksjonen: står den av, sendes ingenting ut, men kanalene og nøklene dine beholdes uendret. PATCH …/destinations/:id med enabled slår én enkelt kanal av og på. Feltet restreamOn i health og destinations (der heter det on) forteller hva hovedbryteren står på.

KallNivåGjør
GET /streams/:navn/destinationsreadLister kanalene dine, taket ditt, hvor mange som er aktive, om hovedbryteren står på (on), og hvilke tjenester som finnes.
PATCH /streams/:navn/restreamwriteHovedbryteren: {"on": true|false} slår hele restreamen på eller av.
POST /streams/:navn/destinationswriteLegger til en kanal.
PATCH /streams/:navn/destinations/:idwriteEndrer en kanal, eller slår den av og på.
DELETE /streams/:navn/destinations/:idwriteFjerner en kanal.
curl -s -X PATCH https://panel.streamsky.no/api/v1/streams/ss-1234/restream   -H "Authorization: Bearer $STREAMSKY_KEY"   -H "Content-Type: application/json"   -d '{"on": false}'

Å slå av går alltid — også når abonnementet ikke er aktivt. Å slå på krever aktivt abonnement (423 ellers) og at funksjonen er åpen for kontoen din (403 ellers, med begrunnelsen i error).

curl -s -X POST https://panel.streamsky.no/api/v1/streams/ss-1234/destinations \
  -H "Authorization: Bearer $STREAMSKY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"platform":"twitch","label":"Twitch","key":"live_xxxxxxxx","enabled":true}'

Bruk platform: "custom" hvis du sender til din egen adresse; da oppgir du url selv. Vi tar bare imot rtmp:// og rtmps://. Når du leser målene tilbake er adressen maskert — du ser nok til å kjenne igjen målet ditt, ikke nok til at noen kan bruke det. Sender du key som tom streng i en PATCH, betyr det «ikke endre nøkkelen».

Taket gjelder båndbredde — hver aktiv kanal er en full kopi av bitraten din — så det er de påskrudde kanalene som telles. Går du over, får du 409 med teksten som sier hvor mange du kan ha.

6. «Straks tilbake» og scenebytte

KallNivåGjør
PATCH /streams/:navn/brbwrite{"on": true} holder kanalene dine i live med en pauseskjerm når signalet ryker.
GET /streams/:navn/switcherreadLeser innstillingene for automatisk scenebytte, og om en boks er paret med strømmen.
PATCH /streams/:navn/switcherwriteSetter grensene. Justerer vi en verdi du sendte, får du det tilbake i feltet justert.
POST /streams/:navn/brb-videowriteLaster opp din egen «straks tilbake»-video (rå binær, application/octet-stream). MP4, MOV eller MKV.
DELETE /streams/:navn/brb-videowriteFjerner videoen. Da faller vi tilbake på en nøytral pauseskjerm.
POST /streamboxes/:id/brb-videowriteSamme, men mot en bestemt enhet i stedet for strømmen.
curl -s -X PATCH https://panel.streamsky.no/api/v1/streams/ss-1234/brb \
  -H "Authorization: Bearer $STREAMSKY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"on":true}'

«Straks tilbake» krever SRT-linje og Restream: linja måler signalet, og pauseskjermen sendes ut på restream-kanalene dine. Automatisk scenebytte krever en enhet med OBS — enten en OBS-boks fra oss, eller din egen maskin koblet til med Stream Sky-agenten. Mangler forutsetningen, svarer vi 403 med en forklaring i error.

6b. Fjernstyring og OBS-styring

Start og stopp sendingen og bytt scene — det samme fjernstyringen gjør fra mobilen. Inkludert i SRT-linja: du trenger verken OBS-boks eller Restream.

KallNivåGjør
GET /streams/:navn/kontrollreadAlt om enheten i ett kall: er den i kontakt, sender den, hvilke scener har den, hva er hovedscenen, og hva måler vi på inntaket. live/inntakLive gjelder inntaket (sekken/kameraet); om sendingen er ute står i sendingUt (programLive: OBS-boksens programlinje er oppe, restreamSender: antall kanaler som sender nå) — sendingen kan være ute med pauseskjerm selv om inntaket er nede.
POST /streams/:navn/kontrollwrite{"handling": "start" | "stopp" | "restart" | "oppdater" | "pause" | "fortsett"}. «stopp» går alltid — også med utløpt abonnement. «pause»/«fortsett» sier at senderen selv viser en pauseskjerm (Stream Sky-appen gjør det): da bytter ikke restream til «straks tilbake» fordi bildet står stille.
PATCH /streams/:navn/hovedscenewrite{"scene": "Live"} flytter scenen automatikken går tilbake til. Setter ikke scenen direkte — da ville auto-scenebyttet lagt seg over valget ditt.
POST /streams/:navn/obswrite{"handling": "scene" | "lag-scene", "scene": "..."}. Bytter scene nå eller lager en scene i OBS.
POST /streams/:navn/paringskodewriteEngangskode (SSKY-XXXX-XXXX-XXXX, 15 min) som en enhet bytter i sitt eget token.

Alt her er engangshandlinger med nonce, ikke tilstand. Ber du om et scenebytte mens enheten er nede, kastes det etter to minutter — det skal ikke utføres på en helt annen sending timer senere. Enheten kvitterer, og feltene i kontroll oppdateres når den har gjort jobben.

6c. Dine egne nøkler

KallNivåGjør
GET /apikeysreadLister dine egne nøkler. Selve nøkkelverdien vises aldri igjen — bare navn, scope og bruk.
POST /apikeyswriteLager en ny nøkkel. Klarteksten returneres én gang.
PATCH /apikeys/:idwriteSlår en nøkkel av eller på.
DELETE /apikeys/:idwriteTilbakekaller den. Neste kall med den svarer 401.

6c-2. Chat og chat-kommandoer

Samler Twitch-, Kick- og YouTube-chatten og lar deg og moderatorene styre sendingen fra chatten: !scene <navn>, !brb, !live, !start, !stopp og !fix.

KallNivåGjør
GET /streams/:navn/chatreadOppsettet, om chatten er tilkoblet, overlay-tokenet og de siste meldingene.
PATCH /streams/:navn/chatwrite{"twitch": "kanalnavn", "kick": "kanalnavn", "kommandoer": true, "hvem": "mods" | "eier", "tilgang": {"status": "alle", "stopp": "eier"}, "nyLenke": true}. tilgang velger hvem som får bruke én kommando (alle, mods eller eier; null = følg hvem). alle er bare lov for kommandoer som ikke endrer sendingen. nyLenke gjør den gamle overlay-lenka ugyldig.
GET /streams/:navn/chat/meldingerreadNye meldinger etter ?siden=<id>. Vi holder bare de siste 100 i minnet og lagrer ingenting.
POST /streams/:navn/chat/skrivwrite{"tekst": "Takk for raidet!", "svarPaa": "<msgId>"}. Skriver i din egen Twitch-chat som Stream Sky-boten — bare i en Twitch-kanal du har koblet til med Twitch-kontoen din (Plattformer), og bare når du har gjort boten til moderator der (/mod). Svarer 409 med "trengerKobling": true eller "trengerMod": true ellers. svarPaa (valgfri) svarer i tråd på en melding. Høyst 20 i minuttet per linje og 30 per konto.
POST /streams/:navn/chat/modererwrite{"type": "slett", "msgId": "…"}, {"type": "timeout", "brukerId": "…", "sekunder": 600} eller {"type": "ban", "brukerId": "…"}. msgId og brukerId står på Twitch-meldingene i chat/meldinger; brukeren må ha skrevet i chatten din. Samme krav om moderator som over.
GET /chat/overlay/:tokenreadDet OBS-overlayen henter: bare meldingene, uten noe om kontoen din.

6c-2b. Plattformer: tittel, kategori og seertall

Koble Twitch-, Kick- og YouTube-kontoen din til strømmen, så kan du sette tittel og kategori på alle kanalene med ett kall. Seertallene hentes hvert minutt og står også på GET /streams/:navn (seere). Tilgangsnøklene plattformene gir oss lagres kryptert og vises aldri i noe svar.

KallNivåGjør
GET /streams/:navn/plattformerreadHvilke plattformer som er tilgjengelige og koblet (kontonavn), siste tittel/kategori og seertall.
PATCH /streams/:navn/plattformer/infowrite{"tittel": "…", "kategori": "Just Chatting", "beskrivelse": "…"} til alle koblede kontoer (beskrivelsen brukes på YouTube, kategorien på Twitch og Kick). Svaret sier per plattform om det gikk, og hvilken kategori som ble valgt. Høyst én endring per 5 sekunder.
POST /streams/:navn/plattformer/:p/startwriteFørste steg i innloggingen hos plattformen (:p = kick, twitch eller youtube). Brukes av Min side.
POST /streams/:navn/plattformer/:p/koblewriteAndre steg: leverer koden plattformen ga tilbake. Brukes av Min side.
DELETE /streams/:navn/plattformer/:pwriteKobler fra og ber plattformen trekke tilgangen tilbake.

6c-3. Skjermbilde til Discord

Skriv !screenshot (eller !bilde) i chatten, trykk knappen på Min side, eller kall API-et fra din egen bot: OBS-boksen tar et bilde av scenen som er på lufta, og vi legger det rett i Discord-kanalen din via en webhook. Bildet lagres ingen steder — verken i boksen eller hos oss — og webhook-adressen vises aldri i klartekst igjen etter at du har lagret den. Krever en Cloud OBS-boks. Ett bilde per 15 sekunder per strøm.

KallNivåGjør
GET /streams/:navn/screenshotreadOppsettet: om det er slått på, og webhooken maskert.
PUT /streams/:navn/screenshotwrite{"webhook": "https://discord.com/api/webhooks/…", "paa": true}. Tom webhook fjerner den.
POST /streams/:navn/screenshotwriteTar et skjermbilde nå. Svarer 202 med en gang; bildet ligger i Discord etter et par sekunder. Discord-meldingen viser hvem som tok det: navnet på nøkkelen, eller {"av": "brukernavn"} for seeren som utløste det (f.eks. kanalpoeng i din egen bot) — vises som «brukernavn (via nøkkelnavn)». Bare bokstaver, tall og _ (2–25 tegn).
GET /streams/:navn/eksternt-relereadHent fra eksternt relé: paa, adresse (bare vert:port — nøkkelen vises aldri), henter og feil.
PUT /streams/:navn/eksternt-relewrite{"paa": true, "url": "srt://relé.eksempel.no:4001?streamid=…"}. Vi henter bildet fra reléet inn på linja (bare offentlige srt://-adresser). {"url": null} fjerner adressen. Mens det er på, tar linja ikke imot sending direkte.
GET /streams/:navn/kanalpoengreadSkjermbilde med kanalpoeng (Twitch): paa, tittel, pris, tilgang (om Twitch-tilkoblingen har tilgang til kanalpoeng), abonnement og feil.
PUT /streams/:navn/kanalpoengwrite{"paa": true, "pris": 500, "tittel": "📸 Skjermbilde til Discord"}. Vi lager belønningen i Twitch-kanalen din (krever affiliate/partner, Cloud OBS-boks og Discord-webhook). Svarer 409 med "trengerTilgang": true når Twitch-tilkoblingen mangler tilgang til kanalpoeng — koble til på nytt fra Min side. Når en seer løser inn belønningen, havner bildet i Discord med seerens navn, boten sier fra i chatten, og blir bildet ikke tatt, får seeren poengene tilbake. "paa": false skjuler belønningen.

6c-4. Sendingsrapporter og live-varsel

Etter hver sending lager vi en rapport: bitrate, ping og jitter, pakker som ble tapt, sendt på nytt eller kom for sent, brudd og tid uten signal, hvilke mobilnett sekken brukte (operatør, ikke IP-adresse), og råd i klartekst. Mens du sender, sier vi fra ved mye pakketap i over ett minutt, når nesten all trafikken går over én lenke, og når signalet faller ofte. Rapport og varsel går til en EGEN Discord-webhook (egen kanal) som du setter selv, aldri til skjermbilde-webhooken. Uten den sendes ingenting til Discord, og du ser alt via API-et og på Min side. En sending er ferdig når signalet har vært borte i 10 minutter. Vi tar vare på de siste 30 sendingene i 90 dager.

KallNivåGjør
GET /streams/:navn/rapporterreaddiscord og varsel (av/på), harWebhook og webhook (maskert), rapporter (nyeste først: start, slutt, liveSek, brudd, kbps, rtt, pakker, nett, graf, varsler, vurdering) og pagaar mens du sender.
PATCH /streams/:navn/rapporterwrite{"discord": false} slår av rapporten til Discord, {"varsel": false} live-varselet. {"webhook": "https://discord.com/api/webhooks/…"} setter rapport-webhooken (må være en annen enn skjermbildenes; vi legger en bekreftelse i kanalen), {"webhook": null} fjerner den. Rapportene lagres uansett.

6d. Tilbud på e-post

Har du brukt opp restream-kanalene eller linjene dine, sender vi deg høyst én e-post i måneden per grense om hva neste nivå koster. Du bestemmer selv om du vil ha den.

KallNivåGjør
GET /tilbudread{"paa": true} når du får slike e-poster.
PATCH /tilbudwrite{"paa": false} slår dem av, true på igjen. Fakturaer og varsler om abonnementet ditt får du uansett.
POST /tilbud/avwrite{"token": "..."} fra lenken i e-posten. Tokenet er beviset, så kallet virker uten innlogging via /tilbud/av.

7. OBS-boksene dine

KallNivåGjør
GET /streamboxesreadLister enhetene dine med status, hvilken strøm de er paret med, og når abonnementet utløper. type er obsboks (en boks vi drifter) eller egen (din egen maskin); motor er obs eller ffmpeg.
DELETE /streamboxes/:id/paringwriteKobler fra en enhet du selv har paret. Virker kun på type: "egen" — en boks vi drifter sies opp under Abonnement. Tokenet på enheten dør umiddelbart.
POST /streamboxes/:id/powerwrite{"action": "start" \| "stop" \| "reboot"}
POST /streamboxes/:id/konsollwriteGir en engangsbillett (60 s) til OBS-skrivebordet i nettleseren: {"konsollToken", "vncticket"}. Åpne websocket mot /konsoll/<konsollToken> og bruk vncticket som VNC-passord. Kun bokser vi drifter, og bare når boksen er på.
POST /streamboxes/:id/liminnwriteSkriver tekst inn der markøren står i boksen, som tastetrykk: {"tekst": "..."} (maks 4000 tegn). Dette er «Lim inn»-knappen i skrivebordet. Kun bokser vi drifter, og bare når boksen er på.
GET /streamboxes/:id/overlayreadLister overlay-kildene som ligger i OBS akkurat nå.
POST /streamboxes/:id/overlaywriteLegger inn en overlay-lenke som nettleserkilde: {"url": "...", "navn": "Chat"}
DELETE /streamboxes/:id/overlaywriteFjerner et overlay: {"navn": "Chat"}
POST /streamboxes/:id/mediawriteLegger en video, et bilde eller en lydfil i mappen Mediefiler i boksen (rå binær, application/octet-stream, maks 200 MB). Filnavnet sendes som ?navn=. Filtypen leses fra innholdet: MP4, MOV, MKV, WebM, PNG, JPG, GIF, WebP, MP3, WAV eller OGG. En fil med samme navn overskrives aldri, den nye får « (2)». Kun bokser vi drifter, og bare når boksen er på.
GET /streamboxes/:id/mediareadLister filene i Mediefiler: {"filer": [{"navn", "bytes"}]}
POST /streamboxes/:id/obs-importwriteLaster inn din egen scenesamling: {"content": "<innholdet i JSON-fila>"}

Klipp, opptak og lagring (Pro og Studio)

Lagringen er felles for alle strømmene dine: 2 GB til klipp er inkludert, og opptak av hele sendingen krever «Ekstra lagring» (100 GB per kjøp). Er lagringen full, stoppes nye klipp og opptak (507); det som ligger, beholdes til du sletter det.

KallNivåGjør
POST /streams/:navn/klippwriteLager et klipp av de siste sekundene mens du er live: {"sekunder": 30} (5–30). Svarer med fila: {"fil": {"id", "bytes", "sekunder"}}
PATCH /streams/:navn/opptakwriteOpptak av hele sendingen på eller av: {"on": true}. Krever kjøpt lagring.
GET /lagringreadKvote, forbruk og filene dine: {"kvoteBytes", "brukBytes", "full", "filer": [{"id", "type", "strom", "bytes", "tid"}]}
GET /lagring/fil?id=readLaster ned et klipp eller opptak (MP4).
DELETE /lagring/fil?id=writeSletter et klipp eller opptak. Et opptak som pågår, må slås av først (409).
curl -s -X POST https://panel.streamsky.no/api/v1/streamboxes/$BOKS/power \
  -H "Authorization: Bearer $STREAMSKY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action":"start"}'

Boksen må være startet for å ta imot overlays eller et OBS-oppsett — ellers svarer vi 409. Overlay-lenken må være https:// og peke ut på internett; vi tar ikke imot adresser som peker innover i nettverket.

Til obs-import bruker du fila fra OBS → Scenesamling → Eksporter (ikke Profil → Eksporter — det er den forvekslingen folk gjør). Vi rører aldri profilen din, så SRT-lenka i boksen står som den står. Maks 1 MB.

8. Publiseringsadressene

Selve videoen sendes ikke gjennom API-et. Den går direkte til:

BrukAdresse
SRTLA-bonding (flere mobilnett samtidig)srt.streamsky.no:5050
Vanlig SRT — publisering og avspillingsrt.streamsky.no:8890
RTMP — publisering (for utstyr uten SRT)srt.streamsky.no:1935

De ferdige lenkene henter du med en write-nøkkel — de kommer i urls på strømmen din, som srtla, srtPublish og srtPlay. Formen er slik, der streamid bærer navnet på strømmen og publiseringsdetaljen din:

srt://srt.streamsky.no:8890?streamid=publish:<strøm>:<bruker>:<hemmelighet>

RTMP er delt i to felt, fordi det er slik OBS og de fleste encodere spør om det: rtmpServer hører hjemme i «Server», og rtmpKey i «Streamnøkkel». Kreds ligger i nøkkelen, ikke i serveradressen:

Server:       rtmp://srt.streamsky.no:1935/
Streamnøkkel: <strøm>?user=<bruker>&pass=<hemmelighet>

SRT gir lavere forsinkelse og tåler ustabilt nett langt bedre. Bruk RTMP når utstyret ditt ikke støtter SRT — ikke som førstevalg.

⚠️ Disse lenkene må aldri deles

Publiseringslenka inneholder din egen hemmelighet. Den som har den, kan sende video ut på kanalene dine som om det var deg. Avspillingslenka lar hvem som helst se sendingen din.

Derfor: aldri i et skjermbilde, aldri på strøm, aldri i en offentlig chat, aldri i et kodelager. Dette er den vanligste måten en IRL-streamer mister kontrollen på — lenka blir stående synlig i OBS-vinduet mens sendingen går.

Har det først skjedd: kjør POST /streams/:navn/rotate med én gang, eller trykk Bytt nøkler i portalen. De gamle lenkene dør i samme sekund.

9. Bygg din egen sendeboks

Vil du bygge din egen IRL-boks — en Raspberry Pi, en Radxa, eller noe helt annet — finnes det et eget enhets-API for det. Boksen din blir da en enhet vi kjenner: du ser den i portalen, og du kan starte, stoppe og oppdatere sendingen fra fjernstyringen på mobilen, akkurat som med våre egne bokser.

Vil du bare ha det til å virke? Da trenger du ikke dette kapittelet. Stream Sky-agenten er ferdig og kjører på Windows, Linux og macOS — den styrer OBS over obs-websocket, eller en ffmpeg-/belacoder-kommando du setter selv. Fjernstyring er inkludert i SRT-linja: du trenger verken OBS-boks eller Restream.

Kapittelet under er for deg som vil bygge din egen klient mot enhets-API-et.

Base-URL: https://panel.streamsky.no

Autentisering: Authorization: Bearer <enhetstoken>

API-versjon: følger med i hvert svar som apiVersjon (nå 1)

Boksen ringer oss — ikke omvendt

Enheten din poller oss og henter ønsket tilstand. Vi kobler aldri inn til den. Det er med vilje: en IRL-boks står på mobilnett bak CGNAT og har ingen adresse vi kunne nådd. Så lenge boksen din kommer ut på HTTPS, virker fjernstyringen — uten tunnel, uten åpne porter, uten fast IP.

Merk at vi sender tilstand, ikke kommandoer i kø. Boksen sammenligner det vi ønsker med det den faktisk gjør, og retter opp. Har den vært borte en time, gjør den bare det som trengs nå — den spiller ikke av gamle kommandoer.

Steg 1: par enheten

Kunden lager en engangskode i portalen, eller via POST /api/v1/streams/:navn/paringskode med en write-nøkkel. Koden ser ut som SSKY-A3F9-K2M7-Q4XZ og varer i 15 minutter. Boksen bytter den i sitt eget, langlevde token:

curl -X POST https://panel.streamsky.no/api/enhet/par \
  -H "Content-Type: application/json" \
  -d "{\"kode\":\"SSKY-A3F9-K2M7-Q4XZ\",\"modell\":\"Raspberry Pi 4 Model B\",\"versjon\":\"1.0.0\"}"
{
  "ok": true, "apiVersjon": 1,
  "token": "agt_…",
  "stream": "minstrom",
  "srtla": { "host": "srt.streamsky.no", "port": 5050 },
  "srt":   { "host": "srt.streamsky.no", "port": 8890 }
}

Lagre tokenet trygt — det er enhetens legitimasjon fra nå av. Koden virker én gang. Parer kunden på nytt, mister den forrige enheten tilgangen — det er slik en mistet eller solgt boks kobles fra.

Steg 2: poll tilstanden

Hvert 2.–5. sekund. Her ligger både målingene våre og det kunden har trykket på i fjernstyringen:

curl -H "Authorization: Bearer agt_…" https://panel.streamsky.no/api/agent/state
{
  "ok": true, "apiVersjon": 1, "paired": true, "stream": "minstrom",
  "live": true, "kbps": 4200, "rttMs": 38,
  "kontroll": { "sending": "paa", "hovedscene": null, "handling": null },
  "publisering": {
    "srtla": "srtla://srt.streamsky.no:5050",
    "srt": "srt://srt.streamsky.no:8890",
    "streamid": "publish:minstrom:<bruker>:<hemmelighet>"
  }
}
FeltBetydning
kontroll.sending"paa", "av" eller null. Start eller stopp sendingen din for å matche. null = kunden har ikke bestemt noe.
kontroll.handlingEngangshandling, f.eks. {"type":"restart","nonce":"…","ts":"…"}. Utfør én gang per nonce, og kvitter i steg 3. Er den mer enn to minutter gammel, får du den ikke — vi kaster den.
publisering.streamidLegg denne på SRT- eller SRTLA-adressen. Les den på hver poll — bytter kunden nøkler, endrer den seg, og en boks som har bakt den inn blir stum.
live, kbps, rttMsHva vi ser fra vår side. Nyttig til å vise kunden om signalet faktisk kommer fram.
enabled, configGjelder automatisk scenebytte i OBS. Bygger du en ren IRL-boks, kan du se bort fra dem.

Steg 3: meld tilbake

Uten dette står boksen din som «ingen kontakt» i portalen. Send den når noe endrer seg, og ellers hvert 20.–30. sekund:

POST https://panel.streamsky.no/api/agent/rapport
Authorization: Bearer agt_…

{
  "sender": true,
  "kvittering": "<nonce fra kontroll.handling, hvis du nettopp utførte en>",
  "enhet": {
    "versjon": "1.0.0", "bitrateKbps": 4200, "tempC": 61.5, "batteriProsent": 82,
    "lenker": [
      { "navn": "modem0", "oppe": true, "kbps": 2100 },
      { "navn": "modem1", "oppe": true, "kbps": 2100 }
    ]
  }
}

lenker er bonding-linjene dine — de vises i fjernstyringen, så kunden ser på mobilen hvilke modem som faktisk bærer. Maks 8. Alle tall klemmes til fornuftige intervaller og all tekst klippes; sender du noe rart, får du fortsatt 200, men vi lagrer bare det som gir mening.

Steg 4: meld deg av

Når enheten skal tas ut av bruk. Da forsvinner den fra portalen i stedet for å bli stående som offline for alltid:

POST https://panel.streamsky.no/api/agent/koble-fra
Authorization: Bearer agt_…

Versjoner og kompatibilitet

Hvert svar bærer apiVersjon. Vi legger gjerne til nye felt — det regnes ikke som en brytende endring, så boksen din må tåle felt den ikke kjenner. Endrer vi noe brytende, bumper vi tallet og sier fra i god tid. Sjekk gjerne at apiVersjon er den du bygde mot, og logg en advarsel hvis ikke.

Grenser

Tokenet ligger på et minnekort

Enhetstokenet gir rett til å sende på kundens strøm og lese publiseringsdetaljene. Det bor på en maskin som kan mistes, stjæles eller selges videre. Derfor: lim aldri inn en vanlig API-nøkkel i en boks — den gir tilgang til hele kontoen. Bruk parekoden, som er scopet til én strøm.

Mistes boksen: lag en ny parekode og par en annen enhet. Det gamle tokenet dør i samme sekund. Eller trykk Bytt nøkler på strømmen.

To ferdige utgangspunkt

1. Stream Sky-agenten — den vi selv anbefaler, og den kundene våre bruker. Ferdig, ikke et skjelett: to motorer (OBS over obs-websocket, eller din egen koder-kommando), automatisk innfylling av SRT-lenka i OBS, telemetri, backoff og oppstart som tjeneste. Windows, Linux og macOS. Kun standardbiblioteket. Full veiledning: streamsky.no/egen-maskin.

python3 streamsky-agent.py par SSKY-XXXX-XXXX-XXXX
python3 streamsky-agent.py oppsett --motor ffmpeg --kommando "ffmpeg ... -f mpegts {url}"
python3 streamsky-agent.py kjor

2. Referanseagenten — et kortere skjelett som viser hele samtalen uten annet støy: parering, polling, start og stopp, kvittering og rapportering. Det eneste du fyller ut selv er sender_kommando(). Bruk denne hvis du vil lese deg til protokollen før du skriver din egen klient.

sudo python3 streamsky-irl-agent.py par SSKY-XXXX-XXXX-XXXX
sudo python3 streamsky-irl-agent.py kjor

Hva bygger du selv?

Vi leverer plattformsiden. Selve sendingen er din: du trenger noe som koder video og noe som snakker SRT eller SRTLA mot oss. srtla og belacoder er åpen kildekode (GPL-3.0) og gjør begge deler godt — belacoder justerer bitraten løpende etter hvordan hver linje har det, som er det som får IRL til å fungere på ustabilt mobilnett.

Om maskinvare: velg et kort med maskinvarekoder for H.264. Raspberry Pi 5 og Jetson Orin Nano har ingen — der går all koding på CPU. Pi 4 har 1080p30. Rockchip RK3588 (Radxa ROCK 5B/5B+, Orange Pi 5) er merkbart sterkere, og 5B/5B+ har i tillegg HDMI-inngang, så kameraet går rett i kortet uten opptaksdongle.

10. Grenser og god skikk

Trenger du hjelp?

Står du fast, eller mangler du et endepunkt for noe du prøver å få til — åpne en supportsak, så svarer vi. Du kan også bruke kontaktskjemaet.

Del aldri nøkkelen din eller en publiseringslenke i en supportsak. Vi trenger dem ikke — de første tegnene i nøkkelen holder for at vi finner den igjen.

← Tilbake til Stream Sky