Für Entwickler

REST API

Die Orblio-API ist eine externe, Token-authentifizierte Schnittstelle. Damit liest und schreibst du Sammlungen, Seiten, Medien, Ordner und Benutzer aus eigenen Programmen — im JSON-Format über HTTP.

Überblick

Basis-Pfad/_/api/<resource>/… — die Endpunkte liegen unter /_/, damit sie nie mit einer Seite kollidieren.
FormatAnfragen und Antworten in JSON (Content-Type: application/json).
AuthHeader X-Orb-Token und X-Orb-Secret.
RechteJede Operation wird gegen die granularen Rechte des API-Zugangs geprüft.
CORSAktiviert (Access-Control-Allow-Origin: *); OPTIONS liefert 204.

Authentifizierung

Ein API-Zugang ist ein Benutzer mit der Rolle API (siehe Team & Rechte). Bei der Erstellung erhältst du zwei Werte:

TokenÖffentlicher Bezeichner, Form orb_<hex>. Dient dem Nachschlagen des Zugangs.
SecretGeheimnis, Form sk_<hex>. Wird nur einmal bei der Erstellung angezeigt und intern nur als gesalzener SHA-256-Hash gespeichert.

Beide Werte gehören in jede Anfrage — als HTTP-Header:

X-Orb-Token:  orb_1a2b3c4d5e6f...
X-Orb-Secret: sk_9f8e7d6c5b4a...

Secret sicher aufbewahren

Das Secret kann nach der Erstellung nicht erneut angezeigt werden. Bewahre es sicher auf (z. B. in einem Passwort-Tresor). Geht es verloren, erzeuge einen neuen Zugang. Ein deaktivierter/gesperrter Zugang kann sich nicht mehr authentifizieren.

Fehlen die Header oder passen Token/Secret nicht zusammen, antwortet die API mit 401:

{ "error": "Invalid or missing API credentials" }

Erstes Beispiel

curl https://deine-domain.ch/_/api/collections \
  -H "X-Orb-Token: orb_..." \
  -H "X-Orb-Secret: sk_..."

PHP-Client (zum Download)

Damit du nicht jeden Aufruf von Hand zusammenbaust, gibt es einen schlanken, abhängigkeitsfreien PHP-Client: die Klasse OrblioApiClient. Sie kümmert sich um Authentifizierung, JSON, Fehlerbehandlung, Timeouts, optionale Wiederholungen und Datei-Uploads — und bietet für jede Ressource fertige Methoden.

⬇  api.php herunterladen   Quelltext ansehen

VoraussetzungPHP 8.1+. cURL empfohlen (für Uploads nötig); ohne cURL nutzt der Client automatisch einen Stream-Fallback.
AbhängigkeitenKeine — eine einzige Datei, per require einbinden.
DateiIm Orblio-Paket unter tools/api.php enthalten.

Schnellstart

<?php
require_once __DIR__ . '/api.php';

/* Token, Secret und Domain — den Pfad /_/api hängt der Client selbst an */
$api = new OrblioApiClient('orb_...', 'sk_...', 'https://deine-domain.ch');

/* Seiten auflisten */
$pages = $api->listPages();

/* Datensatz in Sammlung 3 anlegen und die neue ID lesen */
$id = $api->createRecord(3, ['name' => 'Maria Muster', 'role' => 'Vorstand'])['id'];

Zugangsdaten lassen sich auch fluent oder über Umgebungsvariablen (ORBLIO_API_TOKEN, ORBLIO_API_SECRET) setzen:

$api = (new OrblioApiClient())
    ->setBaseUrl('https://deine-domain.ch')
    ->setCredentials('orb_...', 'sk_...')
    ->setTimeout(15)
    ->setMaxRetries(2);

Methoden im Überblick

Für jede Ressource gibt es benannte Methoden — alle geben das dekodierte JSON als Array zurück:

