cms.c2sgmbh/docs/anleitungen/API_ANLEITUNG.md
Martin Porwoll 49d317fc84 docs: update anleitungen with BlogWoman features and fixes
API_ANLEITUNG.md:
- Fix rate limiting section (was incorrectly stated as not implemented)
- Add comprehensive rate limit documentation with limits table
- Expand collections overview from 13 to 42+ collections
- Add BlogWoman APIs (Favorites, Series)

FRONTEND.md:
- Fix Globals section (SiteSettings/Navigations are now Collections)
- Add Favorites and Series APIs
- Update date

UNIVERSAL_FEATURES.md:
- Add Favorites Collection (affiliate products)
- Add Series Collection (YouTube series)
- Add 5 new BlogWoman blocks documentation
- Update files overview and multi-tenant config
- Add version 1.3 changelog entry

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 15:05:23 +00:00

26 KiB

API-Anleitung - Payload CMS

Übersicht

Das Payload CMS stellt eine REST-API und eine GraphQL-API bereit. Diese Anleitung beschreibt die Nutzung der REST-API für alle Collections.

Base URL: https://pl.porwoll.tech/api


Authentifizierung

Login

curl -X POST "https://pl.porwoll.tech/api/users/login" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@example.com",
    "password": "your-password"
  }'

Response:

{
  "message": "Auth Passed",
  "user": {
    "id": 1,
    "email": "admin@example.com",
    "isSuperAdmin": true,
    "tenants": [...]
  },
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

Token verwenden

curl "https://pl.porwoll.tech/api/posts" \
  -H "Authorization: JWT eyJhbGciOiJIUzI1NiIs..."

Mehrsprachigkeit (Localization)

Das CMS unterstützt Deutsch (de) und Englisch (en). Lokalisierte Felder können über den locale Parameter abgerufen werden.

# Deutsche Inhalte (Standard)
curl "https://pl.porwoll.tech/api/posts?locale=de"

# Englische Inhalte
curl "https://pl.porwoll.tech/api/posts?locale=en"

# Alle Sprachen gleichzeitig
curl "https://pl.porwoll.tech/api/posts?locale=all"

Users API

Aktuellen User abrufen

curl "https://pl.porwoll.tech/api/users/me" \
  -H "Authorization: JWT your-token"

User-Felder

Feld Typ Beschreibung
email string E-Mail-Adresse (eindeutig)
isSuperAdmin boolean Super Admin hat Zugriff auf alle Tenants
tenants array Zugewiesene Tenants

Tenants API

Alle Tenants abrufen (Auth + SuperAdmin erforderlich)

curl "https://pl.porwoll.tech/api/tenants" \
  -H "Authorization: JWT your-token"

Tenant erstellen (Auth + SuperAdmin erforderlich)

curl -X POST "https://pl.porwoll.tech/api/tenants" \
  -H "Authorization: JWT your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Meine Firma GmbH",
    "slug": "meine-firma",
    "domains": [
      { "domain": "meine-firma.de" },
      { "domain": "www.meine-firma.de" }
    ]
  }'

Tenant-Felder

Feld Typ Beschreibung
name string Anzeigename des Tenants
slug string URL-freundlicher Identifier (eindeutig)
domains array Zugeordnete Domains

Posts API

Alle Posts abrufen

# Alle Posts
curl "https://pl.porwoll.tech/api/posts"

# Nur Blog-Artikel
curl "https://pl.porwoll.tech/api/posts?where[type][equals]=blog"

# Nur News
curl "https://pl.porwoll.tech/api/posts?where[type][equals]=news"

# Nur veröffentlichte Posts
curl "https://pl.porwoll.tech/api/posts?where[status][equals]=published"

# Nur hervorgehobene Posts
curl "https://pl.porwoll.tech/api/posts?where[isFeatured][equals]=true"

# Mit Sortierung (neueste zuerst)
curl "https://pl.porwoll.tech/api/posts?sort=-publishedAt"

# Limitiert auf 10 Einträge
curl "https://pl.porwoll.tech/api/posts?limit=10"

# Pagination (Seite 2)
curl "https://pl.porwoll.tech/api/posts?limit=10&page=2"

# Mit Locale
curl "https://pl.porwoll.tech/api/posts?locale=de"

Einzelnen Post abrufen

# Nach ID
curl "https://pl.porwoll.tech/api/posts/1"

