Appearance
Produkte
Produkte sind die Marketing-Einheiten des Katalogs (zum Beispiel ein Schneepflug-Typ). Sie bündeln Artikel, Bilder, Hersteller, Traktormodelle und Taxonomie-Terme.
Die API liefert nur aktive Produkte (is_active). Preise kommen nie mit.
| Methode | Pfad | Anmeldung |
|---|---|---|
GET | /products | keine |
GET | /products/{slug} | keine |
GET | /content/products | Token mit content:catalog:read |
GET | /content/products/{slug} | Token mit content:catalog:read |
Die /content/…-Varianten verwenden denselben Code und liefern exakt dieselben Daten. Es gibt sie, damit Kirby und der Nuxt-Server mit einem Token arbeiten können, das auf den Katalog beschränkt ist. Sie werden unten am Ende kurz gezeigt.
Felder eines Produkts
| Feld | Typ | Bedeutung |
|---|---|---|
id | Integer | Interne ID |
slug | String | Kennung für URLs, eindeutig |
objekttyp | String | null | produktgruppe, produkt oder modellvariante |
ordernumber | String | null | Produktnummer |
names | Objekt | Name je Sprache, z. B. { "de": "…", "en": "…" } |
descriptions | Objekt | Beschreibung je Sprache (kann HTML enthalten) |
product_page_url | String | null | Link auf die Produktseite der Website, wenn im PIM gepflegt |
features | Objekt | null | Technische Daten aus dem Feld-Template, Schlüssel → Wert. Inhalt hängt vom Template ab |
sale_start | Datum | null | Verkaufsstart |
end_of_life | Datum | null | Auslaufdatum |
primary_image | Medium | null | Erstes Bild aus images, sonst null |
images | Medium[] | Freigegebene Bilder, Hauptbild zuerst. Aufbau wie bei Medien |
articles_count | Integer | Zahl der aktiven Artikel |
taxons | Term[] | Zugeordnete Taxonomie-Terme mit taxonomy_slug |
articles | Artikel[] | Nur in der Detailansicht. Aktive Artikel ohne eigene Relationen |
manufacturers | Hersteller[] | Nur in der Detailansicht |
tractor_models | Traktormodell[] | Nur in der Detailansicht, ohne manufacturer/series |
created_at, updated_at | Datum | Zeitstempel |
Woher kommen die Bilder? Zuerst aus den Verknüpfungen mit der Mediathek (Rolle „Bild“), sortiert nach Hauptbild und Position, und nur, wenn sie öffentlich freigegeben sind. Nur wenn es davon keine gibt, nimmt die API die direkt am Produkt hochgeladenen Bilder. Bilder aus Verknüpfungen haben zusätzlich die Felder usages (wofür das Bild gedacht ist, z. B. ["website", "catalog"]) und folder.
Das Feld texts (Texte je Ausgabestelle) steht zwar in der Resource-Klasse, wird aber von keinem Endpunkt geladen und kommt deshalb nie mit.
Produkte auflisten
GET /products
Liefert alle aktiven Produkte, sortiert nach ordernumber, seitenweise.
Query-Parameter
| Parameter | Typ | Bedeutung |
|---|---|---|
taxons | String oder String[] | Filter nach Taxonomie-Termen, siehe unten |
manufacturer | String | Slug eines Herstellers, z. B. john-deere |
ids | Integer[] | Nur diese Produkt-IDs: ids[]=3&ids[]=9 |
search | String | Katalogsuche in ordernumber, names (alle Sprachen), slug, Schlagwörtern und Synonymen |
page | Integer | Seite, Standard 1 |
per_page | Integer | Einträge pro Seite, Standard 15, höchstens 100 |
Optionaler Header: X-Search-Session fasst Suchen einer Sitzung für die Suchanalyse zusammen.
Taxonomie-Filter
taxons filtert nach Termen aus der PIM-Taxonomie. Ein Eintrag hat die Form dimension:slug, also Taxonomie-Slug und Term-Slug, z. B. anwendungsbereich:gruenpflege.
- Gleiche Dimension = ODER.
produktkategorie:schneepfluege,produktkategorie:kehrmaschinenliefert Produkte aus beiden Kategorien. - Verschiedene Dimensionen = UND.
produktkategorie:schneepfluege,leistungsklasse:bis-100-psliefert nur Schneepflüge in dieser Leistungsklasse. - Unterbegriffe zählen mit. Wer eine Oberkategorie wählt, bekommt auch die Produkte der Unterkategorien.
- Ohne Dimension (
taxons=gruenpflege) heißt „irgendein Term mit diesem Slug“, egal in welcher Taxonomie. Das ist erlaubt, aber unscharf: rund 90 Slugs gibt es in mehreren Taxonomien. Geben Sie die Dimension immer mit an. - Unbekannte Einträge werden ignoriert. Ein veralteter Link zeigt dann den ganzen Katalog statt einer leeren Liste.
Drei Schreibweisen funktionieren gleich:
text
?taxons=produktkategorie:schneepfluege,leistungsklasse:bis-100-ps
?taxons[]=produktkategorie:schneepfluege&taxons[]=leistungsklasse:bis-100-ps
?taxons=produktkategorie:schneepfluegeNicht so
?taxons=a&taxons=b (derselbe Schlüssel zweimal ohne []) kommt bei PHP nur als b an. Manche HTTP-Bibliotheken (z. B. ofetch/ufo) erzeugen genau das, wenn man ein Array übergibt. Nehmen Sie die Komma-Form.
Welche Dimensionen und Slugs es gibt, liefert GET /taxonomies.
Beispiel
bash
curl -sS 'https://admin.matev.eu/api/v1/products?taxons=produktkategorie:schneepfluege&per_page=12' \
-H 'Accept: application/json'js
const params = new URLSearchParams({
taxons: ['produktkategorie:schneepfluege'].join(','),
per_page: '12',
})
const res = await fetch(`https://admin.matev.eu/api/v1/products?${params}`, {
headers: { Accept: 'application/json' },
})
if (!res.ok) throw new Error((await res.json()).error?.code)
const { data, meta } = await res.json()php
use Illuminate\Support\Facades\Http;
$response = Http::acceptJson()
->get('https://admin.matev.eu/api/v1/products', [
'taxons' => 'produktkategorie:schneepfluege',
'per_page' => 12,
])
->throw();
$products = $response->json('data');
$total = $response->json('meta.total');Antwort 200
json
{
"data": [
{
"id": 41,
"slug": "schneepflug-sp-250",
"objekttyp": "produkt",
"ordernumber": "SP-250",
"names": { "de": "Schneepflug SP 250", "en": "Snow plough SP 250", "fr": "Chasse-neige SP 250" },
"descriptions": { "de": "<p>Robuster Schneepflug für Kompakttraktoren.</p>", "en": "<p>Sturdy snow plough for compact tractors.</p>" },
"product_page_url": "https://www.example.test/produkte/winterdienst/schneepflug-sp-250",
"features": { "arbeitsbreite_cm": "250", "gewicht_kg": "320" },
"sale_start": "2024-01-01T00:00:00+00:00",
"end_of_life": null,
"primary_image": {
"id": 512,
"name": "SP 250 im Einsatz",
"file_name": "sp-250-einsatz.jpg",
"mime_type": "image/jpeg",
"type": "image",
"usages": ["website"],
"size": 2483112,
"url": "https://admin.matev.eu/storage/media/512/sp-250-einsatz.jpg",
"thumb_url": "https://admin.matev.eu/storage/media/512/conversions/sp-250-einsatz-thumb.jpg",
"conversions": {
"thumb": { "url": "https://admin.matev.eu/storage/media/512/conversions/sp-250-einsatz-thumb.jpg", "width": 300, "height": 300, "fit": "crop" },
"preview": { "url": "https://admin.matev.eu/storage/media/512/conversions/sp-250-einsatz-preview.jpg", "width": 800, "height": 800, "fit": "max" }
},
"srcset": "https://admin.matev.eu/storage/media/512/conversions/sp-250-einsatz-thumb.jpg 300w, https://admin.matev.eu/storage/media/512/conversions/sp-250-einsatz-preview.jpg 800w",
"alt": "Schneepflug SP 250 räumt einen Hof",
"title": "SP 250 im Einsatz",
"caption": null,
"description": null,
"copyright": "matev GmbH",
"license": null,
"ki_status": "kein_ki",
"ki_label": "Kein KI",
"folder": { "id": 7, "name": "Winterdienst", "slug": "winterdienst" },
"created_at": "2026-02-11T09:14:00+00:00"
},
"images": [ { "id": 512, "…": "wie primary_image" } ],
"articles_count": 6,
"taxons": [
{
"id": 88,
"taxonomy_id": 3,
"taxonomy_slug": "produktkategorie",
"parent_id": 80,
"slug": "schneepfluege",
"names": "Schneepflüge",
"position": 2
}
],
"created_at": "2026-01-15T10:30:00+00:00",
"updated_at": "2026-09-30T14:22:00+00:00"
}
],
"links": { "first": "…?page=1", "last": "…?page=3", "prev": null, "next": "…?page=2" },
"meta": { "current_page": 1, "from": 1, "last_page": 3, "path": "https://admin.matev.eu/api/v1/products", "per_page": 12, "to": 12, "total": 31, "links": [] }
}names bei Termen ist in dieser Version ein einfacher Text in der Server-Sprache (siehe Sprachen).
Fehler
| Status | code | Wann |
|---|---|---|
| 405 | method_not_allowed | andere Methode als GET |
| 500 | server_error | Fehler auf dem Server |
Ungültige Filterwerte führen nicht zu einem Fehler, sie werden ignoriert.
Ein Produkt abrufen
GET /products/{slug}
Liefert ein aktives Produkt mit allen Details: zusätzlich articles, manufacturers und tractor_models.
Pfad-Parameter
| Parameter | Typ | Bedeutung |
|---|---|---|
slug | String | Slug des Produkts |
Beispiel
bash
curl -sS https://admin.matev.eu/api/v1/products/schneepflug-sp-250 \
-H 'Accept: application/json'js
const res = await fetch('https://admin.matev.eu/api/v1/products/schneepflug-sp-250', {
headers: { Accept: 'application/json' },
})
if (res.status === 404) {
// Produkt gibt es nicht oder es ist inaktiv
}
const { data: product } = await res.json()php
use Illuminate\Support\Facades\Http;
$response = Http::acceptJson()->get('https://admin.matev.eu/api/v1/products/schneepflug-sp-250');
if ($response->notFound()) {
abort(404);
}
$product = $response->throw()->json('data');Antwort 200
json
{
"data": {
"id": 41,
"slug": "schneepflug-sp-250",
"objekttyp": "produkt",
"ordernumber": "SP-250",
"names": { "de": "Schneepflug SP 250", "en": "Snow plough SP 250" },
"descriptions": { "de": "<p>Robuster Schneepflug für Kompakttraktoren.</p>" },
"product_page_url": null,
"features": { "arbeitsbreite_cm": "250" },
"sale_start": "2024-01-01T00:00:00+00:00",
"end_of_life": null,
"primary_image": { "id": 512, "…": "siehe Liste" },
"images": [ { "id": 512, "…": "siehe Liste" } ],
"articles_count": 2,
"articles": [
{
"id": 1201,
"type": "main",
"type_code": "131",
"ordernumber": "131 7810",
"names": { "de": "Schneepflug SP 250 Grundgerät" },
"short_names": { "de": "SP 250" },
"descriptions": { "de": "" },
"weight": "320.000",
"customs_tariff_number": "84303100",
"sale_start": null,
"end_of_life": null
},
{
"id": 1388,
"type": "spare",
"type_code": "130",
"ordernumber": "130 2214",
"names": { "de": "Räumleiste Gummi 250 cm" },
"short_names": { "de": "" },
"descriptions": { "de": "" },
"weight": "12.500",
"customs_tariff_number": null,
"sale_start": null,
"end_of_life": "2025-12-31T00:00:00+00:00"
}
],
"manufacturers": [
{ "id": 4, "slug": "john-deere", "short_name": "JD", "names": { "de": "John Deere" } }
],
"tractor_models": [
{ "id": 230, "identifier": "JD-3038E", "model": "3038E", "type_of_tractor": "Kompakttraktor", "manufacturer_id": 4, "tractor_series_id": 17 }
],
"taxons": [
{ "id": 88, "taxonomy_id": 3, "taxonomy_slug": "produktkategorie", "parent_id": 80, "slug": "schneepfluege", "names": "Schneepflüge", "position": 2 }
],
"created_at": "2026-01-15T10:30:00+00:00",
"updated_at": "2026-09-30T14:22:00+00:00"
}
}Fehler
| Status | code | Wann |
|---|---|---|
| 404 | not_found | Kein Produkt mit diesem Slug, oder es ist inaktiv |
| 405 | method_not_allowed | andere Methode als GET |
| 500 | server_error | Fehler auf dem Server |
Mit Token: /content/products
GET /content/products und GET /content/products/{slug} verhalten sich genau wie die öffentlichen Endpunkte oben (gleiche Parameter, gleiche Antwort). Sie brauchen ein Token mit der Ability content:catalog:read.
bash
curl -sS 'https://admin.matev.eu/api/v1/content/products?search=Schneepflug' \
-H 'Accept: application/json' \
-H "Authorization: Bearer $MATEV_TOKEN"
curl -sS https://admin.matev.eu/api/v1/content/products/schneepflug-sp-250 \
-H 'Accept: application/json' \
-H "Authorization: Bearer $MATEV_TOKEN"js
// Nur serverseitig (Node/Nitro), nie im Browser: das Token ist geheim.
const headers = {
Accept: 'application/json',
Authorization: `Bearer ${process.env.CONTENT_API_TOKEN}`,
}
const list = await fetch('https://admin.matev.eu/api/v1/content/products?search=Schneepflug', { headers })
const one = await fetch('https://admin.matev.eu/api/v1/content/products/schneepflug-sp-250', { headers })php
use Illuminate\Support\Facades\Http;
$api = Http::baseUrl('https://admin.matev.eu/api/v1')
->acceptJson()
->withToken(config('services.matev.token'));
$list = $api->get('/content/products', ['search' => 'Schneepflug'])->throw()->json('data');
$product = $api->get('/content/products/schneepflug-sp-250')->throw()->json('data');Antwort: wie oben.
Zusätzliche Fehler
| Status | code | Wann |
|---|---|---|
| 401 | unauthenticated | Token fehlt oder ist ungültig |
| 403 | forbidden | Token hat nicht content:catalog:read |