Ga naar inhoud

HTTP-API

Request- en response-bodies zijn JSON. Endpoints die een body accepteren, verwachten Content-Type: application/json. De basis-URL op deze hele pagina is http://headend.local:8080; vervang die door het adres en de poort die u met --port hebt ingesteld.

Zender-ID’s in paden zijn de numerieke id uit het configuratiebestand. Ze worden na een verwijdering hergebruikt, dus een script dat een ID over een herconfiguratie heen onthoudt, kan op de verkeerde zender inwerken.

MethodePadDoel
GET/loginDe loginpagina zelf. Voor een script onbruikbaar; hij staat hier zodat een onverwacht HTML-antwoord op een API-aanroep herkenbaar is als een doorverwijzing daarheen.
POST/api/loginWisselt gebruikersnaam en wachtwoord in voor een sessiecookie. De inloggegevens zijn de waarden van CASTMUX_WEB_USERNAME en CASTMUX_WEB_PASSWORD.
POST/api/logoutMaakt de huidige sessie ongeldig.

Sla met curl de cookie bij het inloggen op in een cookie-jar en stuur die jar daarna mee:

Terminal window
# log in, keeping the session cookie
curl -s -c cookies.txt \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"correct-horse-battery"}' \
http://headend.local:8080/api/login
# now call an authenticated endpoint with the same jar
curl -s -b cookies.txt \
http://headend.local:8080/api/viewers
MethodePadDoel
GET/api/versionVersie, commit en buildtijd van de draaiende binary. Bewust zonder authenticatie, zodat een monitoringsysteem op elk apparaat in een installatiebestand kan nagaan wat er is uitgerold, zonder inloggegevens te krijgen waarmee het er iets aan kan veranderen.
Terminal window
curl -s http://headend.local:8080/api/version
# {"version":"3.1.0","commit":"9f2c41a","built":"2026-04-08T09:12:44Z"}
MethodePadDoel
POST/api/internal/streams/{id}/restartHerstart één zender, voor een supervisor die op het apparaat zelf draait. De optionele ?reason= wordt naar de log geschreven, zodat een herstart daar vermeldt waarom hij plaatsvond. Het antwoord bevat de naam van de zender en of er een draaiende engine is herstart. De meegeleverde watchdog gebruikt dit om één vastgelopen zender te herstellen zonder de hele container te herstarten en daarmee alle gezonde zenders van de lucht te halen.

Voor dit endpoint is geen login nodig. In plaats daarvan weigert het elke verbinding die niet van een loopbackadres komt (127.0.0.1 of ::1), met 403 en een logregel die de aanroeper noemt. Zo hoeft het beheerderswachtwoord niet in een bestand op schijf te staan waar de watchdog het kan lezen. Om het endpoint te bereiken, is al een shell op het apparaat nodig.

