Blog (Headless CMS)-Integration

Zuletzt aktualisiert: Aug 31, 2026Abschnitt: Integrationen

Vollständige API-Referenz: https://api.mailoo.app/docs/v1

Nutzen Sie Mailoo als zentrales Headless CMS für Ihren Blog: Erstellen und verwalten Sie Artikel im Dashboard und stellen Sie sie über eine externe API nach Projekt bereit. Externe Websites (oder Ihre eigene) können dieselbe API nutzen.

Übersicht

Die Blog-Integration funktioniert wie andere Mailoo-Integrationen (z. B. Form): Sie fügen eine Blog-Integration zu einem Projekt hinzu. Alle Artikel für diesen Blog gehören zu dieser Integration. Die API stellt Blog-Artikel nicht ohne Autorisierung bereit. Lese-API: Artikel auflisten und einen nach Slug abrufen; erfordert X-API-Key mit der Berechtigung blog.external-read; Zugriff über Projekt-UID und Integrations-ID. Verwaltungs-API: Artikel erstellen, aktualisieren und löschen mit X-API-Key und Berechtigung blog.manage (gleicher Pfad-Präfix /api/v1/blog/.../articles). Agenten können den Mailoo-MCP-Server mit einem persönlichen MCP-Token nutzen, das unter Profile → Security erstellt wird; siehe mailoo-mcp{.interpreted-text role="doc"}.

Funktionen:

  • Artikel im Mailoo-Dashboard erstellen, bearbeiten und löschen (pro Integration) oder über die Verwaltungs-API / MCP mit blog.manage
  • Als Entwurf oder veröffentlicht publizieren; optionaler Auszug, SEO-Metadaten (metaTitle, metaDescription, ogImageMediaId → öffentliche ogImageUrl), Klassifikatoren (Themen, Intentionen, Zielgruppen, SEO-Cluster), Tags
  • Lese-API (X-API-Key erforderlich): veröffentlichte Artikel auflisten und einen nach Slug abrufen, über Projekt-UID und Integrations-ID
  • Verwaltungs-API (X-API-Key + blog.manage): POST/GET/PUT/DELETE …/blog/{projectUid}/integrations/{integrationId}/articles; Klassifikatorwerte mit blog.external-read oder blog.manage auflisten
  • Artikelantwort (Liste): id, title, slug, excerpt, content (Markdown, Quelle der Wahrheit), htmlContent (HTML, von der API aus content generiert; für die Anzeige verwenden), status, publishedAt, createdAt, updatedAt, author (id, name, email?, avatar, bio --- lokalisiert bei gesetztem locale), category (primäres Thema für Abwärtskompatibilität: erstes Thema nach Slug, oder null), themes, intents, audiences, seoClusters (jeweils ein Array von { id, slug, name }), metaTitle, metaDescription (null wenn nicht gesetzt --- Konsumenten können auf title / excerpt zurückgreifen), ogImageUrl (null wenn nicht gesetzt), canonicalUrl (absolute URL wenn das Integrations-Canonical-Template gesetzt ist; andernfalls null), seoWords ([{ slug, word }] --- Vereinigung der SEO-Wort-Katalogeinträge der Integration, die mit den SEO-Clustern des Artikels verknüpft sind; lokalisiert bei gesetztem locale; leeres Array wenn keine), featured, readTimeMinutes, tags (Array, Standard []). Paginierung enthält page, limit, total, totalPages, hasNextPage, hasPrevPage. Inline-Bilder verwenden URLs der Mailoo-Bild-API (siehe images{.interpreted-text role="doc"}); es gibt kein separates Top-Level-image-Feld am Artikel.
  • Artikelantwort (Einzeln nach Slug): gleiche Felder wie beim Listeneintrag, plus optionale linkedLinks --- ein geordnetes Array (max. 10 pro Artikel) kuratierter Links: id, type (internal_article | update_announcement | external_resource), label, url, intro (nullable), date (nullable ISO-Datetime), sortOrder. Interne Links verwenden einen Same-Site-Pfad /blog/{targetSlug} in url; stellen Sie beim Aufbau des öffentlichen href Ihr Locale-Segment voran (z. B. /{locale}/blog/...). Redakteure verwalten Links im Dashboard; internal_article-Einträge können Label/Datum/Intro automatisch vom Zielartikel übernehmen, mit optionalen Überschreibungen.
  • JSON-LD (optional): GET …/slug/{slug}/json-ld?locale= gibt Schema.org BlogPosting zurück. Wenn das Integrations-Canonical-Template konfiguriert ist, sind url / mainEntityOfPage / inLanguage / Publisher-Name absolute Werte (oder locale-gefüllt). Wenn nicht gesetzt, bleiben Platzhalter {{canonicalUrl}}, {{origin}}, {{locale}} für den Integrator zum Ersetzen. Nicht im Standard-Listen-/Slug-Payload enthalten. Same-Origin-BFF: GET /api/v1/blog/slug/{slug}/json-ld.

