API
Die sechs vier API liefert die Daten hinter dem Radio: was gerade läuft, was als Nächstes kommt und welche Songs zuletzt gespielt wurden. Sie ist offen, liefert JSON und kann nur lesen.
Überblick
| Basis-URL | https://api.sechs-vier.de |
|---|---|
| Format | JSON, UTF-8 |
| Zugriff | nur lesend (GET), ohne Anmeldung |
Aufruf von / | Im Browser siehst du eine Übersichtsseite mit Live-Status. Mit dem Header Accept: application/json bekommst du Name, API-Version und Links als JSON. |
Zum Befüllen der Daten gibt es außerdem einen Endpunkt, der intern und nicht öffentlich ist. Er steht hier nicht zur Verfügung.
{
"name": "sechs vier API",
"description": "Die Daten hinter dem Radio.",
"version": "1",
"links": {
"docs": "https://sechs-vier.de/api/",
"website": "https://sechs-vier.de/",
"now": "/now",
"history": "/history"
}
}
Jetzt läuft
Zweck: Was läuft gerade, und was kommt als Nächstes? Das ist der Endpunkt für ein „Jetzt läuft“-Widget.
GET https://api.sechs-vier.de/now
curl -s https://api.sechs-vier.de/nowconst res = await fetch("https://api.sechs-vier.de/now", { cache: "no-store" });
const now = await res.json();
console.log(now.title, "von", now.artist);{
"id": "34412b69871547e58d1e4695eba9e064",
"artist": "Muster & Co.",
"title": "Dritter Beispielsong",
"cover_url": "https://is1-ssl.mzstatic.com/image/thumb/Music/beispiel3/600x600bb.jpg",
"artist_img_url": "https://cdn-images.dzcdn.net/images/artist/beispiel/1000x1000-000000-80-0-0.jpg",
"video_url": "https://video-ssl.itunes.apple.com/itunes-assets/Video/beispiel.m4v",
"started_at": "2026-11-06T14:15:58Z",
"kind": "song",
"duration_sec": 215,
"next": {
"artist": "Vierte Band",
"title": "Vierter Beispielsong",
"cover_url": "https://is1-ssl.mzstatic.com/image/thumb/Music/beispiel4/600x600bb.jpg"
},
"server_time": 1793974653.4
}
Läuft gerade kein Song (Jingle, Spot, Nachrichten, Moderation), ist kind gleich "other", und Artist, Titel und Bilder sind leer:
{
"id": "a7c86877c2654c4db3d08107fbcf349e",
"artist": "",
"title": "",
"cover_url": null,
"artist_img_url": null,
"video_url": null,
"started_at": "2026-11-06T14:19:33Z",
"kind": "other",
"duration_sec": null,
"next": null,
"server_time": 1793974785.8
}
Solange noch nie etwas gelaufen ist, lautet die Antwort null.
| Feld | Typ | Bedeutung |
|---|---|---|
id | Text | Kennung dieses Eintrags. Ändert sich bei jedem neuen Song. |
artist | Text | Interpret. Bei kind: "other" leer. |
title | Text | Titel. Bei kind: "other" leer. |
cover_url | Text oder null | Adresse des Covers (https). |
artist_img_url | Text oder null | Adresse eines Interpretenbilds (https). |
video_url | Text oder null | Adresse einer Video-Vorschau (https). |
started_at | Text | Startzeit als ISO 8601 in UTC, zum Beispiel 2026-11-06T14:15:58Z. Sie bezieht sich auf den gehörten Stream (siehe Stream-Delay). |
kind | Text | "song" oder "other" (alles, was kein Song ist). |
duration_sec | Zahl oder null | Länge in ganzen Sekunden, wenn bekannt. |
next | Objekt oder null | Der nächste Song mit artist, title und cover_url. Nur bei laufendem Song gesetzt. |
server_time | Zahl | Serverzeit in Sekunden seit 1970 (Unix-Zeit). Damit kannst du den Fortschritt berechnen, ohne der Uhr des Geräts zu vertrauen: server_time - Date.parse(started_at) / 1000. |
Zuletzt gespielt
Zweck: Die letzten Songs, neueste zuerst. Der aktuelle Song und alles, was kein Song ist, fehlen.
GET https://api.sechs-vier.de/history?limit=2
| Parameter | Bedeutung |
|---|---|
limit | Anzahl der Songs, 1 bis 599. Ohne Angabe 20. |
curl -s "https://api.sechs-vier.de/history?limit=2"const res = await fetch("https://api.sechs-vier.de/history?limit=2", { cache: "no-store" });
const songs = await res.json();
songs.forEach((s) => console.log(s.artist, "-", s.title));[
{
"id": "c6e75a3c47534c7fbc29b60d5e853771",
"artist": "Die Beispiele",
"title": "Zweiter Beispielsong",
"cover_url": "https://is1-ssl.mzstatic.com/image/thumb/Music/beispiel2/600x600bb.jpg",
"artist_img_url": null,
"video_url": null,
"started_at": "2026-11-06T14:12:40Z",
"kind": "song",
"duration_sec": 187
},
{
"id": "a993c8aac308452e87e8042a0e5ff16e",
"artist": "Beispielband",
"title": "Erster Beispielsong",
"cover_url": "https://is1-ssl.mzstatic.com/image/thumb/Music/beispiel1/600x600bb.jpg",
"artist_img_url": null,
"video_url": null,
"started_at": "2026-11-06T14:09:12Z",
"kind": "song",
"duration_sec": 201
}
]
Die Felder sind dieselben wie bei /now, nur next und server_time gibt es hier nicht. Ist die Liste leer, lautet die Antwort [].
Live-Stream der Änderungen
Zweck: Statt ständig nachzufragen, hältst du eine Verbindung offen und bekommst jede Änderung sofort (Server-Sent Events).
GET https://api.sechs-vier.de/events
curl -s -N https://api.sechs-vier.de/eventsconst es = new EventSource("https://api.sechs-vier.de/events");
es.addEventListener("now", (e) => {
const now = JSON.parse(e.data);
console.log(now.title);
});
es.addEventListener("ping", () => { /* Verbindung lebt */ });retry: 5000
event: now
data: {"id": "34412b69871547e58d1e4695eba9e064", "artist": "Muster & Co.", "title": "Dritter Beispielsong", "cover_url": "https://is1-ssl.mzstatic.com/image/thumb/Music/beispiel3/600x600bb.jpg", "artist_img_url": "https://cdn-images.dzcdn.net/images/artist/beispiel/1000x1000-000000-80-0-0.jpg", "video_url": "https://video-ssl.itunes.apple.com/itunes-assets/Video/beispiel.m4v", "started_at": "2026-11-06T14:15:58Z", "kind": "song", "duration_sec": 215, "next": {"artist": "Vierte Band", "title": "Vierter Beispielsong", "cover_url": "https://is1-ssl.mzstatic.com/image/thumb/Music/beispiel4/600x600bb.jpg"}, "server_time": 1793974653.4}
: keepalive
event: ping
data: {}
| Ereignis | Bedeutung |
|---|---|
now | Dasselbe Objekt wie bei /now. Kommt direkt nach dem Verbinden und danach bei jeder Änderung. |
ping | Etwa alle 15 Sekunden ein Lebenszeichen ohne Inhalt ({}). |
Zeilen, die mit : beginnen, sind Kommentare, die Verbindungen offen halten. Du kannst sie ignorieren. Kommt länger als 45 Sekunden gar nichts an, ist die Verbindung vermutlich tot: schließen und neu öffnen. Pro Adresse sind höchstens 20 gleichzeitige Streams erlaubt.
Erreichbarkeit
Zweck: Läuft der Dienst?
GET https://api.sechs-vier.de/health
curl -s https://api.sechs-vier.de/health{
"ok": true
}
Fehlercodes
Fehler kommen immer als kleines JSON mit dem Feld error. Mehr Details gibt der Dienst bewusst nicht heraus.
| Status | Bedeutung |
|---|---|
404 | Diesen Pfad gibt es nicht. {"error": "not found"} |
405 | Falsche Methode. Öffentlich geht nur GET. |
422 | Ungültiger Parameter, zum Beispiel limit=abc. {"error": "invalid"} |
429 | Zu viele Anfragen. Der Header Retry-After nennt die Sekunden bis zum nächsten Versuch. |
500, 502, 503 | Der Dienst hat gerade ein Problem oder wird neu gestartet. Später erneut versuchen. |
{
"error": "too many requests"
}
Hinweise
Abfrage-Intervall
Frage /now höchstens alle 5 bis 10 Sekunden ab, besser nutzt du /events. Pro Adresse sind rund 300 Anfragen pro Minute erlaubt. Danach antwortet die API mit 429. Halte dich an Retry-After und mach dann langsamer weiter, statt es sofort noch einmal zu versuchen.
Caching
/now, /history und /events senden Cache-Control: no-store bzw. no-cache. Die Antworten ändern sich laufend, speichere sie nicht zwischen. Frage selbst im Browser mit cache: "no-store" ab.
CORS
Aus dem Browser dürfen nur Seiten von https://sechs-vier.de lesen. Das steht im Header Access-Control-Allow-Origin. Erlaubt ist nur GET. Von einer anderen Website aus blockiert der Browser die Abfrage. Rufe die API dann auf deinem Server ab und gib die Daten von dort weiter. Wenn du einen anderen Anwendungsfall hast, melde dich über die Kontaktseite.
Stream-Delay
Der Livestream kommt mit einigen Sekunden Verzögerung bei dir an. Die API zeigt einen Song deshalb erst an, wenn er im Stream wirklich zu hören ist. Anzeige und Ton passen so zusammen. Du musst nichts umrechnen: started_at gilt für den gehörten Stream, nicht für das Studio.
Cover und Bilder
Die Adressen für Cover, Interpretenbilder und Videos zeigen auf Server der Rechteinhaber und Musikdienste. Sie können sich ändern oder verschwinden. Baue Bilder so ein, dass die Seite auch ohne sie funktioniert.
Einbinden: „Jetzt läuft“-Widget
Ein kleines Beispiel für eine Seite auf sechs-vier.de. Es fragt alle 10 Sekunden ab, setzt Texte immer mit textContent (nie als HTML) und übernimmt nur Bilder mit https. Schlägt eine Abfrage fehl, versucht es später einfach weiter.
<div id="np" aria-live="polite">
<img id="np-cover" alt="" width="80" height="80" hidden>
<p><strong id="np-title"></strong> <span id="np-artist"></span></p>
</div>
<script>
(function () {
var BASE = "https://api.sechs-vier.de";
function update() {
var ctl = new AbortController();
var t = setTimeout(function () { ctl.abort(); }, 8000);
fetch(BASE + "/now", { cache: "no-store", signal: ctl.signal })
.then(function (r) { return r.ok ? r.json() : null; })
.then(function (n) {
var song = n && n.kind === "song";
document.getElementById("np-title").textContent = song ? n.title : "sechs vier";
document.getElementById("np-artist").textContent = song ? "von " + n.artist : "";
var img = document.getElementById("np-cover");
var ok = song && /^https:\/\//.test(n.cover_url || "");
if (ok) { img.src = n.cover_url; }
img.hidden = !ok;
})
.catch(function () { /* beim nächsten Mal wieder */ })
.then(function () { clearTimeout(t); setTimeout(update, 10000); });
}
update();
})();
</script>Nutzungsbedingungen
- Nicht kommerziell. Die API darf nur für nicht-kommerzielle Zwecke genutzt werden.
- Quelle nennen. Wo du Daten aus der API anzeigst, nenne die Quelle: „sechs vier von hier“, am besten mit Link auf sechs-vier.de.
- Keine Garantie. Es gibt keine Zusage für Verfügbarkeit oder Richtigkeit der Daten. Die API kann sich ändern, ausfallen oder eingestellt werden. Bei Missbrauch oder Überlastung können Zugriffe gesperrt werden.
- Rechte Dritter. Die Rechte an Covern, Interpretenbildern und Videos liegen bei den jeweiligen Rechteinhabern. Sie gehören nicht zu sechs vier und dürfen nicht ohne Erlaubnis weiterverwendet werden.
- Fair nutzen. Halte die Abfrage-Intervalle ein (siehe Hinweise).
Mehr dazu im Impressum und in der Datenschutzerklärung.