API-Referenz

Die ScreenWay-Studio-REST-API nutzen.

Die öffentliche API ist um Konto-API-Keys und /api/v1-REST-Endpoints organisiert. Damit automatisieren Sie Screens, Medien, Programme, Apps, Designer-Projekte, Notifications und Analytics.

Authentifizierung

Legen Sie einen API-Key in Studio unter Einstellungen → API Keys an. Keys beginnen mit swk_, werden nur einmal angezeigt und lassen sich auf das Konto, Spaces, Gruppen oder einzelne Screens beschränken. Senden Sie jeden Request mit dem Header Authorization: Bearer swk_….

Screens auflisten
curl https://studio.screenway.com/api/v1/screens \
  -H "Authorization: Bearer swk_your_api_key_here"

Key-Scopes

Jeder Key trägt eine Liste von targets. Target-bewusste Endpoints (z. B. Notifications) respektieren diese: Ein Request, dessen Targets außerhalb des Key-Scope liegen, wird mit 403 abgelehnt. Alle Endpoints sind an das Konto gebunden, ein Key kann niemals Daten in einem anderen Konto lesen oder verändern.

Target-Typen

workspace
scope
Jeder Screen im Konto.
space
scope
Alle Screens im angegebenen Space.
group
scope
Alle Screens einer Screen-Gruppe.
screen
scope
Ein einzelner Screen anhand der ID.

Keys sicher aufbewahren

Der vollständige Key wird einmalig beim Anlegen gezeigt. Studio speichert nur einen Bcrypt-Hash und die ersten 12 Zeichen als Lookup-Prefix. Bei einem Leak: Key unverzüglich widerrufen; der Originalwert lässt sich nicht wiederherstellen.

Fehler

Alle Fehler liefern einen JSON-Body mit einem einzigen error-String und einem passenden HTTP-Status. Validierungsmeldungen sind menschenlesbar und benennen das Problem.

Fehler-Antwort
{
  "error": "Invalid command type. Allowed: content:program, content:media, system:restart, system:reload, playback:jump"
}
200OKLesen oder Aktion erfolgreich.
201CreatedNeue Ressource angelegt (Uploads, Ordner, App-Instanzen, Designer-Projekte).
400Bad RequestPflichtfeld fehlt, Wert ungültig oder Body nicht parsebar.
401UnauthorizedBearer-Token fehlt oder ist ungültig. Authorization-Header prüfen.
403ForbiddenAngeforderte Targets liegen außerhalb des Key-Scope (target-bewusste Endpoints).
404Not FoundRessource existiert nicht, oder existiert in einem anderen Konto und ist für diesen Key versteckt.
500Server ErrorUnerwarteter Fehler. Einmal wiederholen, dann ScreenWay-Status checken.

Kontofremde Lookups liefern 404

Wenn ein Key auf eine Ressource zugreift, die existiert, aber zu einem anderen Konto gehört, antwortet die API mit 404 statt 403, damit fremde IDs nicht geleakt werden.

Pagination & Antworten

List-Endpoints liefern data plus meta. Pagination nutzt limit (Default 50, maximal 200) und offset (Default 0). Single-Resource-Endpoints liefern ein einzelnes data-Objekt ohne meta.

Paginierter Request
GET /api/v1/screens?limit=100&offset=200

{
  "data": [ ... ],
  "meta": { "total": 412, "limit": 100, "offset": 200 }
}

Gemeinsame Query-Parameter

limit
integer
Seitengröße. Default 50, gekappt bei 200.
offset
integer
Anzahl zu überspringender Einträge. Mit limit kombiniert für Paging.
space_id
uuid
Auf einen einzelnen Space im Konto einschränken.

Rate Limits & Retries

Die v1-API erzwingt heute keine harten Rate Limits, das darunterliegende Supabase und der Storage können missbräuchlichen Traffic aber drosseln. Behandeln Sie 500-Antworten als retry-fähig mit exponentiellem Backoff. Media-Uploads (POST /media, /from-url, /from-data) sind am teuersten; Parallelität gering halten.