# Nach Slug (über Query)
curl "https://pl.porwoll.tech/api/posts?where[slug][equals]=mein-erster-artikel"

Post erstellen (Auth erforderlich)

curl -X POST "https://pl.porwoll.tech/api/posts" \
  -H "Authorization: JWT your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant": 1,
    "title": "Mein neuer Artikel",
    "slug": "mein-neuer-artikel",
    "type": "blog",
    "isFeatured": false,
    "excerpt": "Eine kurze Zusammenfassung des Artikels...",
    "content": {
      "root": {
        "type": "root",
        "children": [
          {
            "type": "paragraph",
            "children": [{ "text": "Der Artikelinhalt..." }]
          }
        ]
      }
    },
    "status": "draft"
  }'

Post aktualisieren (Auth erforderlich)

curl -X PATCH "https://pl.porwoll.tech/api/posts/1" \
  -H "Authorization: JWT your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "published",
    "publishedAt": "2025-11-30T12:00:00.000Z"
  }'

Post löschen (Auth erforderlich)

curl -X DELETE "https://pl.porwoll.tech/api/posts/1" \
  -H "Authorization: JWT your-token"

Testimonials API

Alle Testimonials abrufen

# Alle Testimonials
curl "https://pl.porwoll.tech/api/testimonials"

# Nur aktive Testimonials
curl "https://pl.porwoll.tech/api/testimonials?where[isActive][equals]=true"

# Sortiert nach Bewertung (beste zuerst)
curl "https://pl.porwoll.tech/api/testimonials?sort=-rating"

# Sortiert nach eigener Reihenfolge
curl "https://pl.porwoll.tech/api/testimonials?sort=order"

Testimonial erstellen (Auth erforderlich)

curl -X POST "https://pl.porwoll.tech/api/testimonials" \
  -H "Authorization: JWT your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant": 1,
    "quote": "Hervorragender Service! Ich bin sehr zufrieden.",
    "author": "Max Mustermann",
    "role": "Geschäftsführer",
    "company": "Musterfirma GmbH",
    "rating": 5,
    "source": "Google Reviews",
    "isActive": true,
    "order": 1
  }'

Newsletter Subscribers API

Newsletter-Anmeldung (Öffentlich)

# Einfache Anmeldung
curl -X POST "https://pl.porwoll.tech/api/newsletter-subscribers" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant": 1,
    "email": "kunde@example.com",
    "source": "website-footer"
  }'

# Mit Namen und Interessen
curl -X POST "https://pl.porwoll.tech/api/newsletter-subscribers" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant": 1,
    "email": "kunde@example.com",
    "firstName": "Max",
    "lastName": "Mustermann",
    "interests": ["blog", "products"],
    "source": "blog-sidebar"
  }'

Response (Erfolg):

{
  "doc": {
    "id": 1,
    "tenant": 1,
    "email": "kunde@example.com",
    "status": "pending",
    "confirmationToken": "uuid-token-here",
    "subscribedAt": "2025-11-30T14:23:41.012Z"
  },
  "message": "Newsletter Subscriber successfully created."
}

Subscribers abrufen (Auth erforderlich)

# Alle Subscribers
curl "https://pl.porwoll.tech/api/newsletter-subscribers" \
  -H "Authorization: JWT your-token"

# Nur bestätigte Subscribers
curl "https://pl.porwoll.tech/api/newsletter-subscribers?where[status][equals]=confirmed" \
  -H "Authorization: JWT your-token"

# Nach E-Mail suchen
curl "https://pl.porwoll.tech/api/newsletter-subscribers?where[email][equals]=kunde@example.com" \
  -H "Authorization: JWT your-token"

Subscriber bestätigen (Double Opt-In)

# Über Token bestätigen
curl -X PATCH "https://pl.porwoll.tech/api/newsletter-subscribers/1" \
  -H "Authorization: JWT your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "confirmed"
  }'

Subscriber abmelden

curl -X PATCH "https://pl.porwoll.tech/api/newsletter-subscribers/1" \
  -H "Authorization: JWT your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "unsubscribed"
  }'

Pages API

Seiten abrufen

# Alle Seiten
curl "https://pl.porwoll.tech/api/pages"

# Seite nach Slug
curl "https://pl.porwoll.tech/api/pages?where[slug][equals]=startseite"

# Nur veröffentlichte Seiten
curl "https://pl.porwoll.tech/api/pages?where[status][equals]=published"

# Mit Locale
curl "https://pl.porwoll.tech/api/pages?locale=de&depth=2"

