Werkstattbericht Content-Automatisierung – Teil 6 von 8. Wie ich für einen meiner Blogs die Beitragsproduktion mit n8n und Claude automatisiert habe: was funktioniert hat, was nicht, und was am Ende dabei herauskam. Zu den anderen Teilen: 1 · 2 · 3 · 4 · 5 · 6 · 7 · 8.
Es gibt eine Sorte Fehler, die schlimmer ist als ein Absturz. Der Absturz sagt dir wenigstens, dass etwas nicht geklappt hat.
Diese hier sagt: 200 OK.
Und dann macht sie gar nichts.
Dies ist Teil 6 des Werkstattberichts. Es geht um Yoast-Felder über die WordPress-REST-API, um eine Stunde Ratlosigkeit, und um das, was am Ende jedes Beitrags steht – wo bei mir bis vor Kurzem 70.000 Wörter identischer Text geplant waren.
200 OK, und nichts ist passiert
Der Befund
Der Workflow erzeugt für jeden Beitrag ohnehin einen SEO-Titel, eine Meta-Beschreibung und – nach einer Ergänzung, dazu gleich mehr – eine Fokus-Keyphrase. Diese drei Werte in die entsprechenden Yoast-Felder zu schreiben, sollte eine Fingerübung sein: Die REST-API kennt ein Feld meta an jedem Beitrag, da schreibt man rein, fertig.
Ich habe zuerst nachgesehen, was in diesem Feld überhaupt steht. Die Antwort meiner Seite:
{"footnotes": ""}
Das war’s. Die Yoast-Felder sind dort nicht enthalten.
Und das ist kein Fehler, sondern WordPress-Logik: Meta-Felder, deren Name mit einem Unterstrich beginnt, gelten als geschützt. Sie sind über die REST-API weder les- noch schreibbar, solange sie nicht ausdrücklich freigegeben sind. Yoast benennt seine Felder genau so – _yoast_wpseo_title, _yoast_wpseo_metadesc, _yoast_wpseo_focuskw.
Exkurs: der teuerste Teil daran
Das Tückische ist nicht die Sperre. Die ist dokumentiert und vernünftig – sie verhindert, dass irgendeine App die internen Felder deines Systems überschreibt.
Das Tückische ist, dass WordPress einen Schreibversuch nicht ablehnt. Es verwirft ihn stillschweigend und antwortet mit 200 OK. Der aufrufende Workflow bekommt also ein Erfolgssignal und macht zufrieden weiter.
Ohne Gegenprüfung hätte ich das Wochen später gemerkt. Vielleicht Monate. Vermutlich in dem Moment, in dem ich mich gewundert hätte, warum Google bei allen meinen Beiträgen ein selbst zusammengesetztes Snippet zeigt statt meiner Beschreibung.
Ich halte das für ein Muster, das man sich merken sollte: Ein 200 beweist, dass die Anfrage angekommen ist. Nicht, dass sie gewirkt hat. Bei allem, was Zustand verändert, ist die einzige verlässliche Prüfung das Zurücklesen.

