Delivery-API
Öffentliche Lese-API der Inhaltsverwaltung: Endpoints, Authentifizierung, Filter, populate, Pagination und Fehlercodes.
Basis-URL
Die Delivery-API liefert publizierte Inhalte an Ihr Frontend aus. Basis-Pfad:
https://<slug>.scorebase.ch/headless/api/v1
<slug> ist die Subdomain Ihrer Organisation. HCMS_URL akzeptiert sowohl .../headless als auch .../headless/api/v1.
Authentifizierung
Alle Lese-Endpunkte erwarten einen Bearer-Token mit read-Scope:
Authorization: Bearer hcms_live_xxx
Ausnahmen ohne Bearer-Token:
GET /media/{id}/transformist vollständig öffentlich.POST /analytics/pageview,POST /analytics/eventundPOST /forms/{key}/submitakzeptieren alternativ den öffentlichen Parameter?site=<tokenPrefix>.
Endpoints
| Methode | Pfad | Zweck |
|---|---|---|
| GET | /collections |
Sammlungen auflisten |
| GET | /collections/{slug}/entries |
Einträge einer Sammlung |
| GET | /collections/{slug}/entries/count |
Anzahl Einträge |
| GET | /collections/{slug}/entries/{id} |
Einzelner Eintrag |
| GET | /pages |
Seiten auflisten |
| GET | /pages/by-path |
Seite nach Pfad (mit aufgelösten Blöcken) |
| GET | /menus / /menus/{key} |
Menüs |
| GET | /theme |
Theme/Design-Tokens |
| GET | /blocks |
Block-Palette |
| GET | /search |
Volltextsuche (q erforderlich) |
| GET | /media / /media/{id}/transform |
Medien / Bild-Transform |
| GET | /settings |
Analytics-/Tracking-Konfiguration |
| POST | /graphql |
GraphQL-Delivery (read-only; GET liefert GraphiQL) |
| POST | /analytics/pageview / /analytics/event |
Ereignis-Ingest |
| GET/POST | /forms/{key} / /forms/{key}/submit |
Formulare |
Webshop und Buchungen stehen nicht mehr in dieser Tabelle. Der CMS-eigene Webshop (
/shop/*) und das CMS-eigene Buchungssystem (/bookings/*) sind am 22. September 2026 entfallen. Katalog und Kasse liegen in der E-Commerce-App, Buchungsstrecken und Belegung in der Termine-App — mit eigenen öffentlichen Endpunkten. Siehe „Webshop und Buchungen im Frontend anbinden".
Öffentliche Interaktions-Endpunkte: Die Submit- und Ingest-Endpunkte akzeptieren neben dem Bearer-Token den nicht geheimen Parameter
?site=<tokenPrefix>und sind honeypot- und IP-ratenlimitiert.
Query-Parameter (Einträge)
| Parameter | Standard | Beschreibung |
|---|---|---|
status |
published |
draft erfordert Vorschau-Token/Scope |
locale |
de |
Sprache |
environment |
– | Environment-Key (wird bei env-gebundenem Token ignoriert) |
sort |
createdAt |
Sortierfeld (createdAt, updatedAt, publishedAt, slug, status oder ein data-Feld) |
order |
desc |
asc oder desc |
page |
1 |
Seite (1-basiert) |
limit |
20 |
max. 100 |
populate |
– | Relationen als kommagetrennte Pfade, max. Tiefe 3 |
fields |
– | Projektion des data-Objekts |
q |
– | Volltextsuche |
filter |
– | JSON-Filter (URL-kodiert) |
Filter
Kurzschreibweise (ein data-Feld je Parameter, Operator in Klammern, ohne Klammer = eq):
?price[gte]=10&price[lt]=100&tag[in]=a,b,c
Operatoren: eq, neq, gt, gte, lt, lte, contains, startsWith, in. Mehrere Filter werden mit UND verknüpft.
JSON-Filter (filter=, URL-kodiert): Operatoren $eq, $ne, $gt, $gte, $lt, $lte, $contains, $startsWith, $in, $notIn, $null sowie Gruppierung mit $and/$or (max. Tiefe 3, max. 50 Bedingungen).
Antwortformat
Erfolg – Daten unter data, Pagination unter meta:
{
"data": [ /* ... */ ],
"meta": { "page": 1, "limit": 20, "total": 137 }
}Fehler – strukturiert unter error:
{ "error": { "code": "BAD_REQUEST", "message": "..." } }Fehlercodes
| Status | Code | Auslöser |
|---|---|---|
| 400 | BAD_REQUEST |
Ungültige Parameter, populate-Tiefe > 3, unbekanntes Filterfeld |
| 401 | UNAUTHORIZED |
Kein/ungültiger Token oder ungültiger ?site= |
| 401 | TOKEN_INACTIVE / TOKEN_EXPIRED |
Token widerrufen / abgelaufen |
| 403 | FORBIDDEN |
Fehlender Scope oder Sammlung nicht im Token-Scope |
| 404 | NOT_FOUND |
Ressource nicht gefunden |
| 404 | UNKNOWN_ENVIRONMENT |
?environment= unbekannt |
| 422 | VALIDATION_ERROR |
Validierungsfehler (z.B. Formular-Submit) |
| 429 | RATE_LIMIT_EXCEEDED |
Ratenlimit überschritten (Header Retry-After) |
| 500 | INTERNAL_ERROR |
Serverfehler |
Seiten und Vorschau
GET /pages/by-path löst datengetriebene Blöcke standardmässig serverseitig auf (Default resolve=data, nicht opt-in). Die aufgelösten Einträge landen additiv unter blocks[].resolved; das rohe data bleibt unverändert. Aufgelöste Antworten cachen mit s-maxage=60 + stale-while-revalidate und liefern die referenzierten Collection-Slugs als meta.collectionTags. Zum Abschalten hängen Sie resolve=none an – dann kommen die rohen Blöcke zurück (voll ETag-cachebar). Der Vorschau-Modus nutzt einen eintragsgebundenen previewToken (HMAC, 60 Minuten) und erzwingt no-store.
Tipp: Im Frontend-Starter kapselt
cms/client.tsdiese API. Nutzen Sie den typisierten SDK-Client statt roherfetch-Aufrufe – so bleiben Filter, populate und Typen konsistent.