Skip to content

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.

MethodePfadLiefert
GET/content/mediaListe (JSON)
GET/content/media/{media}Ein Medium (JSON)
GET/content/media/{media}/previewBilddatei zum Einbetten
GET/content/media/{media}/downloadOriginaldatei als Download
GET/content/media-foldersFreigegebene 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 ​

FeldTypBedeutung
idIntegerInterne ID
external_idInteger | nullID im Quellsystem Pimcore. Für Verweise ext:<external_id> verwenden
nameStringAnzeigename
file_nameStringDateiname
mime_typeStringMIME-Typ
typeStringAsset-Typ (wie bei den öffentlichen Medien)
sizeIntegerGröße in Byte
altString | nullAlt-Text in der Server-Sprache
titleString | nullTitel in der Server-Sprache
folderObjekt | null{ id, name, slug }
availableBooleantrue, wenn die Datei auf dem Server liegt
preview_urlString | nullAbsolute URL zu /content/media/{id}/preview. null, wenn available false ist
download_urlString | nullAbsolute URL zu /content/media/{id}/download. null, wenn available false ist
created_atDatumHochgeladen 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 ​

ParameterTypBedeutung
renderableBoolean (1/0)Nur Formate, die ein Browser direkt zeigt: JPEG, PNG, WebP, AVIF, GIF, SVG
folder_idIntegerNur dieser Ordner (ohne Unterordner)
external_idIntegerNur das Medium mit dieser Pimcore-ID
searchStringTeiltreffer in Name oder Dateiname. Keine Synonyme
pageIntegerSeite, Standard 1
per_pageIntegerStandard 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 ​

StatuscodeWann
401unauthenticatedToken fehlt oder ist ungültig
403forbiddenToken hat nicht content:media:read
405method_not_allowedandere Methode als GET

Ein Medium abrufen ​

GET /content/media/{media}

Pfad-Parameter ​

ParameterTypBedeutung
mediaInteger 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 ​

StatuscodeWann
401unauthenticatedToken fehlt oder ist ungültig
403forbiddenToken hat nicht content:media:read
404not_foundUnbekannt, 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 ​

ParameterOrtTypBedeutung
mediaPfadInteger oder ext:<ID>Welches Medium
formatQueryStringBildformat, 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.

StatuscodeWann
401unauthenticatedToken fehlt oder ist ungültig
403forbiddenToken hat nicht content:media:read
404not_foundUnbekannt, 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 ​

ParameterTypBedeutung
mediaInteger 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 ​

StatuscodeWann
401unauthenticatedToken fehlt oder ist ungültig
403forbiddenToken hat nicht content:media:read
404not_foundUnbekannt, 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 ​

StatuscodeWann
401unauthenticatedToken fehlt oder ist ungültig
403forbiddenToken hat nicht content:media:read