Seite mit Blocks

Die Blocks werden im layout-Array zurückgegeben:

{
  "docs": [{
    "id": 1,
    "title": "Startseite",
    "slug": "startseite",
    "layout": [
      {
        "blockType": "hero-block",
        "title": "Willkommen",
        "subtitle": "..."
      },
      {
        "blockType": "posts-list-block",
        "title": "Aktuelle News",
        "postType": "news",
        "limit": 3
      },
      {
        "blockType": "testimonials-block",
        "title": "Das sagen unsere Kunden",
        "layout": "slider"
      }
    ]
  }]
}

Die Cookie-Konfiguration wird automatisch nach Domain gefiltert.

# Für Frontend Cookie-Banner
curl "https://pl.porwoll.tech/api/cookie-configurations?where[tenant][equals]=1"

Response:

{
  "docs": [{
    "id": 1,
    "tenant": 1,
    "title": "Cookie-Einstellungen",
    "revision": 1,
    "enabledCategories": ["necessary", "analytics"],
    "translations": {
      "de": {
        "bannerTitle": "Wir respektieren Ihre Privatsphäre",
        "bannerDescription": "Diese Website verwendet Cookies...",
        "acceptAllButton": "Alle akzeptieren",
        "acceptNecessaryButton": "Nur notwendige",
        "settingsButton": "Einstellungen",
        "saveButton": "Auswahl speichern",
        "privacyPolicyUrl": "/datenschutz",
        "categoryLabels": {
          "necessary": { "title": "Notwendig", "description": "..." },
          "functional": { "title": "Funktional", "description": "..." },
          "analytics": { "title": "Statistik", "description": "..." },
          "marketing": { "title": "Marketing", "description": "..." }
        }
      }
    },
    "styling": {
      "position": "bottom",
      "theme": "dark"
    }
  }]
}

Dokumentation aller verwendeten Cookies für die Datenschutzerklärung.

# Alle Cookies eines Tenants
curl "https://pl.porwoll.tech/api/cookie-inventory?where[tenant][equals]=1"

# Nur aktive Cookies
curl "https://pl.porwoll.tech/api/cookie-inventory?where[tenant][equals]=1&where[isActive][equals]=true"

# Nach Kategorie filtern
curl "https://pl.porwoll.tech/api/cookie-inventory?where[tenant][equals]=1&where[category][equals]=analytics"

Response:

{
  "docs": [{
    "id": 1,
    "tenant": 1,
    "name": "_ga",
    "provider": "Google LLC",
    "category": "analytics",
    "duration": "2 Jahre",
    "description": "Wird verwendet, um Benutzer zu unterscheiden.",
    "isActive": true
  }]
}
Feld Typ Beschreibung
name string Technischer Cookie-Name (z.B. "_ga")
provider string Anbieter (z.B. "Google LLC")
category enum necessary, functional, analytics, marketing
duration string Speicherdauer (z.B. "2 Jahre")
description string Beschreibung für Endnutzer
isActive boolean Cookie aktiv?

Consent-Logs sind ein WORM (Write-Once-Read-Many) Audit-Trail für DSGVO-Nachweise.

curl -X POST "https://pl.porwoll.tech/api/consent-logs" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-consent-api-key" \
  -d '{
    "tenant": 1,
    "clientRef": "uuid-from-cookie",
    "categories": {
      "necessary": true,
      "functional": false,
      "analytics": true,
      "marketing": false
    },
    "revision": 1,
    "userAgent": "Mozilla/5.0..."
  }'

Response:

{
  "doc": {
    "id": 1,
    "consentId": "550e8400-e29b-41d4-a716-446655440000",
    "tenant": 1,
    "clientRef": "uuid-from-cookie",
    "categories": { "necessary": true, "analytics": true, ... },
    "revision": 1,
    "anonymizedIp": "a1b2c3d4e5f6...",
    "expiresAt": "2028-12-02T00:00:00.000Z",
    "createdAt": "2025-12-02T10:00:00.000Z"
  }
}

Wichtig:

  • CREATE: Nur mit gültigem X-API-Key Header
  • READ: Nur authentifizierte Admin-User
  • UPDATE: Nicht erlaubt (WORM-Prinzip)
  • DELETE: Nicht erlaubt (nur via Retention-Job)
