Aller au contenu

API HTTP

Les corps de requête et de réponse sont en JSON. Les points de terminaison qui acceptent un corps attendent Content-Type: application/json. L’URL de base utilisée sur toute cette page est http://headend.local:8080 ; remplacez-la par l’adresse et le port configurés avec --port.

Les identifiants de chaîne dans les chemins sont l’id numérique du fichier de configuration. Ils sont réutilisés après une suppression : un script qui garde un identifiant en cache d’une reconfiguration à l’autre peut agir sur la mauvaise chaîne.

MéthodeCheminRôle
GET/loginLa page de connexion elle-même. Sans utilité pour un script ; elle figure ici pour qu'une réponse HTML inattendue à un appel d'API soit reconnue comme une redirection vers elle.
POST/api/loginÉchange le nom d'utilisateur et le mot de passe contre un cookie de session. Les identifiants sont les valeurs de CASTMUX_WEB_USERNAME et CASTMUX_WEB_PASSWORD.
POST/api/logoutInvalide la session courante.

Avec curl, stockez le cookie dans un fichier (cookie jar) à la connexion, puis présentez ce fichier ensuite :

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
MéthodeCheminRôle
GET/api/versionVersion, commit et date de compilation du binaire en cours d'exécution. Volontairement sans authentification, pour qu'un système de supervision puisse vérifier ce qui est déployé sur chaque appareil d'un parc sans recevoir d'identifiants permettant d'y modifier quoi que ce soit.
Terminal window
curl -s http://headend.local:8080/api/version
# {"version":"3.1.0","commit":"9f2c41a","built":"2026-04-08T09:12:44Z"}
MéthodeCheminRôle
POST/api/internal/streams/{id}/restartRedémarre une chaîne, pour un superviseur tournant sur l'appareil lui-même. Le paramètre facultatif ?reason= est écrit dans le journal, afin qu'un redémarrage y indique sa cause. La réponse contient le nom de la chaîne et indique si un moteur en cours d'exécution a été redémarré. Le watchdog fourni s'en sert pour rétablir une chaîne bloquée sans redémarrer tout le conteneur et couper du même coup toutes les chaînes saines.

Ce point de terminaison ne nécessite pas de connexion. En revanche, il refuse toute connexion qui ne provient pas d’une adresse de boucle locale (127.0.0.1 ou ::1), avec un 403 et une ligne de journal nommant l’appelant. Cela évite de stocker le mot de passe administrateur dans un fichier sur disque pour que le watchdog le lise. Atteindre ce point de terminaison exige déjà un shell sur l’appareil.