MethodePadDoel
Levenscyclus
POST/api/channelsMaakt een zender aan. De body heeft dezelfde vorm als één item onder streams in het configuratiebestand. Het toegekende ID wordt teruggegeven.
PUT/api/channels/{id}Vervangt de instellingen van een bestaande zender. Een draaiende zender wordt herstart als de wijziging invloed heeft op hoe hij draait.
DELETE/api/channels/{id}Verwijdert een zender. Stopt hem eerst. Het ID komt beschikbaar voor hergebruik.
POST/api/channels/{id}/restartHerstart één zender zonder de andere aan te raken. Het eerste wat u probeert wanneer één zender zich misdraagt en de rest gezond is.
Status
POST/api/streams/{id}/activeSchakelt een zender in of uit. Een uitgeschakelde zender behoudt zijn configuratie maar wordt nooit gestart.
POST/api/streams/{id}/force-always-onZet de always-on-override aan of uit. Aan: de zender draait continu; uit: hij draait wanneer kijkerdetectie ziet dat iemand kijkt.
Inspectie
GET/api/channelsEen korte lijst van alle zenders: id, name, bestemmings-address en -port, en epg_id. Genoeg om te zien welke zenders er zijn. Het geeft niet de volledige instellingen van een zender terug — bron, engine, profiel, bewaking — dus een script dat die nodig heeft, leest het configuratiebestand.
GET/api/channels/{id}/ts-qualityKwaliteit van de transportstream voor één zender: de laatste meting, lopende totalen van continuïteits-, transport- en PCR-fouten, en de geschiedenis van de laatste 30 minuten met intervallen van 5 seconden. Vermeldt ook of de monitoring voor de zender draait en hoe de PCR-timing wordt gemeten. Zie Kwaliteit van de transportstream.
GET/api/channels/{id}/logsRecente engine-uitvoer voor één zender. Hier verschijnt een bronfout in de bewoordingen die de originserver zelf gebruikte, in plaats van als algemene storing.
GET/api/channels/resolutionsDe resolutie die momenteel voor elke zender is gekozen, en of dat een exacte match is met het gevraagde profiel of de dichtstbijzijnde trede die de originserver aanbood. Geleverd uit de cache; wacht niet op het ophalen bij originservers.
Voorvertoning
POST/api/channels/{id}/previewStart een in de browser te bekijken voorvertoning van een zender.
POST/api/channels/{id}/preview/stopStopt de voorvertoning. Voorvertoningen kosten echte CPU, dus stop ze expliciet in plaats van erop te vertrouwen dat het sluiten van de pagina volstaat.
Terminal window
# create a channel
curl -s -b cookies.txt -X POST \
-H 'Content-Type: application/json' \
-d '{
"name": "Example One",
"description": "Main lounge line-up",
"active": true,
"force_always_on": false,
"engine": "tsduck",
"resolution_profile": "hd",
"source": {"type": "hls", "url": "https://origin.example.net/one/master.m3u8"},
"destination": {"address": "239.10.0.1", "port": 5000}
}' \
http://headend.local:8080/api/channels
MethodePadDoel
Bronnen
POST/api/epg/sourcesVoegt een XMLTV-bron toe. Body: {"name": "...", "url": "..."}. Geeft de id van de nieuwe bron terug. De zenderlijst van de bron wordt op de achtergrond opgehaald.
PUT/api/epg/sources/{id}Hernoemt een bron of laat die naar een nieuwe URL wijzen, met dezelfde body. Opgeslagen data blijft behouden en wordt bij de volgende synchronisatie vervangen.
DELETE/api/epg/sources/{id}Verwijdert een bron en de opgeslagen gidsdata. Zenders die eraan gekoppeld zijn, behouden hun epg_id.
POST/api/epg/sources/{id}/syncHaalt de bron nu op en slaat programma's op voor gekoppelde zenders. Synchroon: het antwoord meldt het werkelijke resultaat, en bij een grote gids kan dat minuten duren.
Koppeling en data
GET/api/epg/channelsElke bron, op ID, met naam, URL, laatste ophaalmoment en status, en de gids-ID's die de bron aanbiedt.
POST/api/epg/mapKoppelt een zender aan een gids-ID. Body: {"stream_id": 3, "tvg_id": "rtl.de"}. Een lege tvg_id wist de koppeling. Opgeslagen in de epg_id van de zender.
GET/api/epg/nowWat er nu is en wat er hierna komt, voor alle gekoppelde zenders in één aanroep. Een gekoppelde zender waarop niets wordt uitgezonden, is aanwezig met een lege now; dat is iets anders dan een niet-gekoppelde zender, die ontbreekt.
MethodePadDoel
GET/api/licenceDe licentiestatus van het apparaat: state met een leesbare message en detail, can_stream, de device_code waar support om zal vragen, en een supportcontact in contact. Heeft de laatste synchronisatie zenders geweigerd die de licentieserver stuurde, dan staan de redenen er ook bij. Het licentietoken zelf wordt nooit teruggegeven.
POST/api/licence/retryDoet nu een check-in bij de licentieserver in plaats van te wachten op de volgende geplande poging. Gebruik dit nadat u hebt verholpen wat de licentie blokkeerde, zoals een verlopen abonnement of een firewallregel. Het antwoordt direct; poll /api/licence voor de uitkomst.
MethodePadDoel
GET/api/viewersKijkerstatus voor alle zenders in één aanroep. Gebruik dit om te pollen in plaats van over zenders te lussen, wat het aantal verzoeken vermenigvuldigt met de omvang van de zenderlijst.
GET/api/streams/{id}/viewersDetails voor één zender: de lijst met clientadressen die op dit moment zijn aangemeld, het aantal, een vlag die aangeeft of er een IGMP-querier op het segment aanwezig is, en een vlag die aangeeft of de detectie gedegradeerd is.
MethodePadDoel
Meting
GET/api/metricsSysteemmeetwaarden en meetwaarden per zender in één document: CPU, geheugen, uptime, en per zender status en doorvoer. Aan de serverkant ongeveer twee seconden gecachet, dus sneller pollen levert dezelfde getallen op en kost alleen verwerking van verzoeken.
GET/api/network-statsTellers op interfaceniveau en bereikbaarheidsresultaten voor de hosts in ping_hosts.
GET/api/udp-bitrateGemeten bitrate die de netwerkpoort daadwerkelijk verlaat, per zender. Dit is het engine-onafhankelijke levenssignaal: het geeft weer wat er op de kabel staat, niet wat een decoder beweert te produceren.
Beheer
PUT/api/settingsWijzigt global-instellingen. Stuur alleen de sleutels die u wilt wijzigen; alles wat u weglaat, behoudt zijn huidige waarde. Alleen PUT — er is geen GET-variant, dus lees de huidige instellingen uit het configuratiebestand.
GET/api/network-interfacesAlle IPv4-adressen op het apparaat, om udp_device te kiezen: adres, interface, of de interface actief is, het subnet, en of het adres via DHCP is toegekend. Loopback- en link-local-adressen worden weggelaten, omdat geen van beide ooit de juiste keuze is. Inactieve interfaces worden getoond, niet verborgen, omdat een inactieve interface precies is wat u moet kunnen zien.
POST/api/restart-allHerstart alle zenders. Het starten wordt gespreid met startup_stagger_seconds, zodat niet de hele zenderlijst tegelijk terugkomt en samen mislukt.
POST/api/restart-appHerstart de Castmux-applicatie. Die antwoordt eerst, sluit dan netjes af, en het herstartbeleid van de container start hem binnen enkele seconden opnieuw. Alle zenders zijn kort uit de lucht. Anders dan /api/reboot heeft dit niets op de host nodig, dus het werkt in elke containeruitrol.
POST/api/rebootHerstart het apparaat. Alle zenders zijn zolang uit de lucht; dit is geen oplossing voor een zenderstoring.
MethodePadDoel
Multiplexen
GET/api/dvb/muxesToont de geconfigureerde multiplexen met hun RF-parameters en huidige status. Anders dan zenders hebben multiplexen wel een lees-endpoint.
POST/api/dvb/muxesMaakt een multiplex aan.
PUT/api/dvb/muxes/{id}Werkt RF-parameters of signaleringsidentificaties bij. Het wijzigen van frequentie, modulatie of symbol rate onderbreekt de draaggolf.
DELETE/api/dvb/muxes/{id}Verwijdert een multiplex. De zenders die erop zaten, worden niet verwijderd.
POST/api/dvb/muxes/{id}/activeStart of stop de uitzending van de draaggolf.
Inhoud en bediening
POST/api/dvb/muxes/{id}/channelsWijst de doorgegeven zenders en hun volgorde toe. De volgorde bepaalt de service-ID's, dus herschikken geeft services een nieuwe identiteit en kan televisies dwingen opnieuw te zoeken. Voeg waar mogelijk achteraan toe in plaats van tussenin.
GET/api/dvb/muxes/{id}/logsUitvoer van de multiplexer en de modulator voor deze draaggolf.
POST/api/dvb/muxes/{id}/hot-swapWisselt de inhoud van een draaiende multiplex zonder de draaggolf te laten wegvallen, zodat toestellen afgestemd blijven in plaats van tijdens de wijziging „geen signaal” te melden.
POST/api/dvb/muxes/{id}/suspendZet de multiplex tijdelijk stil, voor onderhoud aan de modulator of het kabelnetwerk, zonder de configuratie te verwijderen.
MethodePadDoel
POST/api/hdmi/activeSchakelt de HDMI-uitvoer in of uit.
POST/api/hdmi/configStelt in welke zender op de HDMI-poort wordt getoond en hoe die wordt weergegeven.
GET/api/hdmi/outputsWat dit apparaat kan aansturen: vos (videodrivers), drm_devices (displayapparaten) en audio_devices (elk met een value en label, zoals de speler ze zelf opsomt), plus de huidige selectie in current. De waarden zijn precies wat /api/hdmi/config accepteert.
GET/api/hdmi/metricsStatus en doorvoer van de HDMI-uitvoer.
GET/api/hdmi/logsUitvoer van het HDMI-weergaveproces.