Feld Typ Beschreibung
consentId string Server-generierte UUID (read-only)
clientRef string Client-Cookie-Referenz für Traceability
tenant relation Zugehöriger Tenant
categories json Akzeptierte Kategorien
revision number Konfigurationsversion zum Zeitpunkt der Zustimmung
userAgent string Browser-Information
anonymizedIp string HMAC-Hash der IP (täglich rotierend)
expiresAt date Automatische Löschung nach 3 Jahren

Privacy Policy Settings abrufen (Öffentlich, Tenant-isoliert)

Konfiguration für die Datenschutzerklärungs-Seite (z.B. Alfright Integration).

curl "https://pl.porwoll.tech/api/privacy-policy-settings?where[tenant][equals]=1"

Response:

{
  "docs": [{
    "id": 1,
    "tenant": 1,
    "title": "Datenschutzerklärung",
    "provider": "alfright",
    "alfright": {
      "tenantId": "alfright_schutzteam",
      "apiKey": "9f315103c43245bcb0806dd56c2be757",
      "language": "de-de",
      "iframeHeight": 4000
    },
    "styling": {
      "headerColor": "#ca8a04",
      "backgroundColor": "#111827",
      ...
    },
    "showCookieTable": true,
    "cookieTableTitle": "Übersicht der verwendeten Cookies"
  }]
}

Query-Parameter

Filterung (where)

# Equals
?where[field][equals]=value

# Not equals
?where[field][not_equals]=value

# Greater than
?where[field][greater_than]=10

# Less than
?where[field][less_than]=100

# Contains (Text)
?where[field][contains]=suchtext

# In (Array)
?where[field][in]=value1,value2

# AND-Verknüpfung
?where[and][0][field1][equals]=value1&where[and][1][field2][equals]=value2

# OR-Verknüpfung
?where[or][0][field1][equals]=value1&where[or][1][field2][equals]=value2

Sortierung (sort)

# Aufsteigend
?sort=fieldName

# Absteigend
?sort=-fieldName

# Mehrere Felder
?sort=-publishedAt,title

Pagination

# Limit
?limit=10

# Seite
?page=2

# Beide kombiniert
?limit=10&page=2

Depth (Relations laden)

# Keine Relations laden
?depth=0

# Eine Ebene
?depth=1

# Zwei Ebenen
?depth=2

Locale (Mehrsprachigkeit)

# Deutsch (Standard)
?locale=de

# Englisch
?locale=en

# Alle Sprachen
?locale=all

Fehlerbehandlung

Häufige Fehlercodes

Code Bedeutung
200 Erfolg
201 Erstellt
400 Ungültige Anfrage
401 Nicht authentifiziert
403 Nicht autorisiert
404 Nicht gefunden
500 Server-Fehler

Fehler-Response

{
  "errors": [
    {
      "message": "Du hast keine Berechtigung, diese Aktion auszuführen."
    }
  ]
}

Validierungsfehler

{
  "errors": [
    {
      "message": "The following field is invalid: email",
      "field": "email"
    }
  ]
}

Multi-Tenant Hinweise

Tenant-ID ermitteln

  1. Admin Panel: Unter "Settings → Tenants" die ID ablesen
  2. API:
curl "https://pl.porwoll.tech/api/tenants" \
  -H "Authorization: JWT your-token"

Domain-basierter Zugriff

Wenn ein Frontend über eine Tenant-Domain (z.B. porwoll.de) zugreift, wird der Tenant automatisch erkannt und nur dessen Daten zurückgegeben.

Manueller Tenant-Filter

Für direkte API-Zugriffe:

curl "https://pl.porwoll.tech/api/posts?where[tenant][equals]=1"

Super Admin

User mit isSuperAdmin: true haben Zugriff auf alle Tenants und können neue Tenants erstellen/bearbeiten.


Beispiel: Frontend-Integration

Next.js Beispiel

// lib/api.ts
const API_BASE = 'https://pl.porwoll.tech/api'
const TENANT_ID = 1

export async function getPosts(type?: string, limit = 10, locale = 'de') {
  const params = new URLSearchParams({
    'where[tenant][equals]': String(TENANT_ID),
    'where[status][equals]': 'published',
    limit: String(limit),
    sort: '-publishedAt',
    depth: '1',
    locale,
  })

  if (type && type !== 'all') {
    params.append('where[type][equals]', type)
  }

  const res = await fetch(`${API_BASE}/posts?${params}`)
  return res.json()
}