Idempotente Reads

Bei jedem 5xx oder Netzwerkfehler bedenkenlos wiederholbar.

Mutationen

Nur wiederholen, wenn bestätigt ist, dass der vorherige Call nicht doch durchging. Keiner der mutierenden Endpoints unterstützt aktuell einen Idempotency-Key.

Bulk-Operationen

Workflow-Endpoints wie /programs/{id}/assign, Notifications oder App-Instances bevorzugen, statt Einzelaufrufe zu schleifen.

Endpoint-Übersicht

GET/api/v1/screensScreens auflisten, filterbar nach space_id und status.
GET/api/v1/screens/{id}Screen-Details und aktuellen Status lesen.
POST/api/v1/screens/{id}/commandsNeustart, Reload, Playback-Jump oder Content-Befehl senden.
GET/api/v1/mediaMedien des Kontos auflisten.
POST/api/v1/mediaMedien als multipart/form-data hochladen.
POST/api/v1/media/from-urlÖffentliche Medien per URL importieren.
POST/api/v1/media/from-dataData-URL oder Base64-Payload hochladen.
GET/api/v1/foldersMedien-Ordner eines Space auflisten.
POST/api/v1/foldersMedien-Ordner anlegen.
GET/api/v1/programsProgramme des Kontos auflisten.
POST/api/v1/programs/{id}/assignProgramm einem oder mehreren Screens zuweisen.
GET/api/v1/appsVerfügbare ScreenWay-Apps des Kontos auflisten.
GET/api/v1/app-instancesKonfigurierte App-Instanzen auflisten.
POST/api/v1/app-instancesKonfigurierte App-Instanz anlegen.
GET/api/v1/designer-projectsDesigner-Projekte auflisten.
POST/api/v1/designer-projectsDesigner-Projekt anlegen.
POST/api/v1/designer-projects/{id}/renderDesigner-Projekt zu PNG/JPEG-Data-URL rendern.
POST/api/v1/notificationsNotifications an Screens, Spaces, Gruppen oder Konto-Targets senden.
GET/api/v1/analyticsAnalytics des Kontos für einen Zeitraum.

Screens

GET/api/v1/screens

Screens im Konto listen, sortiert nach Anlagedatum.

Query-Parameter

space_id
uuid
Auf einen einzelnen Space einschränken.
status
string
Nach aktuellem Player-Status filtern (z. B. online, offline).
limit
integer
Default 50, max 200.
offset
integer
Default 0.
200-Antwort
{
  "data": [
    {
      "id": "9e6e…",
      "name": "Lobby Display",
      "status": "online",
      "space_id": "a3b1…",
      "space_name": "Berlin HQ",
      "device_id": "dev_…",
      "is_paired": true,
      "paired_at": "2026-04-12T08:14:22Z",
      "last_seen_at": "2026-05-13T09:02:11Z",
      "player_version": "1.42.0",
      "os_version": "Android 13",
      "resolution": "1920x1080",
      "location": {
        "street_address": "Friedrichstr. 1",
        "postal_code": "10117",
        "city": "Berlin",
        "country": "DE"
      },
      "rotation": 0,
      "created_at": "2026-03-01T11:00:00Z",
      "updated_at": "2026-05-13T09:02:11Z"
    }
  ],
  "meta": { "total": 1, "limit": 50, "offset": 0 }
}
POST/api/v1/screens/{id}/commands

Befehl an einen einzelnen Screen senden. Der Befehl wird in screen_commands persistiert und via Supabase Realtime gebroadcastet.

Body

typerequired
string
Einer von content:program, content:media, system:restart, system:reload, playback:jump.
payload.programId
uuid
Pflicht bei type=content:program.
payload.mediaId
uuid
Pflicht bei type=content:media.
Beispiel-Body
{
  "type": "content:program",
  "payload": { "programId": "prog_…" }
}
200-Antwort
{
  "data": {
    "id": "cmd_…",
    "screen_id": "9e6e…",
    "type": "content:program",
    "status": "sent",
    "created_at": "2026-05-13T09:14:55Z"
  }
}