Een uitgewerkt voorbeeld: inloggen, drie zenders aanmaken, een multiplex aanmaken en de zenders daaraan toewijzen in de volgorde waarin ze moeten verschijnen. Dit is de volledige ingebruiknamereeks voor een kleine locatie, en het loont om die te scripten, want drie zenders in een formulier typen is waar verwisselde multicastadressen vandaan komen.

#!/usr/bin/env bash
set -euo pipefail
BASE="http://headend.local:8080"
JAR="$(mktemp)"
# 1. log in ------------------------------------------------------------
curl -sf -c "$JAR" -H 'Content-Type: application/json' \
-d "{\"username\":\"$CASTMUX_USER\",\"password\":\"$CASTMUX_PASS\"}" \
"$BASE/api/login" > /dev/null
# 2. create the channels ------------------------------------------------
# name | multicast group | source playlist
CHANNELS=(
"Example One|239.10.0.1|https://origin.example.net/one/master.m3u8"
"Example Two|239.10.0.2|https://origin.example.net/two/master.m3u8"
"Example News|239.10.0.3|https://origin.example.net/news/master.m3u8"
)
IDS=()
for row in "${CHANNELS[@]}"; do
IFS='|' read -r NAME GROUP URL <<< "$row"
ID=$(curl -sf -b "$JAR" -X POST -H 'Content-Type: application/json' \
-d "{
\"name\": \"$NAME\",
\"active\": true,
\"force_always_on\": true,
\"engine\": \"tsduck\",
\"resolution_profile\": \"hd\",
\"source\": {\"type\": \"hls\", \"url\": \"$URL\"},
\"destination\": {\"address\": \"$GROUP\", \"port\": 5000}
}" \
"$BASE/api/channels" | sed -n 's/.*"id":\([0-9]*\).*/\1/p')
echo "created $NAME as id $ID"
IDS+=("$ID")
# respect the stagger: three HLS origins opened at once is the
# failure this setting exists to prevent
sleep 3
done
# 3. create the multiplex ------------------------------------------------
MUX=$(curl -sf -b "$JAR" -X POST -H 'Content-Type: application/json' \
-d '{
"name": "Mux A",
"device": 0,
"frequency": 474000000,
"qam": 256,
"symbol_rate": 6900,
"network_id": 1,
"ts_id": 1,
"network_name": "Seaview Court",
"active": true
}' \
"$BASE/api/dvb/muxes" | sed -n 's/.*"id":\([0-9]*\).*/\1/p')
# 4. assign the channels, in line-up order -------------------------------
# this order fixes the service IDs; changing it later means a re-tune
LIST=$(IFS=,; echo "${IDS[*]}")
curl -sf -b "$JAR" -X POST -H 'Content-Type: application/json' \
-d "{\"channel_ids\": [$LIST]}" \
"$BASE/api/dvb/muxes/$MUX/channels"
rm -f "$JAR"