Seiten-SEO für Konsumenten: Verwenden Sie metaTitle ?? title → Dokument-/OG-Titel, metaDescription ?? excerpt → Beschreibung, ogImageUrl (sonst erstes Body-Bild) → OG/Twitter-Bild, canonicalUrl (oder slug + Ihr Locale-Präfix und Site-Origin wenn null) → Canonical / rel=canonical. Optionale seoWords / tags können <meta name="keywords"> oder interne Verlinkung speisen. Absolute Canonicals werden nicht pro Artikel gespeichert; konfigurieren Sie ein integrations-eigenes Canonical-Template unter Connection & settings (publicBaseUrl + Pfad-Muster mit {locale} / {slug}).

Autorenprofile (Dashboard)

Jedes Konto kann benutzereigene Autorenprofile pflegen (Anzeigename, Slug, optionale öffentliche E-Mail, Avatar-URL, Bio, optionale Locale-Überschreibungen). Artikel speichern eine Live-Referenz zum gewählten Profil, sodass Aktualisierungen sich automatisch übertragen. Pseudonyme werden unterstützt (isAlias). Ein Profil kann als globaler Standard markiert werden; Sie können auch einen pro-Blog-Integrations-Standard setzen (nur Ihre Präferenz --- wird nicht in der gemeinsamen Integrationskonfiguration gespeichert).

  • Reiter Authors auf der Blog-Integration: Profile auflisten und erstellen/bearbeiten.
  • Reiter Connection & settings: Default author speichert die pro-Integrations-Überschreibung (fällt auf den globalen Standard zurück wenn nicht gesetzt). Canonical URL template speichert config.canonicalTemplate (publicBaseUrl, pathPattern), damit externe Lesezugriffe canonicalUrl zurückgeben können. IndexNOW notify (optionales config.indexNow) sendet Artikel-IDs per POST an Ihre Website bei Veröffentlichung/Änderung --- Sie rufen IndexNOW auf (siehe indexnow-notify{.interpreted-text role="doc"}). Stock photos speichert pro-Integrations-Unsplash-/Pexels-API-Schlüssel (verschlüsselt), damit Redakteure Stockfotos suchen und in Artikel importieren können; importierte Fotos werden zu normalen Mailoo-UserMedia-Einbettungen (siehe images{.interpreted-text role="doc"}). Agenten können dieselben sanitisierten Einstellungen über GET/PATCH /api/v1/blog/.../settings oder das MCP-Tool manage_blog_integration_settings lesen/aktualisieren (siehe mailoo-mcp{.interpreted-text role="doc"}).
  • Neuer/Bearbeiteter Artikel: Wählen Sie ein Autorenprofil oder lassen Sie Integrations-/globaler Standard, damit die API den Autor automatisch auflöst.

Blog-Integration erstellen

  1. Gehen Sie zu Dashboard → Projects → [Ihr Projekt]
  2. Klicken Sie auf Create New Integration
  3. Wählen Sie Blog (Headless CMS)
  4. Setzen Sie einen Namen und Status (z. B. Active)
  5. Öffnen Sie nach der Erstellung die Integration, um die Articles-Liste und den Connection-Block zu sehen

Artikel verwalten