Medien & Ordner

GET/api/v1/media

Medien im Konto listen, neueste zuerst.

Query-Parameter

space_id
uuid
Auf einen Space beschränken.
type
string
Nach Medientyp filtern (image, video, …).
folder_id
uuid | "__root__"
__root__ für Medien ohne Ordner.
limit / offset
integer
Standard-Pagination.
POST/api/v1/media/from-url

Bild oder Video von einer öffentlichen HTTP(S)-URL importieren. Localhost und private IP-Bereiche werden abgelehnt.

Body

space_idrequired
uuid
Ziel-Space.
urlrequired
string
Öffentliche http(s)-URL.
name
string
Anzeigename; Fallback auf Remote-Dateinamen.
folder_id
uuid
Bestehender Ordner für die Datei.
folder_name
string
Erstellt oder wiederverwendet einen Ordner mit diesem Namen; mit parent_folder_id kombinierbar.
parent_folder_id
uuid
Elternordner für folder_name-Lookups.
Beispiel-Body
{
  "space_id": "a3b1…",
  "url": "https://example.com/poster.png",
  "name": "Frühlings-Poster",
  "folder_name": "Poster"
}
POST/api/v1/media/from-data

Data-URL oder Base64-Payload hochladen. Nützlich für KI-generierte Assets oder QR-Codes.

Body

space_idrequired
uuid
Ziel-Space.
data_url
string
Entweder data_url oder base64_data ist Pflicht.
base64_data
string
Roher Base64-String (zusammen mit mime_type).
mime_type
string
Pflicht, wenn nur base64_data übergeben wird.
file_name
string
Dateiname-Hinweis für den Upload.
Beispiel-Body
{
  "space_id": "a3b1…",
  "data_url": "data:image/png;base64,iVBORw0KGgo...",
  "file_name": "qr.png"
}

Programme

GET/api/v1/programs

Programme im Konto listen.

Query-Parameter

space_id
uuid
Auf einen Space beschränken.
limit / offset
integer
Standard-Pagination.
POST/api/v1/programs/{id}/assign

Programm einem oder mehreren Screens zuweisen. Speichert die Zuweisung und sendet in einem Aufruf einen content:program-Befehl.

Body

screen_idsrequired
uuid[]
Nicht-leere Liste von Screen-IDs im Konto.
Beispiel-Body
{
  "screen_ids": ["9e6e…", "12b3…"]
}

Die Antwort teilt die Eingabe in assigned_screen_ids und skipped_screen_ids auf. Ungültige oder fremde IDs werden stillschweigend übersprungen.

Apps & App-Instanzen

GET/api/v1/apps

Aktive ScreenWay-Apps listen. Mit slug eine bestimmte App finden.

Query-Parameter

slug
string
Exakter Slug-Match (z. B. clock, google-sheets).
category
string
Nach Kategorie filtern (utility, info, entertainment, …).
search
string
Teilstring-Suche über Name, Slug, Description.
limit / offset
integer
Standard-Pagination.
POST/api/v1/app-instances

Konfigurierte App-Instanz in einem Space anlegen.

Body

app_idrequired
uuid
Die zu instanziierende App.
space_idrequired
uuid
Ziel-Space.
namerequired
string
Anzeigename der Instanz.
config
object | string
Konfiguration konform zum config_schema der App. String-Werte müssen gültiges JSON sein.
transparent_background
boolean
App über transparenter Ebene rendern (overlay-tauglich).

Designer-Projekte

POST/api/v1/designer-projects/{id}/render

Das exportierte HTML eines Designer-Projekts in eine Bild-Data-URL rendern. Optional das Ergebnis als Projekt-Thumbnail zurückschreiben.

Body