Die Freigabe und die Gegenprüfung
Ein mu-plugin, drei Felder
Die Freigabe ist eine kleine PHP-Datei, die nach wp-content/mu-plugins/ gehört. Den Ordner legt man notfalls selbst an – was dort liegt, ist automatisch aktiv, taucht in der Plugin-Liste nicht als deaktivierbar auf und überlebt Theme- und Plugin-Updates.
Sie gibt genau drei Felder frei, nur für Beiträge, und nur für Benutzer, die Beiträge bearbeiten dürfen:
| Feld | was es ist |
|---|---|
_yoast_wpseo_title | der SEO-Titel, also das <title> der Seite |
_yoast_wpseo_metadesc | die Meta-Beschreibung |
_yoast_wpseo_focuskw | die Fokus-Keyphrase |
Soweit mir bekannt sind das die Feldnamen, die Yoast seit Langem verwendet – verlässlich bestätigen kann ich es nicht. Genau deshalb prüft der Workflow es selbst nach.
Ob die Freigabe gewirkt hat, siehst du übrigens in zehn Sekunden: Ruf angemeldet
https://DEINE-SEITE/wp-json/wp/v2/posts?per_page=1&_fields=meta
im Browser auf. Taucht dort jetzt _yoast_wpseo_metadesc auf, steht die Freigabe. Steht da weiterhin nur footnotes, ist die Datei nicht aktiv.
Warum der Workflow nachliest
Nach dem Veröffentlichen hängen jetzt drei neue Nodes:
Yoast-Felder setzen → Yoast-Felder nachlesen → Yoast-Ergebnis prüfen → in die Tabelle
Der Workflow schreibt, liest sofort wieder aus und vergleicht mit dem, was er geschrieben hat. Das Ergebnis geht als Klartext in die Ergebnistabelle:
Yoast gesetzt: Titel, Beschreibung, Keyphrase- oder
ACHTUNG Yoast nicht gesetzt – _yoast_wpseo_metadesc (Feld nicht in der REST-Antwort)
Die zweite Meldung heißt in der Praxis fast immer: Die Freigabedatei liegt noch nicht am Platz. Aber sie fängt eben auch den Fall ab, dass Yoast irgendwann seine Feldnamen ändert – dann steht es in der Tabelle statt in meinem Gedächtnis.
Eine Ergänzung war dafür noch nötig, und die ist inhaltlich die interessantere: Der Blog Planner erzeugte bisher gar keine Fokus-Keyphrase. Titel, Slug, Anriss, Meta-Beschreibung – ja. Aber nicht das eine Feld, gegen das Yoast überhaupt prüft. Prompt und Ausgabeschema haben deshalb einen Zusatz bekommen:
Nenne die eine Suchphrase, für die dieser Artikel ranken soll. Zwei bis fünf Wörter, so wie ein Mensch sie eingeben würde. Sie muss im Titel, in der Einleitung und in der Meta-Beschreibung wörtlich vorkommen. Keine Aufzählung, keine Alternativen.
Das „keine Alternativen“ ist kein Schmuck. Ohne diesen Halbsatz liefern Modelle zuverlässig drei Vorschläge mit Schrägstrich dazwischen.
Zwei Workflows, zwei Aufgaben
Neue Beiträge im Lauf, Bestand per Nachpflege
An dieser Stelle kam die Frage auf, ob man das nicht besser als eigenen, periodisch laufenden Workflow baut. Die Antwort ist: beides – aber für verschiedene Fälle.
| im Artikelworkflow | im Nachpflege-Workflow | |
|---|---|---|
| für | die 1.121 neuen Beiträge | die 78 vorhandenen |
| Datenlage | Titel, Beschreibung und Keyphrase liegen im Lauf schon vor | müssen aus Titel und Anriss neu erzeugt werden |
| Kosten | null zusätzliche Modellaufrufe | ein Modellaufruf je Beitrag |
| zusätzlich | — | fängt ab, wenn der Artikelworkflow einmal scheitert |
Für neue Beiträge wäre die Nachpflege der teurere Umweg: Die Daten würden weggeworfen und später noch einmal erzeugt. Für den Bestand ist sie der einzige Weg. Und als Netz darunter ist sie unabhängig davon wertvoll – sie meldet jeden Beitrag, bei dem etwas fehlt, egal warum.
Der Nachpflege-Workflow hat 14 Nodes und läuft montags um 6 Uhr. Er holt alle Beiträge – veröffentlichte und Entwürfe – mit context=edit, seitenweise, sucht die, bei denen eines der drei Felder leer ist, erzeugt für höchstens zehn davon Vorschläge aus Titel und Anriss und schreibt für jeden bearbeiteten Beitrag eine Zeile in ein eigenes Tabellenblatt.
Drei Sicherungen
Ein Workflow, der ungefragt in bestehende Beiträge schreibt, macht mich nervös. Deshalb hat dieser drei Bremsen:
Er läuft zunächst als reiner Bericht. In seinem Einstellungs-Node steht nur_bericht = true. In diesem Zustand erzeugt er Vorschläge, schreibt sie in die Tabelle und fasst WordPress nicht an. Erst wenn ich die Vorschläge gesehen habe und einverstanden bin, setze ich den Wert auf false.
Er überschreibt nie. Ein Feld, in dem etwas steht, wird nicht angerührt – auch nicht, wenn der Vorschlag besser wäre. Was ich von Hand eingetragen habe, bleibt.
Er erkennt die fehlende Freigabe von selbst und bricht mit Klartext ab, statt zehn wirkungslose Schreibversuche zu machen:
„Die Yoast-Felder sind über die REST-API nicht sichtbar. Bitte zuerst die Datei yoast-rest-freigabe.php in wp-content/mu-plugins/ ablegen.“
Zehn Beiträge pro Lauf sind bewusst wenig. Für 78 Bestandsbeiträge reicht das in acht Wochen – und wenn es schneller gehen soll, stelle ich den Wert hoch und löse den Workflow von Hand aus.