Auf der Integrationsseite können Sie:

  • Artikeltabelle: Titel, Slug, Klassifikatoren-Zusammenfassung, Status, Datum und Edit für jeden Artikel; Schnellfilter nach Thema, Intention, Zielgruppe und SEO-Cluster; Export Markdown report (mit oder ohne vollständigem Artikeltext) für KI-gestützte Inhaltsplanung
  • Artikel erstellen: Öffnet das Formular für neue Artikel (Titel, Auszug, SEO-Metadaten, Inhalt, Status). Inhalt wird in Markdown eingegeben (Überschriften, Listen, Fett, Links, Bilder über das Dashboard-Bildpanel --- einschließlich des Stock-Reiters für Unsplash/Pexels wenn Schlüssel konfiguriert sind --- oder öffentliche Einbettungs-URLs); die API wandelt ihn beim Speichern in HTML um.
  • Bearbeiten: Öffnet das Bearbeitungsformular für diesen Artikel (als Entwurf speichern, veröffentlichen oder archivieren). Derselbe Markdown-Editor für das Standard-Locale und für jede Übersetzung (Locales).
  • Verknüpfte Links: Beim Erstellen/Bearbeiten können Sie bis zu 10 kuratierte verknüpfte Links anhängen (Typ, URL oder interner Zielartikel, optionales Label/Intro/Datum). Die externe Get-by-Slug-API liefert sie als linkedLinks für Headless-Frontends (z. B. Release Notes auf einer Portfolio-Projektseite).

Inhaltsformat: Der Artikelinhalt wird als content in Markdown gespeichert. Die API generiert htmlContent daraus. Konsumenten sollten htmlContent für die Anzeige verwenden, um korrekte Struktur und Typografie zu erhalten.

Links in htmlContent: Absolute http://-/https://-URLs und protokollrelative //…-Links enthalten target="_blank" und rel="noopener noreferrer". Same-Tab-Verhalten gilt für Site-Root-Pfade (/path), explizit pfadrelative Links (./…, ../…), Seiten-Anker (#section) und reine Query-URLs (?q=1).

Same-Site-Links --- führenden Schrägstrich verwenden. In Markdown wird [label](support/docs) zu HTML href="support/docs". Das ist eine pfadrelative URL: Browser lösen sie gemäß RFC 3986 relativ zum Verzeichnis der Seite auf, die den Artikel anzeigt, nicht relativ zum Site-Root. Beispiel: Auf einem Beitrag unter https://example.com/en/blog/my-post wird support/docs zu /en/blog/support/docs aufgelöst. Um auf einen Site-Bereich vom Root zu verlinken, schreiben Sie [label](/support/docs) (oder die vollständige https://…-URL). Einzelsegment-Links ohne Schrägstrich (z. B. [other](other-slug)) sind ebenfalls pfadrelativ und bleiben daher im gleichen Verzeichnis wie die Beitrags-URL --- nützlich für Geschwister-Beiträge nur dann, wenn Ihre öffentlichen Beitrags-URLs denselben Pfad-Präfix teilen.

Mermaid in htmlContent: Umzäunte Codeblöcke mit der Bezeichnung mermaid werden in statische Inline-SVGs umgewandelt (innerhalb von <figure class="mailoo-mermaid">). Keine Browser-seitige Mermaid-Laufzeit erforderlich; dasselbe HTML eignet sich für E-Mail-Rendering. Ungültige Mermaid-Syntax führt dazu, dass die API das Speichern ablehnt (Artikel, lokalisierte Inhalte, Kampagnen usw.).

Druckbare Zusammenfassungsblöcke in htmlContent: Umzäunte Codeblöcke mit der Bezeichnung mailoo-print werden zu einem selbstbeschreibenden druckbaren Abschnitt. Autoren schreiben:

```mailoo-print Kurzer Zusammenfassungstitel

## Kernpunkte

- Erste **Erkenntnis**
- Zweiter [Link](/docs)
```

Die API wandelt dies in HTML um, ähnlich wie:

<section class="mailoo-printable" data-mailoo-print="true" data-print-title="Kurzer Zusammenfassungstitel">
  <div class="mailoo-printable-body">…geparster Markdown als HTML…</div>
</section>

Der optionale Titel nach mailoo-print in der Fence-Info-Zeile wird zu data-print-title. Der innere Inhalt unterstützt vollständigen Markdown (Überschriften, Listen, Links, Bilder, verschachtelte mermaid-Blöcke). Konsumenten (Ihre Website oder das Blog dieses Repos) sollten [data-mailoo-print] erkennen, im Browser einen Druckknopf einblenden und nur .mailoo-printable-body drucken --- die API bettet keine onclick-Handler ein (CSP-sicher). Siehe blog-nextjs-example{.interpreted-text role="doc"} für ein Client-Enhancer-Muster.