format
"png" | "jpeg"
Default PNG. JPEG berücksichtigt quality.
width / height
integer
Überschreibt die gerenderte Canvas-Größe; Default ist die Projekt-Canvas.
quality
integer (0-100)
JPEG-Qualität.
wait_ms
integer
Zusätzliche Verzögerung vor dem Snapshot (Fonts/Animationen einschwingen lassen).
update_thumbnail
boolean
Wenn true, wird die gerenderte Data-URL als Projekt-Thumbnail gespeichert.
base_url
string
Überschreibt die Basis-URL für relative Assets. Default ist der Request-Host.
Beispiel-Body
{
  "format": "png",
  "width": 1920,
  "height": 1080,
  "update_thumbnail": false
}

Render setzt exported_html voraus

Projekte ohne exported_html antworten mit 400. Projekt einmal im Designer speichern, damit es generiert wird.

Notifications

POST/api/v1/notifications

Notification-Overlay an Screens broadcasten. Ohne explizites targets wird die im API-Key konfigurierte Zielmenge verwendet.

Body

titlerequired
string
Overlay-Titel.
messagerequired
string
Body-Text.
categoryrequired
enum
INFO, SUCCESS, WARNING, ALERT, EMERGENCY oder PROMO.
priorityrequired
enum
LOW, NORMAL, HIGH oder CRITICAL.
icon
string
Optionaler Icon-Hinweis (vom Player definiert).
action_url
string
Optionale CTA-URL.
action_label
string
Optionales CTA-Label.
duration_seconds
number
Wie lange das Overlay sichtbar bleibt.
targets
Target[]
Überschreibt die Key-Targets. Muss eine Teilmenge sein, sonst 403.
Beispiel-Body
{
  "title": "Service Desk",
  "message": "Schalter 4 ist jetzt geöffnet",
  "category": "INFO",
  "priority": "NORMAL",
  "duration_seconds": 30,
  "action_url": "https://studio.screenway.com/dashboard",
  "action_label": "Dashboard öffnen"
}
200-Antwort
{
  "data": {
    "id": "0a7e…",
    "screens_notified": 4,
    "targets": [{ "type": "workspace", "id": "ws_…" }],
    "resolved_screen_ids": ["9e6e…", "12b3…", "44dd…", "8f1c…"]
  }
}

Analytics

GET/api/v1/analytics

Kontoweiter Analytics-Rollup. Default sind die letzten 7 Tage.

Query-Parameter

from
Datum (YYYY-MM-DD)
Beginn des Zeitraums. Default vor 7 Tagen.
to
Datum (YYYY-MM-DD)
Ende des Zeitraums. Default heute.
space_id
uuid
Auf einen Space beschränken.

Die Antwort enthält Screen-Zählungen (total / online / offline), Durchschnitts-Uptime, Gesamt-Items, eine Pro-Screen-Aufschlüsselung sowie die Top-10 abgespielten Inhalte.

Typische Workflows

Medien automatisieren

Dateien per /media/from-url importieren, in Ordner sortieren und per /screens/{id}/commands (type=content:media) auf Screens schieben.

Playback steuern

Playlist im Studio bauen, dann /programs/{id}/assign aufrufen, um viele Screens gleichzeitig umschalten statt einzelne Commands.

Designer-Pipeline

Designer-Projekt anlegen oder aktualisieren, mit update_thumbnail=true PNG rendern und dem Projekt in einem Programm-Slot zuweisen.

Notifications

Zeitkritische Overlays an die Default-Targets des Keys senden oder per targets feiner skopen.

Reporting

/analytics regelmäßig in Ihr BI-Tool ziehen, pro Space mit space_id gruppieren.

Key-Hygiene

Ein Key pro Integration. Targets auf die Screens beschränken, die die Integration anfassen darf.

Konto-Scoping

Jeder Endpoint löst Daten über das Konto des Keys auf. Eine workspace_id manuell zu übergeben ist weder nötig noch möglich.

Designer + Apps

/app-instances und /designer-projects kombinieren, um geschichtete, geplante Inhalte ohne Studio-Klick zusammenzubauen.

Re-Render

Designer-Projekt nach jeder automatisierten Änderung neu rendern, damit Programm-Preview und Store-Assets synchron bleiben.