Das Beitragsende
70.000 Wörter identischer Text
Während ich am SEO-Ende gearbeitet habe, ist mir aufgefallen, was am anderen Ende jedes Beitrags stand:
| Handlungsaufforderung | ein Facebook-Button, 172 Zeichen |
| „Über uns“ | 62 Wörter Standardtext, beginnend mit „Spürst du den Ruf der Wildnis?“ |
| Varianten über alle 1.121 geplanten Zeilen | eine einzige |
Hochgerechnet sind das rund 70.000 Wörter identischer Text – genau an der Stelle, an der ein Leser steht, der den ganzen Beitrag gelesen hat. Also der wertvollste Leser, den ich habe.
Bemerkenswert daran: Die Tabellenspalten dafür sind pro Zeile gedacht. Die Möglichkeit zur Variation war die ganze Zeit da. Sie wurde nur nie genutzt.
An die Stelle des Facebook-Buttons ist ein Weiterlesen-Block getreten: zwei bis drei verwandte Beiträge mit Titel und Anriss. Und zwar aus genau den Kandidaten, die der Verwandtschafts-Node aus Teil 5 ohnehin schon berechnet hat – das kostet keine zusätzliche Rechenoperation.
Ein Detail, das mir wichtig war: Beiträge, die im Fließtext bereits verlinkt wurden, werden hier übersprungen, solange genug andere übrig bleiben. So verlinkt jeder Beitrag auf mehr verschiedene Seiten, statt zweimal auf dieselbe.
Und nebenbei löst das einen Teil des Problems, das ich am Ende von Teil 5 als offen markiert hatte: Neue Beiträge bekommen so wenigstens von ihren Nachfolgern eingehende Links.
Der „Über uns“-Text ist ersatzlos aus den Beiträgen heraus – aber nicht in den Papierkorb. Er ist Seiteninformation und gehört ins Theme: in den Fußbereich oder in eine Autorenbox unter jedem Beitrag. Dort steht er einmal, wird einmal gepflegt und liegt nicht 1.121-mal in der Datenbank.
Der Hinweisblock – und warum keine Notrufnummer drinsteht
An die Stelle des „Über uns“-Blocks tritt bei bestimmten Beiträgen ein Hinweis. Erkannt wird das über die Kategorie und über Stichwörter im Thema:
| Beiträge von 1.121 | |
|---|---|
| nur rechtlicher Hinweis | 56 |
| nur gesundheitlicher Hinweis | 120 |
| beide | 19 |
| kein Hinweis | 926 |
Die Zuordnung ist bewusst großzügig: lieber ein Hinweis zu viel als einer zu wenig. Das erzeugt Fälle, die man eigenartig finden kann – „Hygiene unterwegs: Waschen, Zähne, Toilette“ bekommt einen gesundheitlichen Hinweis, „Trekking im Ausland: Vorbereitung, Papiere und Versicherung“ einen rechtlichen. Beides ist vertretbar, aber nicht zwingend.
Die Grenze der Lösung ist ehrlicherweise diese: Die Erkennung greift nur auf Titel und Kategorie zu, nicht auf den fertigen Text. Ein Beitrag, der erst im Fließtext auf ein Rechtsthema kommt, bleibt unerkannt. Damit ich das kontrollieren kann, schreibt der Workflow in die Ergebnistabelle eine Spalte mit dem Wert Recht, Gesundheit, Recht + Gesundheit oder keiner. Nach fünfzig Beiträgen sehe ich daran, ob die Stichwortlisten nachgeschärft werden müssen.
Und ein Punkt, der mir persönlich wichtig ist: Im gesundheitlichen Hinweis steht die 112, aber keine Giftnotruf-Nummer. Die Giftinformationszentralen in Deutschland sind regional organisiert und haben unterschiedliche Nummern. Eine aus dem Gedächtnis einzusetzen, wäre genau die Art von plausibel klingender Angabe, die im Ernstfall Zeit kostet. Also steht dort „die zuständige Giftinformationszentrale“ – und wenn ich die für meine Region nachgeschlagen habe, ist es eine Zeile im Node.
Bei einem Text, der 195-mal auf einer Seite stehen soll, ist das kein Detail.
Fazit
Zum Schluss eine Einordnung, die dir womöglich Arbeit erspart.
Die Ampel im Yoast-Kasten – grün, orange, rot – ist ein Redaktionshilfsmittel, kein Rankingfaktor. Sie wird im Browser berechnet, wenn du den Beitrag im Editor öffnest, und in einem eigenen Feld gespeichert. Ein per API angelegter Beitrag hat dort nichts stehen, und die Ampel bleibt grau, bis du ihn einmal öffnest. Nach meinem Kenntnisstand sieht Google diesen Wert nicht. Ich habe deshalb nicht versucht, ihn zu berechnen – das wäre Aufwand für ein Symbol.
Überhaupt ist die Erwartung zu justieren: Meine Seiten waren nie „ohne SEO“. Yoast erzeugt aus dem Beitrag heraus schon ohne jede Einstellung title, canonical, robots, Open-Graph-Angaben und einen vollständigen strukturierten Datensatz mit Article, WebPage, BreadcrumbList, Organization und Person. Was tatsächlich fehlte, war die eigene Meta-Beschreibung – und die ist der Teil, den Google als Snippet anzeigen kann.
Der Aufwand für diesen Teil: eine kleine PHP-Datei, drei Nodes im Artikelworkflow, ein Nachpflege-Workflow mit vierzehn Nodes, ein Code-Node für die Abschlussblöcke. Der Ertrag: 1.121 Beiträge, die ein eigenes Snippet mitbringen, ein Beitragsende, das nicht 1.121-mal gleich aussieht, und eine Tabellenspalte, die mir sagt, wenn etwas davon nicht geklappt hat.
Im nächsten Teil geht es endlich um die Frage, die mir von Anfang an im Kopf herumging: Schreibt ein besseres Modell bessere Texte? Die Antwort ist unbequemer als erwartet – und sie beginnt damit, dass in einem einzigen Beitrag zehnmal das Wort „entscheidend“ steht.
Alle Teile der Serie
- Teil 1: Null Klicks in drei Monaten
- Teil 2: 120 Nodes geerbt
- Teil 3: Schlachttiere im Wildbret-Beitrag
- Teil 4: Vier Beiträge in zwei Sekunden
- Teil 5: Interne Verlinkung, neu gebaut
- Teil 6: Yoast über die REST-API (dieser Beitrag)
- Teil 7: Stil, Modelle und Kosten
- Teil 8: Bilanz nach zwei Tagen
◀ Zurück zu Teil 5: Interne Verlinkung, neu gebaut | Weiter zu Teil 7: Stil, Modelle und Kosten ▶


[…] hat, was nicht, und was am Ende dabei herauskam. Zu den anderen Teilen: 1 · 2 · 3 · 4 · 5 · 6 · 7 · […]