Themen (Kategorien) und Klassifikatoren verwalten

Blog-Inhalte werden auf vier Klassifikator-Achsen organisiert, jeweils mit Viele-zu-Viele-Verknüpfungen zu Artikeln:

  • THEME (ersetzt das frühere „Kategorie"-Modell): Leitthemen; der Dashboard-Block Categories verwaltet weiterhin Theme-Werte für diese Integration (gleiche CRUD-Pfade wie zuvor: …/categories).
  • INTENT, AUDIENCE, SEO_CLUSTER: optionale Achsen für redaktionelle und SEO-Ausrichtung (z. B. informationale vs. transaktionale Intention, ICP, Abfrage-Cluster). Werte unter GET/POST …/blog-classifier-values?type=… verwalten (Dashboard / Bearer-API).

SEO-Wörter (lokalisierte Phrasen) --- optional pro Integration: kurze Phrasen für SEO-Planung, werden nicht auf Artikeln gespeichert. Jedes SEO-Wort hat einen URL-tauglichen slug, ein kanonisches englisches word, optionale locales-Überschreibungen (gleiche JSON-Struktur wie Artikel-Übersetzungen) und eine Viele-zu-Viele-Verknüpfung ausschließlich zu SEO_CLUSTER-Klassifikatorwerten. Dashboard-Reiter Products: GET/POST /api/v1/projects/{projectUid}/integrations/{integrationId}/blog-seo-words und PUT/DELETE …/blog-seo-words/{wordId} (Bearer). Liste unterstützt optionales ?clusterId= (CUID eines SEO-Cluster-Werts). Beim Erstellen oder Bearbeiten eines Artikels zeigt das Formular schreibgeschützt die Vereinigung der SEO-Wörter an, die mit den am Artikel ausgewählten SEO-Clustern verknüpft sind.

Beim Erstellen oder Bearbeiten eines Artikels wählen Sie beliebig viele Werte pro Achse. Externe Listenfilter unterstützen category / categoryId für Themen plus intentId, audienceId, seoClusterId (CUID eines Klassifikatorwerts).

Themenbeschreibung (optional): Für einen Themenwert wählen Sie einen Artikel als descriptionPostId (gleich wie die alte Kategoriebeschreibung). Externes GET …/categories/slug/{slug}/description löst weiterhin Theme-Slugs auf.

Systemthemen (About / Portfolio)

Mailoo reserviert zwei Theme-Slugs pro Blog-Integration: about und portfolio. Verwenden Sie sie für eigenständige Seiten, die nicht in der Standard-Artikelliste erscheinen sollen.

  • Bereitstellung: Das Erstellen einer Blog-Integration erzeugt automatisch die Themenwerte About (Slug about) und Portfolio (Slug portfolio).
  • Standardliste: GET …/blog/{projectUid}/integrations/{integrationId} ohne category und ohne categoryId lässt veröffentlichte Artikel weg, die mit einem Thema verknüpft sind, dessen Slug about oder portfolio ist. Artikel ohne Themen-Klassifikatoren, aber mit einem Legacy-category-String, der diesen Slugs entspricht (Groß-/Kleinschreibung ignoriert), werden ebenfalls weggelassen.
  • Expliziter Filter: Übergeben Sie category (Theme-Slug oder Legacy-String) oder categoryId (Theme-Wert-ID), um diese Artikel einzuschließen.
  • Die Dashboard-Artikelliste zeigt alle Artikel an, sofern Sie keine Filter anwenden.

Der category-Abfrageparameter filtert nach Theme-BlogClassifierValue (Typ THEME)-Slug oder dem Legacy-category-String des Beitrags. Wenn sowohl category als auch categoryId gesetzt sind, gelten beide Bedingungen (logisches UND).

Dashboard-Markdown-Bericht

Authentifizierte Projektredakteure können einen strukturierten Markdown-Bericht für eine Blog-Integration herunterladen:

GET /api/v1/projects/{projectUid}/integrations/{integrationId}/blog/report?includeFullText=true|false&format=md&publishedFrom=YYYY-MM-DD&publishedTo=YYYY-MM-DD

Abfrageparameter:

  • includeFullText --- bei true enthält jeder Artikelabschnitt den vollständigen Markdown-Text.
  • format --- nur md wird unterstützt.
  • publishedFrom / publishedTo (optional, inklusive, UTC-Kalenderdaten YYYY-MM-DD) --- filtern nach publishedAt. Wenn einer der beiden gesetzt ist, werden nur Beiträge mit einem nicht-null publishedAt einbezogen (Entwürfe ohne Veröffentlichungsdatum werden ausgeschlossen). Wenn beide gesetzt sind, muss publishedFrom gleich oder vor publishedTo liegen.

Der Dashboard-Flow Export report öffnet eine dedizierte Seite (Breadcrumb-Navigation) zur Auswahl von Monat, Quartal oder benutzerdefiniertem Zeitraum, Vorschau des Markdowns und Speichern in einer Datei.

Die Datei enthält Metadaten, Aggregate pro Klassifikator-Achse, eine Thema×Intention-Matrix und einen Pro-Artikel-Abschnitt (optional mit vollständigen Markdown-Textkörpern). Gedacht zum Prompten externer LLMs für die Inhaltsplanung.

Verbindung (Externe API)

Der Connection-Block auf der Integrationsseite zeigt die zu kopierenden Umgebungswerte (API-Basis-URL, Projekt-UID, Integrations-ID) und ein fertiges .env-Snippet. Für Webanwendungen ist der einzig empfohlene Ansatz BFF (API-Schlüssel auf dem Server); direkte API-Aufrufe mit X-API-Key sind für Server-zu-Server-Nutzung. Vollständige Endpunktpfade sind unten dokumentiert; sie werden im Dashboard nicht dupliziert. Für Next.js siehe blog-nextjs-example{.interpreted-text role="doc"}.

BFF-Routen (Next.js, Same-Origin) --- verwenden Sie Umgebungsvariablen MAILOO_BLOG_PROJECT_UID, MAILOO_BLOG_INTEGRATION_ID, MAILOO_BLOG_API, MAILOO_BLOG_API_KEY:

  • Veröffentlichte Artikel auflisten: GET /api/v1/blog Abfrage: page, limit, category, categoryId, intentId, audienceId, seoClusterId, search, locale, featured, tag (optional); Filter werden mit logischem UND kombiniert. Ohne category und categoryId werden Artikel in reservierten Theme-Slugs about und portfolio ausgeschlossen (siehe Systemthemen oben). tag ist ein exakter Abgleich auf einen Wert im Artikel-tags-Array (Groß-/Kleinschreibung wie gespeichert). Gibt { success, data: [...], pagination } mit hasNextPage, hasPrevPage zurück. Next.js-SDK createMailooBlogClient().listPosts behält data, pagination und imagePublicEmbedBaseUrl (siehe nextjs-packages{.interpreted-text role="doc"}).

  • Einen Artikel nach Slug abrufen: GET /api/v1/blog/slug/{slug} Abfrage: locale (optional). Gibt { success, data: article } zurück. Nur veröffentlichte Artikel werden zurückgegeben.

  • JSON-LD nach Slug: GET /api/v1/blog/slug/{slug}/json-ld Abfrage: locale (optional). Gibt { success, data: { jsonLd } } zurück (BlogPosting mit Platzhaltern). Next.js: createBlogJsonLdHandler() einbinden; RSC/Sitemap sollte createMailooBlogClient(config).getPostJsonLd aufrufen (direkte API, kein BFF-Loopback). Siehe nextjs-packages{.interpreted-text role="doc"}.

  • Kategorien (Themen) auflisten: GET /api/v1/blog/categories Gibt { success, data: Category[] } zurück (id, slug, name) --- nur Theme-Klassifikatorwerte (abwärtskompatibler Pfadname).

  • Kategoriebeschreibung nach Slug: GET /api/v1/blog/categories/slug/{slug}/description Abfrage: locale (optional). Gibt { success, data: { description, descriptionHtml } } zurück. Wenn die Kategorie keinen Beschreibungsartikel hat, sind beide Felder leere Strings. Wenn der Kategorie-Slug nicht existiert, wird 404 zurückgegeben.

  • Öffentliches Autorenprofil (nach ID oder Slug): Same-Origin-BFF ist nicht erforderlich; rufen Sie die API direkt mit X-API-Key auf:

    GET {baseUrl}/api/v1/blog/{projectUid}/integrations/{integrationId}/authors/{authorSlugOrId}

    Abfrage: locale (optional). Gibt lokalisierten name, bio, avatar und email nur zurück, wenn das Profil eine öffentliche E-Mail freigibt (Pseudonyme legen die Konto-E-Mail nicht offen).

Direkte API-Aufrufe --- erfordern X-API-Key-Header und Berechtigung blog.external-read:

  • Liste: GET {baseUrl}/api/v1/blog/{projectUid}/integrations/{integrationId} Optionale Abfrage: page, limit, category, categoryId, intentId, audienceId, seoClusterId, search, locale, featured, tag (gleiche Semantik wie die BFF-Listenroute oben).
  • Einzeln: GET {baseUrl}/api/v1/blog/{projectUid}/integrations/{integrationId}/slug/{slug} Abfrage: locale (optional).
  • JSON-LD: GET {baseUrl}/api/v1/blog/{projectUid}/integrations/{integrationId}/slug/{slug}/json-ld Abfrage: locale (optional).
  • Kategorien: GET {baseUrl}/api/v1/blog/{projectUid}/integrations/{integrationId}/categories
  • Kategoriebeschreibung: GET {baseUrl}/api/v1/blog/{projectUid}/integrations/{integrationId}/categories/slug/{slug}/description Abfrage: locale (optional). Gleiches Verhalten wie der BFF-Endpunkt oben.
  • Autorenprofil: GET {baseUrl}/api/v1/blog/{projectUid}/integrations/{integrationId}/authors/{authorSlugOrId} Abfrage: locale (optional). Öffentliche Leseansicht des Autorenprofils eines Projekteigentümers für Bylines und Autorenseiten.

Verwaltungs-API --- erfordert X-API-Key und Berechtigung blog.manage (FULL-Schlüssel funktionieren ebenfalls):

  • Liste (alle Status): GET {baseUrl}/api/v1/blog/{projectUid}/integrations/{integrationId}/articles
  • Erstellen: POST …/articles --- Body entspricht der Dashboard-Erstellung (title, Markdown-content, optionale locales einschließlich pro-Locale metaTitle / metaDescription, themeValueIds / intentValueIds / audienceValueIds / seoClusterValueIds, tags, metaTitle, metaDescription, ogImageMediaId, status, slug, authorProfileId, ...). Autor fällt auf das Standardprofil des Schlüsselbesitzers zurück wenn ausgelassen; 400 wenn keines existiert.
  • Abrufen / Aktualisieren / Löschen: GET|PUT|DELETE …/articles/{articleId}
  • Klassifikatorwerte (lesen oder verwalten): GET …/classifier-values?type=THEME|INTENT|AUDIENCE|SEO_CLUSTER --- erfordert blog.external-read oder blog.manage

Agenten-Entdeckung (jeder gültige API-Schlüssel; nur Projekte des Schlüsselbesitzers):

  • GET {baseUrl}/api/v1/agent/projects
  • GET {baseUrl}/api/v1/agent/projects/{uid}/integrations?type=BLOG

Für die MCP-Einrichtung siehe mailoo-mcp{.interpreted-text role="doc"}.

Die Basis-URL ist Ihre Mailoo-API (z. B. https://api.mailoo.app). projectUid und integrationId werden im Connection-Block angezeigt. Bilder in Artikeltexten verwenden die Mailoo-Bild-Upload-API und öffentliche Einbettungs-URLs innerhalb von content / htmlContent (siehe images{.interpreted-text role="doc"} für Speicherung, Berechtigungen und wie man Bytes mit Bearer oder X-API-Key liest). Tags werden als Array zurückgegeben; leeres Array wenn keine. Artikel, die als Kategoriebeschreibungen verwendet werden, werden aus der externen Artikelliste ausgeschlossen und erscheinen daher nicht doppelt in regulären Feed-Ergebnissen. Die Standardliste schließt ebenfalls About- und Portfolio-Kategorieartikel aus, es sei denn, Sie übergeben einen expliziten Kategoriefilter. Für vollständige Antwortfelder und Fehlercodes siehe die API-Dokumentation oben.

Für ein vollständiges Next.js-Beispiel siehe blog-nextjs-example{.interpreted-text role="doc"}.