export async function getTestimonials(limit = 6) {
  const params = new URLSearchParams({
    'where[tenant][equals]': String(TENANT_ID),
    'where[isActive][equals]': 'true',
    limit: String(limit),
    sort: 'order',
    depth: '1',
  })

  const res = await fetch(`${API_BASE}/testimonials?${params}`)
  return res.json()
}

export async function getCookieConfig() {
  const params = new URLSearchParams({
    'where[tenant][equals]': String(TENANT_ID),
  })

  const res = await fetch(`${API_BASE}/cookie-configurations?${params}`)
  const data = await res.json()
  return data.docs[0] || null
}

export async function getCookieInventory() {
  const params = new URLSearchParams({
    'where[tenant][equals]': String(TENANT_ID),
    'where[isActive][equals]': 'true',
    sort: 'category',
  })

  const res = await fetch(`${API_BASE}/cookie-inventory?${params}`)
  return res.json()
}

export async function logConsent(
  categories: Record<string, boolean>,
  revision: number,
  clientRef: string,
  apiKey: string
) {
  const res = await fetch(`${API_BASE}/consent-logs`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': apiKey,
    },
    body: JSON.stringify({
      tenant: TENANT_ID,
      clientRef,
      categories,
      revision,
      userAgent: navigator.userAgent,
    }),
  })
  return res.json()
}

export async function subscribeNewsletter(email: string, source: string) {
  const res = await fetch(`${API_BASE}/newsletter-subscribers`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      tenant: TENANT_ID,
      email,
      source,
    }),
  })
  return res.json()
}

React Component

// components/NewsletterForm.tsx
import { useState } from 'react'
import { subscribeNewsletter } from '@/lib/api'

export function NewsletterForm() {
  const [email, setEmail] = useState('')
  const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle')

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    setStatus('loading')

    try {
      const result = await subscribeNewsletter(email, 'website-footer')
      if (result.doc) {
        setStatus('success')
        setEmail('')
      } else {
        setStatus('error')
      }
    } catch {
      setStatus('error')
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Ihre E-Mail-Adresse"
        required
      />
      <button type="submit" disabled={status === 'loading'}>
        {status === 'loading' ? 'Wird gesendet...' : 'Anmelden'}
      </button>
      {status === 'success' && <p>Vielen Dank! Bitte bestätigen Sie Ihre E-Mail.</p>}
      {status === 'error' && <p>Es ist ein Fehler aufgetreten.</p>}
    </form>
  )
}

Rate Limiting

Das System verwendet einen zentralen Rate-Limiter mit Redis-Backend (Fallback auf In-Memory).

Vordefinierte Limits

Limiter Limit Fenster Verwendung
publicApiLimiter 60 Requests 1 Minute Öffentliche API-Endpunkte
authLimiter 5 Requests 15 Minuten Login-Versuche
emailLimiter 10 Requests 1 Minute E-Mail-Versand
searchLimiter 30 Requests 1 Minute Suche & Posts-API
formLimiter 5 Requests 10 Minuten Formular-Submissions, Newsletter

Response bei Rate-Limit

{
  "error": "Too many requests",
  "retryAfter": 60
}

HTTP Status: 429 Too Many Requests

Headers:

  • X-RateLimit-Limit: Maximale Requests
  • X-RateLimit-Remaining: Verbleibende Requests
  • X-RateLimit-Reset: Reset-Zeitpunkt (Unix Timestamp)
  • Retry-After: Sekunden bis zum Reset

Alle Collections Übersicht

Core Collections

Collection Slug Öffentlich Beschreibung
Users users Nein Benutzer-Verwaltung
Tenants tenants Nein Mandanten
Media media Ja Bilder und Dateien (11 responsive Sizes)
Pages pages Ja Seiten mit Blocks

Content Collections

Collection Slug Öffentlich Beschreibung
Posts posts Ja Blog, News, Presse, Ankündigungen
Categories categories Ja Kategorien für Posts
Tags tags Ja Tags für Posts
Authors authors Ja Autoren für Posts
Testimonials testimonials Ja Kundenbewertungen
FAQs faqs Ja Häufig gestellte Fragen
Social Links social-links Ja Social Media Links

Team & Services

Collection Slug Öffentlich Beschreibung
Team team Ja Team-Mitglieder
Service Categories service-categories Ja Kategorien für Leistungen
Services services Ja Leistungen/Dienstleistungen
Jobs jobs Ja Stellenangebote

Portfolio & Media

