cms.c2sgmbh/docs/anleitungen/API_ANLEITUNG.md
Martin Porwoll d7dfa2e2ea docs: add Community Management APIs to FRONTEND.md and API_ANLEITUNG.md
Add documentation for YouTube/Meta integration:
- YouTube Channels, Content, Series, Notifications APIs
- Social Platforms, Accounts, Community Interactions APIs
- Code examples for frontend integration
- Field documentation with curl examples

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

33 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

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

Community Management (YouTube/Meta)

Collection Slug Öffentlich Beschreibung
YouTube Channels youtube-channels Nein Multi-Kanal-Verwaltung
YouTube Content youtube-content Nein Videos + Shorts mit Statistiken
YT Series yt-series Nein Serien mit Branding (Logo, Farben)
YT Notifications yt-notifications Nein Handlungsbedarf-System
Social Platforms social-platforms Nein Plattform-Konfiguration
Social Accounts social-accounts Nein OAuth-Verbindungen
Community Interactions community-interactions Nein Kommentare/Nachrichten aller Plattformen

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

Community Management APIs (YouTube/Meta)

YouTube Channels API

# Alle Kanäle
curl "https://pl.porwoll.tech/api/youtube-channels" \
  -H "Authorization: JWT your-token"

# Einzelner Kanal
curl "https://pl.porwoll.tech/api/youtube-channels/1" \
  -H "Authorization: JWT your-token"

Felder:

Feld Typ Beschreibung
channelId string YouTube Channel ID
title string Kanalname
handle string @handle
thumbnailUrl string Profilbild-URL
subscriberCount number Abonnenten
videoCount number Anzahl Videos
isActive boolean Sync aktiv

YouTube Content API

# Alle Videos eines Kanals
curl "https://pl.porwoll.tech/api/youtube-content?where[channel][equals]=1" \
  -H "Authorization: JWT your-token"

# Nur Videos (keine Shorts)
curl "https://pl.porwoll.tech/api/youtube-content?where[contentType][equals]=video" \
  -H "Authorization: JWT your-token"

# Videos einer Serie
curl "https://pl.porwoll.tech/api/youtube-content?where[series][equals]=1" \
  -H "Authorization: JWT your-token"

# Nach Veröffentlichungsdatum sortiert
curl "https://pl.porwoll.tech/api/youtube-content?sort=-publishedAt&limit=10" \
  -H "Authorization: JWT your-token"

Felder:

Feld Typ Beschreibung
videoId string YouTube Video ID
title string Video-Titel
description text Beschreibung
thumbnailUrl string Thumbnail-URL
publishedAt date Veröffentlichungsdatum
contentType select video, short
channel relation YouTube-Kanal
series relation YT-Serie
viewCount number Aufrufe
likeCount number Likes
commentCount number Kommentare

YT Series API

# Alle Serien eines Kanals
curl "https://pl.porwoll.tech/api/yt-series?where[channel][equals]=1" \
  -H "Authorization: JWT your-token"

# Nur aktive Serien
curl "https://pl.porwoll.tech/api/yt-series?where[isActive][equals]=true" \
  -H "Authorization: JWT your-token"

Felder:

Feld Typ Beschreibung
name string Serienname (lokalisiert)
slug string URL-Pfad
description textarea Beschreibung (lokalisiert)
channel relation YouTube-Kanal
logo relation Serien-Logo
coverImage relation Cover-Bild
brandColor string Primärfarbe (Hex)
accentColor string Akzentfarbe (Hex)
youtubePlaylistId string Playlist ID
format select short, longform, mixed
isActive boolean Sichtbarkeit

YT Notifications API (Auth erforderlich)

# Alle Benachrichtigungen
curl "https://pl.porwoll.tech/api/yt-notifications" \
  -H "Authorization: JWT your-token"

# Nur ungelesene
curl "https://pl.porwoll.tech/api/yt-notifications?where[status][equals]=unread" \
  -H "Authorization: JWT your-token"

# Nach Priorität
curl "https://pl.porwoll.tech/api/yt-notifications?where[priority][equals]=high" \
  -H "Authorization: JWT your-token"

Felder:

Feld Typ Beschreibung
type select comment, mention, milestone, alert
priority select low, medium, high, urgent
status select unread, read, actioned, dismissed
title string Benachrichtigungstitel
message text Details
channel relation Betroffener Kanal
content relation Betroffenes Video

Community Interactions API (Auth erforderlich)

# Alle Interaktionen
curl "https://pl.porwoll.tech/api/community-interactions" \
  -H "Authorization: JWT your-token"

# Nach Plattform filtern
curl "https://pl.porwoll.tech/api/community-interactions?where[platform][equals]=1" \
  -H "Authorization: JWT your-token"

# Nur Kommentare
curl "https://pl.porwoll.tech/api/community-interactions?where[type][equals]=comment" \
  -H "Authorization: JWT your-token"

# Nach Status
curl "https://pl.porwoll.tech/api/community-interactions?where[status][equals]=pending" \
  -H "Authorization: JWT your-token"

# Nach Sentiment (AI-Analyse)
curl "https://pl.porwoll.tech/api/community-interactions?where[analysis.sentiment][equals]=negative" \
  -H "Authorization: JWT your-token"

Felder:

Feld Typ Beschreibung
platform relation Social Platform
socialAccount relation Social Account
type select comment, reply, dm, mention
externalId string Plattform-ID
author.name string Autor-Name
author.handle string Autor-Handle
message text Nachrichteninhalt
publishedAt date Veröffentlichungsdatum
status select pending, read, in-progress, done, archived
priority select low, normal, high
analysis.sentiment select positive, neutral, negative
analysis.language string Erkannte Sprache

Social Platforms API

# Alle Plattformen
curl "https://pl.porwoll.tech/api/social-platforms" \
  -H "Authorization: JWT your-token"

Felder:

Feld Typ Beschreibung
name string Plattformname
slug string youtube, facebook, instagram
icon string Emoji
color string Brand Color (Hex)
apiConfig.apiType select youtube_v3, facebook_graph, instagram_graph
apiConfig.authType select oauth2, api_key, bearer
isActive boolean Plattform aktiv

Social Accounts API (Auth erforderlich)

# Alle verbundenen Accounts
curl "https://pl.porwoll.tech/api/social-accounts" \
  -H "Authorization: JWT your-token"

# Nach Plattform filtern
curl "https://pl.porwoll.tech/api/social-accounts?where[platform][equals]=1" \
  -H "Authorization: JWT your-token"

Felder:

Feld Typ Beschreibung
platform relation Social Platform
displayName string Anzeigename
accountHandle string @handle
externalId string Plattform-Account-ID
credentials.accessToken string OAuth Token (verschlüsselt)
credentials.tokenExpiresAt date Token-Ablauf
stats.lastSyncedAt date Letzter Sync
isActive boolean Sync aktiv

Weitere Ressourcen


Letzte Aktualisierung: 17.01.2026