BereichMethoden
SammlungenlistCollections() · listRecords($cid[, $query]) · getRecord($cid, $rid) · createRecord($cid, $data) · replaceRecord(…) · updateRecord(…) · deleteRecord($cid, $rid)
SeitenlistPages() · getPage($id) · createPage($link, $data) · replacePage($id, $data[, $link]) · updatePage(…) · deletePage($id)
MedienlistMedia() · getMedia($fileId) · uploadMedia($pfad[, $folderId]) · updateMedia($fileId, $meta) · deleteMedia($fileId)
OrdnerlistFolders() · getFolder($id) · createFolder($name) · renameFolder($id, $name) · deleteFolder($id)
BenutzerlistUsers() · getUser($id) · createUser($email, $pass[, $role, $permissions, $pages, $active]) · updateUser($id, $data) · deleteUser($id)
Generischget() · post() · put() · patch() · delete() · options() · upload()
Diagnoseping() (true bei 200, false bei 401/403) · getLastStatus() · getLastRawBody() · getLastHeaders()

Konfiguration

setTimeout($s[,$c])Gesamt- und (optional) Verbindungs-Timeout in Sekunden.
setMaxRetries($n)Automatische Wiederholungen bei Transportfehlern und 5xx (exponentielles Backoff).
setAuthMode($m)AUTH_HEADERS (Standard), AUTH_BEARER oder AUTH_BOTH — Letztere für vorgelagerte Proxies/Gateways. Orblio selbst wertet nur Token/Secret aus.
setVerifySsl($b)TLS-Prüfung — nur für lokale Tests deaktivieren.
setHeader($n,$v)Zusätzlicher Header für alle Anfragen.

Fehlerbehandlung

Der Client wirft sprechende Exceptions statt stiller Fehlercodes:

ExceptionWann
OrblioTransportExceptionNetzwerk-/Transportfehler (DNS, TLS, Timeout).
OrblioApiExceptionHTTP-Status ≥ 400 oder ungültiges JSON. Bietet getStatusCode(), getResponse(), getRawBody().
OrblioExceptionGemeinsame Basisklasse — fängt beide ab.
try {
    $rec = $api->getRecord(3, 42);
} catch (OrblioApiException $e) {
    /* HTTP-Fehler von der API — z. B. 403 oder 404 */
    error_log($e->getStatusCode() . ': ' . $e->getMessage());
} catch (OrblioTransportException $e) {
    /* Server nicht erreichbar */
    error_log('Verbindung fehlgeschlagen: ' . $e->getMessage());
}

Datei hochladen

/* Lädt eine lokale Datei hoch (optional in einen Ordner) */
$file = $api->uploadMedia('/pfad/zu/bild.jpg', $folderId = null);
echo $file['url'];   /* öffentliche Adresse der Datei */

Erreichbarkeit prüfen

Mit $api->ping() testest du Zugangsdaten und Erreichbarkeit in einer Zeile: true heißt „verbunden“, false heißt „Zugangsdaten abgelehnt (401/403)“.

Endpunkte direkt ansprechen

Wer keinen PHP-Client nutzt (oder eine andere Sprache verwendet), spricht die Endpunkte direkt an. Die folgende Referenz beschreibt sie vollständig.

Konventionen

MethodeBedeutung
GETLesen (Liste oder einzelnes Objekt)
POSTNeu anlegen
PUTErsetzen (kompletter Datensatz)
PATCHZusammenführen (nur gelieferte Felder)
DELETELöschen (bei Inhalten „weich“)

Statuscodes: 200 OK · 201 Erstellt · 204 (OPTIONS) · 400 Fehlerhafte Anfrage · 401 Nicht authentifiziert · 403 Keine Berechtigung · 404 Nicht gefunden · 405 Methode nicht erlaubt · 500 Serverfehler.

Nutzdaten für Datensätze werden im Feld data übergeben. Kontrollspalten (cId, cParent, cDel, cDate) kann ein Client nie setzen — sie werden serverseitig entfernt.

Sammlungen

GET/_/api/collections

Listet alle Sammlungs-Definitionen (id, name, fields).

GET/_/api/collections/{cid}/records

Listet die Datensätze einer Sammlung.

POST/_/api/collections/{cid}/records

Legt einen Datensatz an. Body: { "data": { … } }. Antwort 201 mit id und data. Löst den Webhook collections.create aus.

curl -X POST https://deine-domain.ch/_/api/collections/3/records \
  -H "X-Orb-Token: orb_..." -H "X-Orb-Secret: sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "data": { "name": "Maria Muster", "role": "Vorstand" } }'