Collection Slug Öffentlich Beschreibung
Portfolios portfolios Ja Portfolio-Galerien
Portfolio Categories portfolio-categories Ja Kategorien für Portfolios
Videos videos Ja Video-Bibliothek (YouTube/Vimeo/Upload)
Video Categories video-categories Ja Kategorien für Videos

Products (E-Commerce)

Collection Slug Öffentlich Beschreibung
Products products Ja Produkte
Product Categories product-categories Ja Produkt-Kategorien

Feature Collections

Collection Slug Öffentlich Beschreibung
Locations locations Ja Standorte/Filialen
Partners partners Ja Partner/Kunden (Logos)
Downloads downloads Ja Download-Dateien
Events events Ja Veranstaltungen
Timelines timelines Ja Chronologische Events
Workflows workflows Ja Prozess-Darstellungen

BlogWoman Collections (NEU)

Collection Slug Öffentlich Beschreibung
Favorites favorites Ja Affiliate-Produkte mit Kategorien/Badges
Series series Ja YouTube-Serien mit Branding

Formulare & Newsletter

Collection Slug Öffentlich Beschreibung
Forms forms Nein Formular-Builder (Plugin)
Form Submissions form-submissions Nein Formular-Einsendungen mit CRM-Workflow
Newsletter Subscribers newsletter-subscribers Create: Ja Newsletter mit Double Opt-In
Collection Slug Öffentlich Beschreibung
Cookie Configurations cookie-configurations Ja (Tenant-isoliert) Cookie-Banner Konfiguration
Cookie Inventory cookie-inventory Ja (Tenant-isoliert) Cookie-Dokumentation
Consent Logs consent-logs Nein (API-Key) WORM Audit-Trail
Privacy Policy Settings privacy-policy-settings Ja (Tenant-isoliert) Datenschutz-Konfiguration

Tenant-spezifische Collections

Collection Slug Tenant Beschreibung
Bookings bookings porwoll.de Fotografie-Buchungen
Certifications certifications C2S Zertifizierungen
Projects projects gunshin.de Game-Development-Projekte

System Collections

Collection Slug Öffentlich Beschreibung
Site Settings site-settings Ja (Tenant-isoliert) Website-Einstellungen
Navigations navigations Ja (Tenant-isoliert) Navigationsmenüs
Email Logs email-logs Nein E-Mail-Protokollierung
Audit Logs audit-logs Nein Security Audit Trail
Redirects redirects Nein URL-Weiterleitungen (Plugin)

BlogWoman APIs (NEU)

Favorites API (Affiliate-Produkte)

# Alle Favorites eines Tenants
curl "https://pl.porwoll.tech/api/favorites?where[tenant][equals]=1"

# Nach Kategorie filtern
curl "https://pl.porwoll.tech/api/favorites?where[tenant][equals]=1&where[category][equals]=fashion"

# Nach Badge filtern
curl "https://pl.porwoll.tech/api/favorites?where[tenant][equals]=1&where[badge][equals]=bestseller"

# Nach Preisbereich filtern
curl "https://pl.porwoll.tech/api/favorites?where[tenant][equals]=1&where[priceRange][equals]=mid"

Felder:

Feld Typ Beschreibung
title string Produktname
slug string URL-Pfad
description richtext Beschreibung
image relation Produktbild
affiliateUrl string Affiliate-Link
price string Preis (Freitext)
category select fashion, beauty, travel, tech, home
badge select investment-piece, daily-driver, grfi-approved, new, bestseller
priceRange select budget, mid, premium, luxury
isActive boolean Sichtbarkeit

Series API (YouTube-Serien)

# Alle Serien eines Tenants
curl "https://pl.porwoll.tech/api/series?where[tenant][equals]=1"

# Nur aktive Serien
curl "https://pl.porwoll.tech/api/series?where[tenant][equals]=1&where[isActive][equals]=true"

# Einzelne Serie nach Slug
curl "https://pl.porwoll.tech/api/series?where[tenant][equals]=1&where[slug][equals]=grfi"

Felder:

Feld Typ Beschreibung
title string Serienname (lokalisiert)
slug string URL-Pfad
description richtext Beschreibung (lokalisiert)
logo relation Serien-Logo
coverImage relation Cover-Bild
brandColor string Hex-Farbcode
youtubePlaylistId string YouTube Playlist ID
isActive boolean Sichtbarkeit

Weitere Ressourcen


Letzte Aktualisierung: 08.01.2026