Server gibt bei POST /api/v1/player/status jetzt mqtt-Block zurück (broker, username, password) wenn MORZ_INFOBOARD_MQTT_BROKER gesetzt ist. Agents parsen die Response und verbinden sich bei Config-Änderung automatisch neu (applyMQTTConfig mit Reconnect-Logik, thread-safe via Mutex). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
28 KiB
Info-Board Neu - API-Endpoints Vollständig
Überblick
Die Backend-API unterteilt sich in mehrere Bereiche:
- Health & Meta: System-Status und API-Informationen
- Player Status: Status-Ingest und Diagnose vom Player
- Screenshot API: On-Demand- und periodische Screenshots vom Player
- Screen Management: CRUD und Registrierung von Screens
- Playlists: Abruf und Verwaltung von Wiedergabelisten
- Media: Upload und Verwaltung von Medien-Assets
- Message Wall: Auflösung von Nachrichten-Wand-Anfragen
- Admin & UI: Web-Formulare und Provisionierung
- Provisioning: Erstinstallation neuer Screens (geplant)
Health & Meta
GET /healthz
Health-Check für Monitoring.
Response:
{
"status": "ok",
"service": "morz-infoboard-backend"
}
GET /api/v1
API-Entrypoint mit Tools-Übersicht.
Response:
{
"name": "morz-infoboard-backend",
"version": "dev",
"tools": [
"message-wall-resolve",
"screen-status-list",
"screen-status-detail",
"player-status-ingest",
"screen-status-delete"
]
}
GET /api/v1/meta
Zusätzliche Metainformationen (noch nicht spezifiziert).
Player Status (Diagnose)
Siehe separate Dokumentation in PLAYER-STATUS-HTTP.md.
Endpoints:
POST /api/v1/player/status— Status-Ingest vom Player-AgentGET /api/v1/screens/status— Übersicht aller Screen-StatusGET /api/v1/screens/{screenId}/status— Einzelner Screen-StatusDELETE /api/v1/screens/{screenId}/status— Status löschen
POST /api/v1/player/status
Der Player-Agent sendet seinen aktuellen Status an den Server.
Request-Body:
{
"screen_id": "info01-dev",
"ts": "2026-03-22T16:00:00Z",
"status": "running",
"server_connectivity": "online",
"server_url": "http://127.0.0.1:8080",
"mqtt_broker": "tcp://127.0.0.1:1883",
"heartbeat_every_seconds": 30,
"started_at": "2026-03-22T15:59:30Z",
"last_heartbeat_at": "2026-03-22T16:00:00Z"
}
Response:
{ "status": "accepted" }
Wenn auf dem Server ein MQTT-Broker konfiguriert ist (MORZ_INFOBOARD_MQTT_BROKER), enthält die Response zusätzlich ein mqtt-Objekt mit den Verbindungsdaten. Der Agent soll diese Konfiguration übernehmen und seine MQTT-Verbindung bei Bedarf neu aufbauen.
{
"status": "accepted",
"mqtt": {
"broker": "tcp://mqtt.example.com:1883",
"username": "agent",
"password": "secret"
}
}
mqtt— nur vorhanden, wenn ein Broker konfiguriert ist (omitempty); fehlt das Feld, bleibt die bestehende MQTT-Konfiguration des Agents unverändertmqtt.broker— MQTT-Broker-URL (immer gesetzt, wennmqttvorhanden)mqtt.username— Benutzername (nur wenn konfiguriert, omitempty)mqtt.password— Passwort (nur wenn konfiguriert, omitempty)
Screen Management (JSON API)
POST /api/v1/screens/register
Agent-Selbstregistrierung — wird vom Player-Agent beim Hochfahren aufgerufen.
Der Agent upsert den Screen automatisch im Default-Tenant ("morz"), so dass alle deployt Screen automatisch im Admin-UI erscheinen.
Request-Body:
{
"slug": "info10",
"name": "Info10 Bildschirm",
"orientation": "landscape"
}
Response:
{
"id": "uuid...",
"tenant_id": "uuid...",
"slug": "info10",
"name": "Info10 Bildschirm",
"orientation": "landscape",
"created_at": "2026-03-22T16:00:00Z",
"updated_at": "2026-03-22T16:00:00Z"
}
Status:
200 OK— Screen wurde erzeugt oder aktualisiert (upsert)400 Bad Request— Slug fehlt oder ungültig500 Internal Server Error— DB-Fehler oder Default-Tenant nicht vorhanden
GET /api/v1/tenants/{tenantSlug}/screens
Listet alle Screens eines Tenants auf.
Response:
[
{
"id": "uuid...",
"tenant_id": "uuid...",
"slug": "info10",
"name": "Info10 Bildschirm",
"orientation": "landscape",
"created_at": "2026-03-22T16:00:00Z",
"updated_at": "2026-03-22T16:00:00Z"
},
...
]
Status:
200 OK— Liste erfolgreich abrufen404 Not Found— Tenant nicht vorhanden500 Internal Server Error— DB-Fehler
POST /api/v1/tenants/{tenantSlug}/screens
Erstellt einen neuen Screen für einen Tenant (Admin-API).
Request-Body:
{
"slug": "new-screen",
"name": "New Display",
"orientation": "portrait"
}
Response:
{
"id": "uuid...",
"tenant_id": "uuid...",
"slug": "new-screen",
"name": "New Display",
"orientation": "portrait",
"created_at": "2026-03-22T16:00:00Z",
"updated_at": "2026-03-22T16:00:00Z"
}
Status:
201 Created— Screen erstellt400 Bad Request— Slug oder Name fehlt404 Not Found— Tenant nicht vorhanden500 Internal Server Error— DB-Fehler
Playlist Management (JSON API)
GET /api/v1/screens/{screenId}/playlist
Abruf der aktiven Playlist für einen Screen (Player-Sync).
Der Player ruft diesen Endpoint auf, um die aktuellen Inhalte zu laden.
Response:
{
"playlist_id": "uuid...",
"default_duration_seconds": 20,
"items": [
{
"id": "uuid...",
"playlist_id": "uuid...",
"media_asset_id": null,
"order_index": 0,
"type": "web",
"src": "http://example.com/page1",
"title": "Startseite",
"duration_seconds": 30,
"enabled": true,
"valid_from": null,
"valid_until": null,
"created_at": "2026-03-22T16:00:00Z"
},
{
"id": "uuid...",
"playlist_id": "uuid...",
"media_asset_id": "uuid...",
"order_index": 1,
"type": "image",
"src": "/uploads/banner.jpg",
"title": "Werbebanner",
"duration_seconds": 20,
"enabled": true,
"valid_from": null,
"valid_until": null,
"created_at": "2026-03-22T16:00:00Z"
}
]
}
Wenn keine Playlist vorhanden ist, wird eine leere Liste zurückgegeben:
{
"items": []
}
Status:
200 OK— Playlist abrufen404 Not Found— Screen nicht vorhanden
GET /api/v1/playlists/{screenId}
Abrufen einer kompletten Playlist mit Metadaten.
Response:
{
"playlist": {
"id": "uuid...",
"screen_id": "uuid...",
"tenant_id": "uuid...",
"name": "Hauptplaylist",
"is_active": true,
"default_duration_seconds": 20,
"fallback_enabled": true,
"fallback_dir": "/fallback",
"shuffle_enabled": false,
"created_at": "2026-03-22T16:00:00Z",
"updated_at": "2026-03-22T16:00:00Z"
},
"items": [
{
"id": "uuid...",
"playlist_id": "uuid...",
"type": "web",
"src": "http://example.com",
"title": "Example",
"duration_seconds": 20,
"enabled": true,
"created_at": "2026-03-22T16:00:00Z"
}
]
}
Status:
200 OK— Erfolgreich abrufen500 Internal Server Error— DB-Fehler
POST /api/v1/playlists/{playlistId}/items
Fügt ein Item zu einer Playlist hinzu.
Request-Body (Optionen A: Aus Media-Library):
{
"media_asset_id": "uuid...",
"title": "Optional überschriebener Titel"
}
Request-Body (Optionen B: Direkte URL):
{
"type": "web",
"src": "http://example.com/page",
"title": "Example Page",
"duration_seconds": 30,
"valid_from": "2026-03-22T09:00:00Z",
"valid_until": "2026-03-22T17:00:00Z"
}
Response:
{
"id": "uuid...",
"playlist_id": "uuid...",
"type": "web",
"src": "http://example.com/page",
"title": "Example Page",
"duration_seconds": 30,
"enabled": true,
"valid_from": "2026-03-22T09:00:00Z",
"valid_until": "2026-03-22T17:00:00Z",
"created_at": "2026-03-22T16:00:00Z"
}
Status:
201 Created— Item erstellt400 Bad Request— Type oder Src fehlt; Media-Asset nicht vorhanden500 Internal Server Error— DB-Fehler
PATCH /api/v1/items/{itemId}
Aktualisiert ein Playlist-Item (Titel, Dauer, Zeitfenster, aktiviert).
Request-Body:
{
"title": "Neuer Titel",
"duration_seconds": 25,
"enabled": true,
"valid_from": "2026-03-22T09:00:00Z",
"valid_until": "2026-03-22T17:00:00Z"
}
Status:
204 No Content— Erfolgreich aktualisiert400 Bad Request— Ungültige Dauer500 Internal Server Error— DB-Fehler
DELETE /api/v1/items/{itemId}
Löscht ein Playlist-Item.
Status:
204 No Content— Erfolgreich gelöscht500 Internal Server Error— DB-Fehler
PUT /api/v1/playlists/{playlistId}/order
Reordnet die Items einer Playlist anhand einer geordneten Liste von Item-IDs.
Request-Body:
[
"item-id-1",
"item-id-2",
"item-id-3"
]
Status:
204 No Content— Erfolgreich reordert400 Bad Request— JSON-Array erwartet500 Internal Server Error— DB-Fehler
PATCH /api/v1/playlists/{playlistId}/duration
Setzt die Standard-Dauer für neue Items einer Playlist.
Request-Body (Form-Encoded):
default_duration_seconds=25
Status:
204 No Content— Erfolgreich aktualisiert400 Bad Request— Ungültige oder fehlende Dauer500 Internal Server Error— DB-Fehler
Media Management (JSON API)
GET /api/v1/tenants/{tenantSlug}/media
Listet alle Medien-Assets eines Tenants auf.
Response:
[
{
"id": "uuid...",
"tenant_id": "uuid...",
"title": "Banner Image",
"description": null,
"type": "image",
"source_kind": "upload",
"storage_path": "/uploads/1234567890_banner.jpg",
"original_url": null,
"mime_type": "image/jpeg",
"size_bytes": 102400,
"enabled": true,
"created_at": "2026-03-22T16:00:00Z",
"updated_at": "2026-03-22T16:00:00Z"
},
{
"id": "uuid...",
"tenant_id": "uuid...",
"title": "External Website",
"type": "web",
"source_kind": "remote_url",
"original_url": "http://example.com",
"storage_path": null,
"enabled": true,
"created_at": "2026-03-22T16:00:00Z"
}
]
Wenn keine Assets vorhanden sind, wird eine leere Liste zurückgegeben.
Status:
200 OK— Liste erfolgreich abrufen404 Not Found— Tenant nicht vorhanden500 Internal Server Error— DB-Fehler
POST /api/v1/tenants/{tenantSlug}/media
Registriert ein neues Medien-Asset (Datei-Upload oder externe URL).
Request-Typ A: Datei-Upload (Multipart)
Content-Type: multipart/form-data
type: image (oder video, pdf)
title: Mein Bild
file: <binary data>
Request-Typ B: Externe URL (Multipart)
Content-Type: multipart/form-data
type: web
title: Externe Website
url: http://example.com
Response:
{
"id": "uuid...",
"tenant_id": "uuid...",
"title": "Mein Bild",
"type": "image",
"source_kind": "upload",
"storage_path": "/uploads/1234567890_mein_bild.jpg",
"mime_type": "image/jpeg",
"size_bytes": 102400,
"enabled": true,
"created_at": "2026-03-22T16:00:00Z"
}
Status:
201 Created— Asset erstellt400 Bad Request— Ungültiger Type, fehlende Datei/URL, oder Request zu groß (>512 MB)404 Not Found— Tenant nicht vorhanden500 Internal Server Error— Datei-/DB-Fehler
DELETE /api/v1/media/{id}
Löscht ein Medien-Asset (und physische Datei falls lokal gespeichert).
Status:
204 No Content— Erfolgreich gelöscht404 Not Found— Asset nicht vorhanden500 Internal Server Error— DB-Fehler
Message Wall
POST /api/v1/tools/message-wall/resolve
Spezialendpoint zur Auflösung von Nachrichten-Wand-Anfragen (noch in Entwicklung).
Authentifizierung (Web-Formulare)
Alle Auth-Routen erfordern keine vorherige Authentifizierung.
GET /
Root-Redirect auf /login.
- Anfragen auf exakt
/werden per303 See Otherzu/loginweitergeleitet. - Anfragen auf unbekannte Pfade (z. B.
/irgendwas) geben404 Not Foundzurück (404-Guard).
Status:
303 See Other— Weiterleitung zu/login404 Not Found— Pfad existiert nicht
GET /login
Zeigt das Login-Formular.
- Wenn ein gueltiges
morz_session-Cookie vorhanden ist, wird direkt zum jeweiligen Dashboard weitergeleitet (/adminfuer Admins,/tenant/{slug}/dashboardfuer Tenant-User).
Response: HTML-Seite mit Benutzername/Passwort-Formular und optionaler Flash-Message.
POST /login
Verarbeitet die Login-Eingabe.
Request (Form-Encoded):
username=admin&password=geheim&csrf_token=<token>
Das CSRF-Token muss als verstecktes Formularfeld csrf_token mitgesendet werden.
Der Token wird beim GET /login als Cookie morz_csrf gesetzt und in den Template-Daten
als {{.CSRFToken}} bereitgestellt.
Verhalten:
- Passwort wird per
bcrypt.CompareHashAndPasswordgeprueft - Bei Erfolg wird ein
morz_session-Cookie gesetzt (HttpOnly, Secure, 24h TTL) - Weiterleitung je nach Rolle:
admin→/admin,tenant→/tenant/{slug}/dashboard - Bei Fehler: Rueckkehr zur Login-Seite mit Flash-Message
Status:
303 See Other— Erfolg, Weiterleitung303 See Other— Fehler, Rueckkehr zur Login-Seite mit?msg=
POST /logout
Meldet den aktuellen Benutzer ab.
Request (Form-Encoded):
csrf_token=<token>
Das CSRF-Token muss als verstecktes Formularfeld csrf_token mitgesendet werden.
Der aktuelle Token-Wert wird beim GET-Aufruf der aufrufenden Seite als {{.CSRFToken}}
in die Template-Daten eingebettet und als Cookie morz_csrf gesetzt.
Verhalten:
- Session wird in der DB geloescht (
DeleteSession) - Cookie wird mit
MaxAge=-1geloescht - Weiterleitung zu
/login
Status:
303 See Other403 Forbidden— CSRF-Token fehlt oder ungueltig
Tenant Self-Service Dashboard (Web-Formulare)
Alle Tenant-Routen erfordern RequireAuth + RequireTenantAccess.
Admins koennen auf jeden Tenant zugreifen; Tenant-User nur auf ihren eigenen.
GET /tenant/{tenantSlug}/dashboard
Zeigt das Tenant-Self-Service-Dashboard.
Tabs:
- Tab A "Meine Monitore" — Screen-Karten mit Live-Status (via JS-Fetch aus
/api/v1/screens/status) - Tab B "Mediathek" — Upload-Formular und Dateiliste
Query-Parameter:
tab=media— oeffnet direkt Tab B (z. B. nach Upload-Redirect)flash=uploaded/flash=deleted— zeigt Erfolgs-Flash-Message
Response: HTML-Seite.
POST /tenant/{tenantSlug}/upload
Laedt ein Medium fuer den Tenant hoch.
Request (Multipart Form):
type: image (oder video, pdf)
title: Mein Bild
file: <binary data>
oder fuer eine Web-URL:
type: web
title: Externe Website
url: http://example.com
Verhalten:
- Datei wird in
MORZ_INFOBOARD_UPLOAD_DIRgespeichert - MIME-Typ wird aus dem Upload-Header abgeleitet
- Max. Upload-Groesse: 512 MB
Status:
303 See Other→/tenant/{slug}/dashboard?tab=media&flash=uploaded400 Bad Request— fehlender Typ oder Datei404 Not Found— Tenant nicht vorhanden
POST /tenant/{tenantSlug}/media/{mediaId}/delete
Loescht ein Medien-Asset des Tenants.
Verhalten:
- Eigentuemer-Pruefung:
asset.TenantIDmuss mit dem Tenant uebereinstimmen - Physische Datei wird geloescht sofern vorhanden
Status:
303 See Other→/tenant/{slug}/dashboard?tab=media&flash=deleted403 Forbidden— Asset gehoert nicht diesem Tenant404 Not Found— Tenant oder Asset nicht vorhanden
Admin UI (Web-Formulare)
GET /admin
Administrations-Dashboard mit Übersicht aller Screens und Tenants.
Rückgabe: HTML-Seite mit:
- Liste aller Screens
- Status-Information
- Provisioning-Formulare
- Screen-Verwaltung
POST /admin/screens/provision
Startet einen Provisionierungs-Job für einen neuen oder bestehenden Screen.
Request-Body (Form-Encoded oder JSON):
{
"screen_id": "uuid...",
"target_ip": "192.168.1.100",
"target_port": 22,
"remote_user": "root",
"auth_mode": "password",
"provided_secret_ref": "secret-key-123"
}
Status:
200 OK— Job erfolgreich erstellt400 Bad Request— Fehlende oder ungültige Parameter404 Not Found— Screen nicht vorhanden500 Internal Server Error— DB-Fehler
Hinweis: Der eigentliche Provisionierungs-Job läuft asynchron über einen Worker ab.
POST /admin/screens
Erstellt einen neuen Screen über das Admin-Formular.
Request-Body (Form-Encoded):
slug=new-screen&name=Neuer+Bildschirm&orientation=landscape
Status:
200 OKoder201 Created— Screen erstellt400 Bad Request— Fehlende Parameter500 Internal Server Error— DB-Fehler
Rückleitung zur Admin-Seite.
POST /admin/screens/{screenId}/delete
Löscht einen Screen.
Status:
200 OK— Screen gelöscht404 Not Found— Screen nicht vorhanden500 Internal Server Error— DB-Fehler
Rückleitung zur Admin-Seite.
Screen-User Management (Admin)
POST /admin/users
Erstellt einen neuen Screen-User für einen Tenant (Admin-Formular).
Request-Body (Form-Encoded):
username=screenuser1&password=geheim
Verhalten:
- Neuer User mit
role = 'screen_user'wird angelegt - Passwort wird per bcrypt gehasht
- User wird dem aktuellen Tenant zugeordnet
Status:
200 OKoder201 Created— Screen-User erstellt400 Bad Request— Fehlende oder ungültige Parameter, Username bereits vorhanden500 Internal Server Error— DB-Fehler
Rückleitung zur Admin-Seite.
POST /admin/users/{userID}/delete
Löscht einen Screen-User und alle zugeordneten Screen-Permissions.
Verhalten:
- User mit Rolle
screen_userwird gelöscht - Alle Einträge in
user_screen_permissionsfür diesen User werden gelöscht
Status:
200 OK— Screen-User gelöscht404 Not Found— User nicht vorhanden oder falscher Typ500 Internal Server Error— DB-Fehler
Rückleitung zur Admin-Seite.
POST /admin/screens/{screenID}/users
Fügt einen Screen-User zu einem Screen hinzu.
Request-Body (Form-Encoded):
user_id=<userID>
Verhalten:
- Eintrag in
user_screen_permissionswird erstellt - User muss vom Typ
screen_usersein - Unique-Constraint verhindert Duplikate
Status:
200 OK— User zu Screen hinzugefügt400 Bad Request— Fehlende Parameter, User bereits hinzugefügt404 Not Found— Screen oder User nicht vorhanden500 Internal Server Error— DB-Fehler
Rückleitung zur Admin-Seite oder zum Screen-Detail.
POST /admin/screens/{screenID}/users/{userID}/remove
Entfernt einen Screen-User von einem Screen.
Verhalten:
- Eintrag in
user_screen_permissionswird gelöscht - User behält seine Existenz; nur die Permission wird entfernt
Status:
200 OK— User von Screen entfernt404 Not Found— Screen, User oder Permission nicht vorhanden500 Internal Server Error— DB-Fehler
Rückleitung zur Admin-Seite oder zum Screen-Detail.
Playlist Management UI (Web-Formulare)
GET /manage
Übersichtsseite für eingeloggte Benutzer.
Auth: RequireAuth.
Verhalten:
- Admins und Tenant-User werden direkt zu ihrer Standard-Ansicht weitergeleitet.
- Screen-User mit genau einem zugeordneten Screen werden direkt zu
GET /manage/{screenSlug}weitergeleitet. - Screen-User mit mehreren zugeordneten Screens erhalten eine Übersichtsseite mit Links zu den einzelnen Screens.
Response: HTML-Seite oder Redirect (303 See Other).
GET /manage/{screenSlug}
Verwaltungs-UI für die Playlist eines Screens.
Rückgabe: HTML-Seite mit:
- Liste der Medien-Assets
- Playlist-Editor
- Upload-Formular
- Item-Verwaltung
POST /manage/{screenSlug}/upload
Datei-Upload über das Manage-Formular.
Request (Multipart):
type: image (oder video, pdf)
title: Neues Bild
file: <binary data>
Status:
201 Created— Asset erfolgreich hochgeladen404 Not Found— Screen nicht vorhanden500 Internal Server Error— Fehler
Rückleitung zum Manage-Formular.
POST /manage/{screenSlug}/items
Fügt ein Item zur Playlist hinzu (Formular).
Request (Form-Encoded):
media_asset_id=uuid...&duration_seconds=25
oder
type=web&src=http://example.com&duration_seconds=30
Status:
201 Created— Item erstellt404 Not Found— Screen nicht vorhanden500 Internal Server Error— DB-Fehler
Rückleitung zum Manage-Formular.
POST /manage/{screenSlug}/items/{itemId}
Aktualisiert ein Item (Formular).
Request (Form-Encoded):
title=Neuer+Titel&duration_seconds=25&enabled=on
Status:
200 OKoder204 No Content— Erfolgreich aktualisiert404 Not Found— Item nicht vorhanden500 Internal Server Error— DB-Fehler
Rückleitung zum Manage-Formular.
POST /manage/{screenSlug}/items/{itemId}/delete
Löscht ein Item (Formular).
Status:
204 No Content— Erfolgreich gelöscht404 Not Found— Item nicht vorhanden500 Internal Server Error— DB-Fehler
Rückleitung zum Manage-Formular.
POST /manage/{screenSlug}/reorder
Reordert Items (Formular).
Request (Form-Encoded mit Array-Syntax):
items=item-id-1&items=item-id-2&items=item-id-3
Status:
204 No Content— Erfolgreich reordert500 Internal Server Error— DB-Fehler
Rückleitung zum Manage-Formular.
POST /manage/{screenSlug}/media/{mediaId}/delete
Löscht ein Medien-Asset (Formular).
Status:
204 No Content— Erfolgreich gelöscht404 Not Found— Asset nicht vorhanden500 Internal Server Error— DB-Fehler
Rückleitung zum Manage-Formular.
Datei-Serving
GET /uploads/{filename}
Stellt hochgeladene Medien-Dateien bereit.
Query-Parameter:
- Keine
Status:
200 OK— Datei gefunden404 Not Found— Datei nicht vorhanden
Diagnostic Pages (HTML)
GET /status
HTML-Diagnoseseite für den Browser mit Übersicht aller Screen-Status.
- Automatisches Refresh alle 15 Sekunden
- Shortcut-Links für Filter
- Filterformular (wie JSON-Read-Pfad)
- Direkte JSON-Detail-Links pro Screen
Query-Parameter: Dieselben wie GET /api/v1/screens/status
q— Screen-ID Substring-Suchederived_state—online,degraded,offlineserver_connectivity—online,degraded,offline,unknownstale—true,falseupdated_since— RFC3339-Zeitstempellimit— positive Ganzzahl
GET /status/{screenId}
HTML-Detailseite für einen einzelnen Screen.
Zeigt:
- Screen-Information
- Derived State
- Player Status
- Connectivity
- Freshness und Timestamps
- Endpunkte und Links
Player Local UI (Agent)
GET /player
Zeigt die lokale Player-UI (HTML) auf dem Gerät.
Rückgabe: HTML-Seite mit:
- Splash-Screen
- Systeminformationen-Overlay
- Verbindungsstatus-Punkt
- Basis für Playlist-Anzeige
GET /api/now-playing
JSON-API des Player-Agents (lokal).
Response:
{
"playlist": [
{
"src": "http://backend.local/api/v1/screens/info10/playlist",
"type": "web",
"title": "Startseite",
"duration_seconds": 30
}
],
"status": "running",
"connectivity": "online"
}
GET /api/sysinfo
Systeminformationen des Player-Agents (lokal).
Response:
{
"items": [
{
"label": "Hostname",
"value": "infoboard-01"
},
{
"label": "Uptime",
"value": "5d 2h 30m"
}
]
}
Fehlerbehandlung
Alle JSON-Responses folgen diesem Fehlermodell (falls implementiert):
{
"error": {
"code": "error_code_here",
"message": "Human-readable error message",
"details": null
}
}
Typische HTTP-Status:
200 OK— Erfolgreiche Anfrage (Read)201 Created— Ressource erstellt204 No Content— Erfolgreiche Anfrage ohne Response-Body400 Bad Request— Eingabe-Validierung fehlgeschlagen404 Not Found— Ressource nicht vorhanden500 Internal Server Error— Server-Fehler
Screenshot API
POST /api/v1/player/screenshot
Vom Player-Agent aufgerufener Endpoint zum Hochladen eines Screenshots.
Auth: Keine.
Request: multipart/form-data, max. 3 MB.
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
screen_id |
string | ja | Interne Screen-ID (entspricht dem Slug des Players) |
screenshot |
Datei | ja | Screenshot-Datei (JPEG oder PNG) |
Der MIME-Typ wird aus dem Content-Type-Header des Datei-Parts übernommen. Fehlt er, wird image/png angenommen.
Der Screenshot wird im In-Memory-ScreenshotStore gespeichert (nicht persistiert, kein Filesystem-Zugriff).
Response:
200 OK— Screenshot gespeichert (kein Body)400 Bad Request—screen_idfehlt,screenshot-Feld fehlt, oder Multipart-Parsing fehlgeschlagen500 Internal Server Error— Lesefehler
GET /api/v1/screens/{screenId}/screenshot
Ruft den zuletzt hochgeladenen Screenshot eines Screens ab.
Auth: RequireAuth (eingeloggter Benutzer).
Path-Parameter:
screenId— Screen-ID (wie beim Upload übergeben)
Response:
200 OK— Raw-Image-Daten mit korrektemContent-Type(z. B.image/jpeg),Cache-Control: no-store404 Not Found— kein Screenshot für diese Screen-ID vorhanden
Änderungshistorie
- 2026-03-24 (Update): MQTT-Konfiguration in POST /api/v1/player/status Response dokumentiert (Doris / Doku-Review)
- Response enthält jetzt optionales
mqtt-Objekt mitbroker,username,password(alle omitempty wenn leer) - Feld wird nur gesendet wenn
MORZ_INFOBOARD_MQTT_BROKERkonfiguriert ist - Agent übernimmt die Konfiguration und reconnectet MQTT bei Änderung
- Response enthält jetzt optionales
- 2026-03-24 (Update): Screenshot-Endpoints implementiert und dokumentiert (Doris / Doku-Review)
POST /api/v1/player/screenshot— war als "In Vorbereitung" markiert, ist jetzt vollständig implementiert; Abschnitt komplett neu verfasstGET /api/v1/screens/{screenId}/screenshot— neuer Endpoint,authOnly, liefert Raw-Image aus In-Memory-StoreGET /manage— neue Übersichtsseite fürscreen_usermit mehreren Screens,authOnly
- 2026-03-24 (Update): CSRF-Pflichtfelder in POST /login und POST /logout dokumentiert (Doris / Doku-Review)
POST /loginundPOST /logouterforderncsrf_tokenals Hidden-Field (Double-Submit-Cookie-Pattern)- Hinweis auf
morz_csrf-Cookie und{{.CSRFToken}}-Template-Variable ergaenzt
- 2026-03-24 (Update): Root-Redirect dokumentiert (Doris / Doku-Review)
GET /— Redirect 303 auf/login, 404-Guard für unbekannte Pfade
- 2026-03-23 (Update): Screen-User Management Endpoints (Doris / Doku-Review)
POST /admin/users— Screen-User anlegenPOST /admin/users/{userID}/delete— Screen-User löschenPOST /admin/screens/{screenID}/users— User zu Screen hinzufügenPOST /admin/screens/{screenID}/users/{userID}/remove— User von Screen entfernen
- 2026-03-23 (Update): Security-Enhancements und Upload-Konsolidierung (Doris / Doku-Review)
- CSRF-Schutz (Double-Submit-Cookie) in
internal/httpapi/csrf.go - Rate-Limiting für
/loginininternal/httpapi/ratelimit.go - Upload-Logik konsolidiert in
internal/fileutil/fileutil.goundinternal/httpapi/uploads.go - Neue Env-Variable
MORZ_INFOBOARD_REGISTER_SECRETdokumentiert - Screenshot-Modul im Agent vorbereitet mit
MORZ_INFOBOARD_SCREENSHOT_EVERY
- CSRF-Schutz (Double-Submit-Cookie) in
- 2026-03-23 (Update): Auth- und Tenant-Dashboard-Endpoints ergaenzt (Doris / Doku-Review)
GET /login,POST /login,POST /logoutdokumentiertGET /tenant/{tenantSlug}/dashboarddokumentiertPOST /tenant/{tenantSlug}/uploaddokumentiertPOST /tenant/{tenantSlug}/media/{mediaId}/deletedokumentiert
- 2026-03-23: Initiale Dokumentation aller HTTP-Endpoints basierend auf Code-Review
- Alle Screen-Management-Endpoints dokumentiert
- Alle Playlist-Management-Endpoints dokumentiert
- Alle Media-Management-Endpoints dokumentiert
- Admin-UI und Manage-UI-Endpoints dokumentiert
- Player-Status-Diagnostik dokumentiert
- Player-Local-API dokumentiert