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
/_/api/<resource>/… — die Endpunkte liegen unter /_/, damit sie nie mit einer Seite kollidieren.Content-Type: application/json).X-Orb-Token und X-Orb-Secret.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:
orb_<hex>. Dient dem Nachschlagen des Zugangs.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
cURL empfohlen (für Uploads nötig); ohne cURL nutzt der Client automatisch einen Stream-Fallback.require einbinden.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:
| Bereich | Methoden |
|---|---|
| Sammlungen | listCollections() · listRecords($cid[, $query]) · getRecord($cid, $rid) · createRecord($cid, $data) · replaceRecord(…) · updateRecord(…) · deleteRecord($cid, $rid) |
| Seiten | listPages() · getPage($id) · createPage($link, $data) · replacePage($id, $data[, $link]) · updatePage(…) · deletePage($id) |
| Medien | listMedia() · getMedia($fileId) · uploadMedia($pfad[, $folderId]) · updateMedia($fileId, $meta) · deleteMedia($fileId) |
| Ordner | listFolders() · getFolder($id) · createFolder($name) · renameFolder($id, $name) · deleteFolder($id) |
| Benutzer | listUsers() · getUser($id) · createUser($email, $pass[, $role, $permissions, $pages, $active]) · updateUser($id, $data) · deleteUser($id) |
| Generisch | get() · post() · put() · patch() · delete() · options() · upload() |
| Diagnose | ping() (true bei 200, false bei 401/403) · getLastStatus() · getLastRawBody() · getLastHeaders() |
Konfiguration
AUTH_HEADERS (Standard), AUTH_BEARER oder AUTH_BOTH — Letztere für vorgelagerte Proxies/Gateways. Orblio selbst wertet nur Token/Secret aus.Fehlerbehandlung
Der Client wirft sprechende Exceptions statt stiller Fehlercodes:
| Exception | Wann |
|---|---|
OrblioTransportException | Netzwerk-/Transportfehler (DNS, TLS, Timeout). |
OrblioApiException | HTTP-Status ≥ 400 oder ungültiges JSON. Bietet getStatusCode(), getResponse(), getRawBody(). |
OrblioException | Gemeinsame 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
| Methode | Bedeutung |
|---|---|
| GET | Lesen (Liste oder einzelnes Objekt) |
| POST | Neu anlegen |
| PUT | Ersetzen (kompletter Datensatz) |
| PATCH | Zusammenführen (nur gelieferte Felder) |
| DELETE | Lö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
Listet alle Sammlungs-Definitionen (id, name, fields).
Listet die Datensätze einer Sammlung.
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" } }'
Liest einen einzelnen Datensatz (mit id, data, date, update).
PUT ersetzt das data vollständig, PATCH führt es mit dem bestehenden zusammen. Löst collections.update aus.
Weiches Löschen (cDel = 1). Antwort { "id": …, "deleted": true }. Löst collections.delete aus.
Seiten
Listet alle Seiten (id, link, data).
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.
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.
Listet alle Dateien (über alle Ordner). Jede Datei liefert id, folder, name, title, description, type, url.
Metadaten einer einzelnen Datei.
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"
Metadaten ändern: title, description, credits, creator, name. Werte werden von HTML befreit. Löst media.update aus.
Datei löschen. Löst media.delete aus.
Ordner
Listet Ordner (id, name, type, Anzahl files).
Ordner anlegen. Body: { "name": "…" }.
Ordner umbenennen. Body: { "name": "…" }.
Ordner löschen. Nicht destruktiv: enthaltene Dateien wandern zurück ins Wurzelverzeichnis (Antwort enthält filesMovedToRoot).
Benutzer
Listet Benutzer (id, email, role, active, permissions).
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"] }
}
}
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" }