Twee details in dat script zijn niet toevallig. De sleep 3 tussen het aanmaken komt overeen met startup_stagger_seconds: drie HLS-originservers tegelijk openen is precies de situatie die het gespreid starten moet voorkomen, en een inrichtingsscript is de makkelijkste manier om die na te bootsen. En de zenders worden in één aanroep toegewezen in plaats van drie, omdat de toewijzingsvolgorde de service-ID’s bepaalt — door eerst de lijst op te bouwen en die één keer te posten, wordt de zenderlijst bij de eerste poging genummerd zoals bedoeld.

  • Fouten zijn JSON. Een mislukt verzoek geeft een passende statuscode terug en een JSON-body die het probleem beschrijft. Een HTML-antwoord betekent dat het verzoek niet geauthenticeerd was en naar de loginpagina is doorverwezen — controleer de cookie-jar voordat u de body gaat debuggen.
  • PUT /api/settings voegt samen. Stuur alleen de instellingen die u wilt wijzigen; alles wat u weglaat, behoudt zijn huidige waarde. Een wijziging van de engineparameters, udp_device, default_engine, enable_dummy_listeners, overwrite_srt_latency of overwrite_pkt_size herstart alle actieve zenders, omdat die instellingen bepalen hoe elke engine draait. Andere instellingen worden zonder herstart toegepast.
  • Rate limiting is geen vervanging voor gecachete data. /api/metrics wordt ongeveer twee seconden gecachet; een dashboard dat elke 250 ms pollt, krijgt acht identieke antwoorden en geen extra informatie.

Een volledige lees-API, export en import van de volledige configuratie, en API-tokens in plaats van sessiecookies zijn allemaal gepland. Ze staan met de rest op de roadmappagina.