MéthodeCheminRôle
Cycle de vie
POST/api/channelsCrée une chaîne. Le corps a la même forme qu'une entrée sous streams dans le fichier de configuration. L'identifiant attribué est renvoyé.
PUT/api/channels/{id}Remplace les réglages d'une chaîne existante. Une chaîne en cours est redémarrée si la modification affecte son fonctionnement.
DELETE/api/channels/{id}Supprime une chaîne, après l'avoir arrêtée. L'identifiant redevient disponible.
POST/api/channels/{id}/restartRedémarre une chaîne sans toucher aux autres. La première chose à essayer lorsqu'une seule chaîne se comporte mal et que les autres sont saines.
État
POST/api/streams/{id}/activeActive ou désactive une chaîne. Une chaîne désactivée conserve sa configuration mais n'est jamais démarrée.
POST/api/streams/{id}/force-always-onBascule le forçage en marche permanente. Activé, la chaîne tourne en continu ; désactivé, elle tourne lorsque la détection des spectateurs voit quelqu'un regarder.
Inspection
GET/api/channelsUne liste succincte de toutes les chaînes : id, name, address et port de destination, et epg_id. De quoi savoir quelles chaînes existent. Elle ne renvoie pas l'ensemble des réglages d'une chaîne — source, moteur, profil, supervision — : un script qui en a besoin lit le fichier de configuration.
GET/api/channels/{id}/ts-qualityQualité du transport stream pour une chaîne : le dernier échantillon, les totaux cumulés des erreurs de continuité, de transport et de PCR, et l'historique des 30 dernières minutes par intervalles de 5 secondes. Indique aussi si la supervision tourne pour la chaîne et comment son timing PCR est mesuré. Voir Qualité du transport stream.
GET/api/channels/{id}/logsSortie récente du moteur pour une chaîne. C'est là qu'une erreur de source apparaît dans les termes réellement employés par le serveur d'origine, plutôt que sous la forme d'un échec générique.
GET/api/channels/resolutionsLa résolution actuellement sélectionnée pour chaque chaîne, et s'il s'agit d'une correspondance exacte avec le profil demandé ou du palier le plus proche proposé par le serveur d'origine. Servi depuis le cache ; ne bloque pas sur les récupérations auprès du serveur d'origine.
Aperçu
POST/api/channels/{id}/previewDémarre un aperçu d'une chaîne consultable dans le navigateur.
POST/api/channels/{id}/preview/stopL'arrête. Les aperçus consomment réellement du CPU : arrêtez-les explicitement plutôt que de compter sur la fermeture de la page.
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
MéthodeCheminRôle
Sources
POST/api/epg/sourcesAjoute une source XMLTV. Corps : {"name": "...", "url": "..."}. Renvoie l'id de la nouvelle source. La liste des chaînes de la source est récupérée en arrière-plan.
PUT/api/epg/sources/{id}Renomme une source ou la fait pointer vers une nouvelle URL, avec le même corps. Les données stockées sont conservées et remplacées à la prochaine synchronisation.
DELETE/api/epg/sources/{id}Supprime une source et ses données de guide stockées. Les chaînes qui y étaient associées conservent leur epg_id.
POST/api/epg/sources/{id}/syncRécupère la source immédiatement et stocke les programmes des chaînes associées. Synchrone : la réponse indique le résultat réel, et sur un guide volumineux cela peut prendre plusieurs minutes.
Association et données
GET/api/epg/channelsToutes les sources, indexées par leur id, avec leur nom, leur URL, leur dernière récupération et leur état, ainsi que les identifiants de guide qu'elles proposent.
POST/api/epg/mapAssocie une chaîne à un identifiant de guide. Corps : {"stream_id": 3, "tvg_id": "rtl.de"}. Un tvg_id vide supprime l'association. Enregistré dans l'epg_id de la chaîne.
GET/api/epg/nowLe programme en cours et le suivant, pour toutes les chaînes associées, en un seul appel. Une chaîne associée sans programme diffusé est présente avec now vide, ce qui diffère d'une chaîne non associée, qui est absente.
MéthodeCheminRôle
GET/api/licenceL'état de licence de l'appareil : state avec un message et un detail lisibles, can_stream, le device_code que le support vous demandera, et un contact de support. Si la dernière synchronisation a refusé des chaînes envoyées par le serveur de licences, les raisons sont également incluses. Le jeton de licence lui-même n'est jamais renvoyé.
POST/api/licence/retrySe connecte immédiatement au serveur de licences au lieu d'attendre la prochaine tentative planifiée. À utiliser après avoir corrigé ce qui bloquait la licence, par exemple un abonnement expiré ou une règle de pare-feu. La réponse est immédiate ; interrogez /api/licence pour connaître le résultat.
MéthodeCheminRôle
GET/api/viewersL'état des spectateurs pour toutes les chaînes en un seul appel. Utilisez-le pour l'interrogation périodique plutôt que de boucler sur les chaînes, ce qui multiplie le nombre de requêtes par la taille de la liste de chaînes.
GET/api/streams/{id}/viewersDétail pour une chaîne : la liste des adresses clientes actuellement abonnées, leur nombre, un indicateur de présence d'un querier IGMP sur le segment, et un indicateur signalant si la détection est dégradée.
MéthodeCheminRôle
Mesure
GET/api/metricsMétriques système et métriques par chaîne dans un seul document : CPU, mémoire, durée de fonctionnement, état et débit de chaque chaîne. Mis en cache environ deux secondes côté serveur : interroger plus souvent renvoie les mêmes chiffres et ne coûte que du traitement de requêtes.
GET/api/network-statsCompteurs au niveau des interfaces et résultats de joignabilité des hôtes listés dans ping_hosts.
GET/api/udp-bitrateDébit mesuré qui sort réellement du port réseau, par chaîne. C'est le signal de vie indépendant du moteur : il reflète ce qui est sur le fil plutôt que ce qu'un décodeur prétend produire.
Administration
PUT/api/settingsModifie les réglages global. N'envoyez que les clés à modifier ; tout ce qui est omis conserve sa valeur actuelle. PUT uniquement — il n'existe pas de variante GET : lisez les réglages actuels dans le fichier de configuration.
GET/api/network-interfacesToutes les adresses IPv4 de l'appareil, pour choisir udp_device : adresse, interface, état actif ou non de l'interface, sous-réseau, et attribution éventuelle par DHCP. Les adresses de boucle locale et link-local sont exclues, car aucune n'est jamais le bon choix. Les interfaces inactives sont listées, pas masquées, car une interface inactive est précisément ce que vous avez besoin de voir.
POST/api/restart-allRedémarre toutes les chaînes. Les démarrages sont échelonnés selon startup_stagger_seconds, pour que toute la liste de chaînes ne revienne pas d'un coup et n'échoue pas en bloc.
POST/api/restart-appRedémarre l'application Castmux. Elle répond d'abord, puis s'arrête proprement, et la politique de redémarrage du conteneur la relance en quelques secondes. Toutes les chaînes sont brièvement coupées. Contrairement à /api/reboot, elle n'a besoin de rien sur l'hôte et fonctionne donc dans tout déploiement en conteneur.
POST/api/rebootRedémarre l'appareil. Toutes les chaînes sont coupées pendant toute la durée ; ce n'est pas un remède à une panne de chaîne.
MéthodeCheminRôle
Multiplex
GET/api/dvb/muxesListe les multiplex configurés avec leurs paramètres RF et leur état actuel. Contrairement aux chaînes, les multiplex disposent bien d'un point de terminaison de lecture.
POST/api/dvb/muxesCrée un multiplex.
PUT/api/dvb/muxes/{id}Met à jour les paramètres RF ou les identifiants de signalisation. Modifier la fréquence, la modulation ou le débit de symboles interrompt la porteuse.
DELETE/api/dvb/muxes/{id}Supprime un multiplex. Les chaînes qu'il transportait ne sont pas supprimées.
POST/api/dvb/muxes/{id}/activeDémarre ou arrête l'émission de la porteuse.
Contenu et opérations
POST/api/dvb/muxes/{id}/channelsAffecte les chaînes transportées, et leur ordre. L'ordre détermine les identifiants de service : réordonner réidentifie donc les services et peut obliger les téléviseurs à refaire une recherche. Quand vous avez le choix, ajoutez en fin de liste plutôt que d'insérer.
GET/api/dvb/muxes/{id}/logsSortie du multiplexeur et du modulateur pour cette porteuse.
POST/api/dvb/muxes/{id}/hot-swapÉchange le contenu d'un multiplex en cours sans couper la porteuse, pour que les téléviseurs restent calés au lieu d'afficher « pas de signal » pendant le changement.
POST/api/dvb/muxes/{id}/suspendSuspend temporairement le multiplex, pour une intervention sur le modulateur ou le réseau câblé, sans supprimer la configuration.
MéthodeCheminRôle
POST/api/hdmi/activeActive ou désactive la sortie HDMI.
POST/api/hdmi/configDéfinit la chaîne présentée sur le port HDMI et la manière dont elle est rendue.
GET/api/hdmi/outputsCe que cet appareil peut piloter : vos (pilotes vidéo), drm_devices (périphériques d'affichage) et audio_devices (chacun avec une value et un label, tels que le lecteur lui-même les liste), plus la sélection current. Les valeurs sont exactement celles qu'accepte /api/hdmi/config.
GET/api/hdmi/metricsÉtat et débit de la sortie HDMI.
GET/api/hdmi/logsSortie du processus de rendu HDMI.

Un exemple complet : se connecter, créer trois chaînes, créer un multiplex et y affecter les chaînes dans l’ordre où elles doivent apparaître. C’est toute la séquence de mise en service d’un petit site, et elle mérite d’être scriptée, car saisir trois chaînes dans un formulaire est la source des adresses multicast interverties.

#!/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"

Deux détails de ce script n’ont rien d’anodin. Le sleep 3 entre les créations correspond à startup_stagger_seconds : trois serveurs d’origine HLS ouverts simultanément constituent précisément la situation que l’échelonnement doit éviter, et un script de mise en place est le moyen le plus simple de la recréer. Et les chaînes sont affectées en un seul appel plutôt qu’en trois, car l’ordre d’affectation fixe les identifiants de service — construire la liste d’abord et l’envoyer une seule fois garantit que la liste de chaînes est numérotée comme prévu dès la première tentative.

  • Les erreurs sont en JSON. Une requête en échec renvoie un code d’état approprié et un corps JSON décrivant le problème. Une réponse HTML signifie que la requête n’était pas authentifiée et a été redirigée vers la page de connexion — vérifiez le cookie jar avant de déboguer le corps.
  • PUT /api/settings fusionne. N’envoyez que les réglages à modifier ; tout ce qui est omis conserve sa valeur actuelle. Une modification des paramètres du moteur, de udp_device, default_engine, enable_dummy_listeners, overwrite_srt_latency ou overwrite_pkt_size redémarre toutes les chaînes actives, car ces réglages déterminent le fonctionnement de chaque moteur. Les autres réglages s’appliquent sans redémarrage.
  • La limitation de débit ne remplace pas les données en cache. /api/metrics est mis en cache pendant environ deux secondes ; un tableau de bord qui l’interroge toutes les 250 ms obtient huit réponses identiques et aucune information supplémentaire.

Une API de lecture complète, l’export et l’import de la configuration entière, et des jetons d’API en remplacement des cookies de session sont tous prévus. Ils figurent avec le reste sur la page de feuille de route.