GET/_/api/collections/{cid}/records/{rid}

Liest einen einzelnen Datensatz (mit id, data, date, update).

PUTPATCH/_/api/collections/{cid}/records/{rid}

PUT ersetzt das data vollständig, PATCH führt es mit dem bestehenden zusammen. Löst collections.update aus.

DELETE/_/api/collections/{cid}/records/{rid}

Weiches Löschen (cDel = 1). Antwort { "id": …, "deleted": true }. Löst collections.delete aus.

Seiten

GET/_/api/pages

Listet alle Seiten (id, link, data).

POST/_/api/pages

Legt eine Seite an. Body: { "link": "neue-seite", "data": { … } }. Der Link wird bereinigt (nur a–z A–Z 0–9 _ - /). Fehlt content in data, wird es leer angelegt. Löst pages.create aus.

GETPUTPATCHDELETE/_/api/pages/{pid}

Lesen, ersetzen, zusammenführen oder löschen. Bei PUT/PATCH lässt sich optional der link mitändern. Auslösende Webhooks: pages.update, pages.delete.

Löschen von Seiten: weich oder hart

DELETE löscht eine Seite weich (Markierung pDel), sofern deine Installation diese Spalte führt. Fehlt sie, wird die Seite hart gelöscht — genau wie über die CMS-Oberfläche. Datensätze in Sammlungen werden dagegen immer weich gelöscht.

Medien

Medien-Endpunkte sind ordnerunabhängig: Lese- und Änderungszugriffe suchen die Datei über alle Ordner hinweg.

GET/_/api/media

Listet alle Dateien (über alle Ordner). Jede Datei liefert id, folder, name, title, description, type, url.

GET/_/api/media/{fileId}

Metadaten einer einzelnen Datei.

POST/_/api/media

Datei hochladen — als multipart/form-data mit dem Feld file (optional folder). Löst media.create aus.

curl -X POST https://deine-domain.ch/_/api/media \
  -H "X-Orb-Token: orb_..." -H "X-Orb-Secret: sk_..." \
  -F "file=@bild.jpg" -F "folder=root"
PUTPATCH/_/api/media/{fileId}

Metadaten ändern: title, description, credits, creator, name. Werte werden von HTML befreit. Löst media.update aus.

DELETE/_/api/media/{fileId}

Datei löschen. Löst media.delete aus.

Ordner

GET/_/api/folders

Listet Ordner (id, name, type, Anzahl files).

POST/_/api/folders

Ordner anlegen. Body: { "name": "…" }.

PUTPATCH/_/api/folders/{id}

Ordner umbenennen. Body: { "name": "…" }.

DELETE/_/api/folders/{id}

Ordner löschen. Nicht destruktiv: enthaltene Dateien wandern zurück ins Wurzelverzeichnis (Antwort enthält filesMovedToRoot).

Benutzer

GET/_/api/users

Listet Benutzer (id, email, role, active, permissions).

POST/_/api/users

Benutzer anlegen. Pflicht: email, password. Optional: role (admin, editor, viewer, api — Standard editor), pages, permissions, active. Ohne permissions werden rollenbasierte Standardrechte gesetzt. Löst users.create aus.

{
  "email": "redaktion@beispiel.ch",
  "password": "ein-sicheres-passwort",
  "role": "editor",
  "pages": ["4", "7"],
  "permissions": {
    "pages": { "scope": "list", "ids": [4, 7], "ops": ["read", "update"] }
  }
}
GETPUTPATCHDELETE/_/api/users/{id}

Lesen, ändern oder deaktivieren. DELETE ist ein weiches Löschen (Login wird gesperrt, haslogin = -1), passend zum CMS-Verhalten. Webhooks: users.update, users.delete.

Rechte gelten auch für die API

Ein 403 Forbidden bedeutet, dass der API-Zugang für diese Operation keine Berechtigung hat — nicht, dass der Endpunkt fehlt. Prüfe die granularen Rechte des Zugangs.

Fehlerformat

Fehler kommen immer als JSON mit einem error-Feld und passendem HTTP-Status:

{ "error": "Forbidden" }