Appearance
Medien für das CMS (mit Token)
Diese Endpunkte sind für die „PIM-Mediathek“ im Kirby-Panel und für den Bild-Proxy der Website gedacht. Sie brauchen ein Token mit der Ability content:media:read.
| Methode | Pfad | Liefert |
|---|---|---|
GET | /content/media | Liste (JSON) |
GET | /content/media/{media} | Ein Medium (JSON) |
GET | /content/media/{media}/preview | Bilddatei zum Einbetten |
GET | /content/media/{media}/download | Originaldatei als Download |
GET | /content/media-folders | Freigegebene Ordner (JSON) |
Was ist sichtbar?
Anders als bei den öffentlichen Medien zählt hier nur der Ordner:
- Sichtbar sind Medien in Ordnern, die im PIM mit „Für Content-CMS freigeben“ markiert und aktiv sind, und in deren aktiven Unterordnern.
- Medien ohne Ordner sind nie sichtbar.
- Ausdrücklich gesperrte Medien liefert der Endpunkt nie: Freigabestatus „Nicht freigegeben“, „Rechte unklar“, „Abgelaufen“, ein überschrittenes „Gültig bis“ oder „Freigegeben für Kanäle“ ohne den Kanal Website. Alles andere, auch „In Prüfung“, ist nutzbar.
Ein Medium außerhalb dieser Ordner beantworten alle Endpunkte mit 404 not_found, auch wenn es existiert.
Felder eines CMS-Mediums
| Feld | Typ | Bedeutung |
|---|---|---|
id | Integer | Interne ID |
external_id | Integer | null | ID im Quellsystem Pimcore. Für Verweise ext:<external_id> verwenden |
name | String | Anzeigename |
file_name | String | Dateiname |
mime_type | String | MIME-Typ |
type | String | Asset-Typ (wie bei den öffentlichen Medien) |
size | Integer | Größe in Byte |
alt | String | null | Alt-Text in der Server-Sprache |
title | String | null | Titel in der Server-Sprache |
folder | Objekt | null | { id, name, slug } |
available | Boolean | true, wenn die Datei auf dem Server liegt |
preview_url | String | null | Absolute URL zu /content/media/{id}/preview. null, wenn available false ist |
download_url | String | null | Absolute URL zu /content/media/{id}/download. null, wenn available false ist |
created_at | Datum | Hochgeladen am |
Die URLs in preview_url und download_url brauchen ebenfalls das Token. Sie eignen sich deshalb nicht direkt für <img src> im Browser. Kirby und Nuxt leiten sie über einen eigenen, serverseitigen Proxy weiter.
Medien auflisten
GET /content/media
Neueste zuerst, seitenweise.
Query-Parameter
| Parameter | Typ | Bedeutung |
|---|---|---|
renderable | Boolean (1/0) | Nur Formate, die ein Browser direkt zeigt: JPEG, PNG, WebP, AVIF, GIF, SVG |
folder_id | Integer | Nur dieser Ordner (ohne Unterordner) |
external_id | Integer | Nur das Medium mit dieser Pimcore-ID |
search | String | Teiltreffer in Name oder Dateiname. Keine Synonyme |
page | Integer | Seite, Standard 1 |
per_page | Integer | Standard 24, mindestens 1, höchstens 100 |
Beispiel
bash
curl -sS 'https://admin.matev.eu/api/v1/content/media?renderable=1&search=schneepflug' \
-H 'Accept: application/json' \
-H "Authorization: Bearer $MATEV_TOKEN"js
// Serverseitig (z. B. Nitro-Route), nie im Browser.
const params = new URLSearchParams({ renderable: '1', search: 'schneepflug' })
const res = await fetch(`https://admin.matev.eu/api/v1/content/media?${params}`, {
headers: { Accept: 'application/json', Authorization: `Bearer ${process.env.CONTENT_API_TOKEN}` },
})
const { data, meta } = await res.json()php
use Illuminate\Support\Facades\Http;
$media = Http::acceptJson()
->withToken(config('services.matev.token'))
->get('https://admin.matev.eu/api/v1/content/media', ['renderable' => 1, 'search' => 'schneepflug'])
->throw()
->json('data');Antwort 200
json
{
"data": [
{
"id": 512,
"external_id": 4711,
"name": "SP 250 im Einsatz",
"file_name": "sp-250-einsatz.jpg",
"mime_type": "image/jpeg",
"type": "image",
"size": 2483112,
"alt": "Schneepflug SP 250 räumt einen Hof",
"title": "SP 250 im Einsatz",
"folder": { "id": 7, "name": "Winterdienst", "slug": "winterdienst" },
"available": true,
"preview_url": "https://admin.matev.eu/api/v1/content/media/512/preview",
"download_url": "https://admin.matev.eu/api/v1/content/media/512/download",
"created_at": "2026-02-11T09:14:00+00:00"
}
],
"links": { "first": "…", "last": "…", "prev": null, "next": "…" },
"meta": { "current_page": 1, "per_page": 24, "total": 180, "…": "…" }
}Fehler
| Status | code | Wann |
|---|---|---|
| 401 | unauthenticated | Token fehlt oder ist ungültig |
| 403 | forbidden | Token hat nicht content:media:read |
| 405 | method_not_allowed | andere Methode als GET |
Ein Medium abrufen
GET /content/media/{media}
Pfad-Parameter
| Parameter | Typ | Bedeutung |
|---|---|---|
media | Integer oder ext:<ID> | Interne ID oder Pimcore-ID mit Präfix, z. B. ext:4711 |
Beispiel
bash
curl -sS https://admin.matev.eu/api/v1/content/media/ext:4711 \
-H 'Accept: application/json' \
-H "Authorization: Bearer $MATEV_TOKEN"js
const res = await fetch('https://admin.matev.eu/api/v1/content/media/ext:4711', {
headers: { Accept: 'application/json', Authorization: `Bearer ${process.env.CONTENT_API_TOKEN}` },
})
const { data: asset } = await res.json()php
use Illuminate\Support\Facades\Http;
$asset = Http::acceptJson()
->withToken(config('services.matev.token'))
->get('https://admin.matev.eu/api/v1/content/media/ext:4711')
->throw()
->json('data');Antwort 200
json
{ "data": { "id": 512, "external_id": 4711, "name": "SP 250 im Einsatz", "available": true, "…": "wie in der Liste" } }Fehler
| Status | code | Wann |
|---|---|---|
| 401 | unauthenticated | Token fehlt oder ist ungültig |
| 403 | forbidden | Token hat nicht content:media:read |
| 404 | not_found | Unbekannt, oder nicht in einem freigegebenen Ordner |
Vorschau eines Mediums
GET /content/media/{media}/preview
Liefert die Bilddatei in einer gewünschten Größe zum Einbetten (Content-Disposition: inline). Kein JSON.
Parameter
| Parameter | Ort | Typ | Bedeutung |
|---|---|---|---|
media | Pfad | Integer oder ext:<ID> | Welches Medium |
format | Query | String | Bildformat, z. B. thumb, mini, tile, preview, hero oder ein weiteres aktives Format aus /image-formats. Standard: preview |
Verhalten:
- Gibt es das Format und ist es schon erzeugt, kommt diese Datei mit
Cache-Control: private, max-age=86400. - Ist das Format unbekannt oder noch nicht erzeugt, kommt die Originaldatei (kein Fehler), mit
Cache-Control: private, max-age=300. - Nur für Dateien, die ein Browser direkt zeigt (JPEG, PNG, WebP, AVIF, GIF, SVG). Für PDF, Video usw. antwortet der Endpunkt mit
404. Nehmen Sie dafür/download.
Beispiel
bash
curl -sS -o sp-250-tile.jpg \
'https://admin.matev.eu/api/v1/content/media/ext:4711/preview?format=tile' \
-H "Authorization: Bearer $MATEV_TOKEN"js
// Beispiel für einen serverseitigen Bild-Proxy: Token bleibt auf dem Server.
const upstream = await fetch(
'https://admin.matev.eu/api/v1/content/media/ext:4711/preview?format=tile',
{ headers: { Authorization: `Bearer ${process.env.CONTENT_API_TOKEN}` } },
)
if (!upstream.ok) {
// 404: Platzhalter ausliefern
}
const bytes = Buffer.from(await upstream.arrayBuffer())
const contentType = upstream.headers.get('content-type')php
use Illuminate\Support\Facades\Http;
$response = Http::withToken(config('services.matev.token'))
->get('https://admin.matev.eu/api/v1/content/media/ext:4711/preview', ['format' => 'tile']);
if ($response->successful()) {
return response($response->body(), 200, ['Content-Type' => $response->header('Content-Type')]);
}Antwort 200
Binärdaten mit Content-Type des Bildes, z. B. image/jpeg.
Fehler
Fehler kommen als JSON im üblichen Fehlerformat.
| Status | code | Wann |
|---|---|---|
| 401 | unauthenticated | Token fehlt oder ist ungültig |
| 403 | forbidden | Token hat nicht content:media:read |
| 404 | not_found | Unbekannt, nicht freigegeben, kein Browser-Bildformat, oder die Datei fehlt auf dem Server |
Download eines Mediums
GET /content/media/{media}/download
Liefert die Originaldatei als Anhang (Content-Disposition: attachment; filename="…") mit Cache-Control: private, max-age=300. Funktioniert für alle Dateitypen.
Pfad-Parameter
| Parameter | Typ | Bedeutung |
|---|---|---|
media | Integer oder ext:<ID> | Welches Medium |
Beispiel
bash
curl -sS -OJ https://admin.matev.eu/api/v1/content/media/ext:4711/download \
-H "Authorization: Bearer $MATEV_TOKEN"js
const res = await fetch('https://admin.matev.eu/api/v1/content/media/ext:4711/download', {
headers: { Authorization: `Bearer ${process.env.CONTENT_API_TOKEN}` },
})
const disposition = res.headers.get('content-disposition') // attachment; filename=…
const file = await res.arrayBuffer()php
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
$response = Http::withToken(config('services.matev.token'))
->get('https://admin.matev.eu/api/v1/content/media/ext:4711/download')
->throw();
Storage::put('downloads/sp-250.pdf', $response->body());Antwort 200
Binärdaten, Content-Type wie die Datei.
Fehler
| Status | code | Wann |
|---|---|---|
| 401 | unauthenticated | Token fehlt oder ist ungültig |
| 403 | forbidden | Token hat nicht content:media:read |
| 404 | not_found | Unbekannt, nicht freigegeben, oder Datei fehlt auf dem Server |
Freigegebene Ordner auflisten
GET /content/media-folders
Liefert alle für das CMS freigegebenen Ordner als flache Liste (kein children), sortiert nach Position und Name. Jeder Ordner hat asset_count (Zahl der Medien direkt darin) und einen vollständigen path. Nicht paginiert.
Beispiel
bash
curl -sS https://admin.matev.eu/api/v1/content/media-folders \
-H 'Accept: application/json' \
-H "Authorization: Bearer $MATEV_TOKEN"js
const res = await fetch('https://admin.matev.eu/api/v1/content/media-folders', {
headers: { Accept: 'application/json', Authorization: `Bearer ${process.env.CONTENT_API_TOKEN}` },
})
const { data: folders } = await res.json()php
use Illuminate\Support\Facades\Http;
$folders = Http::acceptJson()
->withToken(config('services.matev.token'))
->get('https://admin.matev.eu/api/v1/content/media-folders')
->throw()
->json('data');Antwort 200
json
{
"data": [
{ "id": 2, "name": "Website", "path": "Website", "slug": "website", "description": null, "parent_id": null, "position": 1, "asset_count": 12 },
{ "id": 9, "name": "Bühnenbilder", "path": "Website / Bühnenbilder", "slug": "buehnenbilder", "description": null, "parent_id": 2, "position": 1, "asset_count": 34 }
]
}Fehler
| Status | code | Wann |
|---|---|---|
| 401 | unauthenticated | Token fehlt oder ist ungültig |
| 403 | forbidden | Token hat nicht content:media:read |