WordPress Self-Hosted Integration
Wie Contento Artikel direkt über die REST API auf deiner WordPress-Website veröffentlicht, welche Anfragen gesendet werden und wie du sie mit curl zum Debuggen manuell reproduzieren kannst.
1. Funktionsweise
Um einen Artikel zu veröffentlichen, sendet Contento zwei HTTP-Anfragen an die WordPress REST API:
- Hauptbild hochladen an
/wp-json/wp/v2/mediaund die zurückgegebene ID speichern. - Artikel erstellen per POST an
/wp-json/wp/v2/posts, wobei die Bild-ID alsfeatured_mediaverwendet wird.
Wenn du bestätigen möchtest, dass die Integration die Anfragen korrekt sendet, kannst du diese Aufrufe mit den nachstehenden Beispielen manuell reproduzieren.
2. Authentifizierung
Alle Anfragen verwenden Basic Auth über HTTPS mit einem Application Password, das in WordPress generiert wurde (Benutzer → Profil → Anwendungspasswörter). Das reguläre Konto-Passwort wird nicht verwendet.
Authorization: Basic <base64(benutzername:app_passwort)>
Für die folgenden Beispiele konfiguriere zwei Variablen in der Shell:
SITE="https://example.com"
AUTH=$(printf '%s' 'WP_BENUTZERNAME:APP_PASSWORT' | base64)
3. Schritt 1 — Hauptbild hochladen
Das Bild wird als Anhang auf WordPress hochgeladen. WordPress antwortet mit einem JSON, das das Feld id enthält — dieses wird im nächsten Schritt benötigt.
curl -i -X POST "$SITE/wp-json/wp/v2/media" \
-H "Authorization: Basic $AUTH" \
-H "Content-Type: image/jpeg" \
-H 'Content-Disposition: attachment; filename="test.jpg"' \
-H "User-Agent: Contento/1.0" \
--data-binary "@$HOME/test.jpg"
Achte auf diese häufigen Fehlerquellen:
Content-Typemuss dem tatsächlichen Dateityp entsprechen (image/pngfür PNG usw.). Prüfen mitfile image.jpg.- Das Argument
--data-binarymuss mit@beginnen — sonst sendet curl die Zeichenkette selbst, nicht den Dateiinhalt. - Die Tilde (
~) wird innerhalb des@-Arguments nicht expandiert — verwende$HOMEoder einen absoluten Pfad.
Erfolgreiche Antwort (HTTP 201):
{
"id": 5738,
"source_url": "https://example.com/wp-content/uploads/2026/05/test.jpg",
"media_type": "image",
...
}
4. Schritt 2 — Artikel mit Hauptbild erstellen
Ersetze MEDIA_ID durch die id aus dem vorherigen Schritt:
curl -i -X POST "$SITE/wp-json/wp/v2/posts" \
-H "Authorization: Basic $AUTH" \
-H "Content-Type: application/json" \
-H "User-Agent: Contento/1.0" \
-d '{
"title": "Test featured image",
"content": "<p>Body</p>",
"status": "publish",
"slug": "test-featured-image",
"featured_media": MEDIA_ID
}'
Eine HTTP-201-Antwort mit "featured_media": <selbe id> und der Klasse has-post-thumbnail in class_list bestätigt, dass WordPress das Bild korrekt mit dem Artikel verknüpft hat.
5. Von Contento gesendete Felder
Für jeden veröffentlichten Artikel erstellt Contento einen Body dieser Form:
{
"title": "Titel des Artikels",
"content": "<html-inhalt des artikels>",
"status": "publish",
"excerpt": "Meta-Beschreibung",
"slug": "artikel-slug",
"categories": [123],
"tags": [456, 789],
"featured_media": 999,
"meta": {
"_yoast_wpseo_focuskw": "focus keyword",
"rank_math_focus_keyword": "focus keyword",
"_aioseo_keywords": "focus keyword"
}
}
Das Feld featured_media erscheint nur, wenn das Hochladen des Bildes erfolgreich war. Das Feld meta enthält das Focus-Keyword für die drei gängigen SEO-Plugins (Yoast, Rank Math, All in One SEO).
6. Häufige Probleme
Bild wird auf der Artikelseite nicht angezeigt
Wenn die Antwort aus Schritt 2 "featured_media" und die Klasse has-post-thumbnail enthält, das Bild aber im Browser trotzdem nicht sichtbar ist, liegt das Problem am WordPress-Theme, nicht an der Integration. Das Theme-Template muss die Funktion the_post_thumbnail() im Single-Post-Layout aufrufen — viele Custom-Themes oder mit Page-Buildern erstellte Themes tun dies nicht standardmäßig oder verstecken das Bild hinter einem Customizer-Toggle.
Ein typisches Anzeichen: Das Bild erscheint in Social-Media-Shares (OG / Twitter Card) und in strukturierten Yoast-Daten, aber nicht auf der Seite — da SEO-Plugins featured_media direkt auslesen, ohne das Template zu benötigen.
HTTP 400 rest_upload_no_data
curl hat einen leeren Body gesendet — die Datei existiert nicht unter dem angegebenen Pfad, oder das Präfix @ vor dem Pfad fehlt. Prüfe mit ls -la, ob die Datei existiert und eine Größe größer als null hat.
HTTP 500 rest_upload_sideload_error
WordPress kann den Dateityp nicht erkennen — entweder stimmt Content-Type nicht mit dem tatsächlichen Inhalt überein (z. B. PNG mit image/jpeg gesendet), oder der Body ist eine beliebige Zeichenkette (fehlendes @ bei --data-binary).
HTML-Antwort statt JSON
Wenn die Antwort mit <!doctype html> oder <html> beginnt, blockiert eine Firewall oder ein Sicherheits-Plugin (Wordfence, iThemes Security usw.) /wp-json/. Überprüfe die Firewall-Regeln und die Whitelist des Sicherheits-Plugins.
HTTP 401 oder 403
Das Anwendungspasswort ist falsch oder deaktiviert. Generiere ein neues unter Benutzer → Profil → Anwendungspasswörter und aktualisiere die Integration im Dashboard. Achtung: Die Leerzeichen zwischen den Zeichengruppen sind Teil des Passworts.
7. Kontakt
Bei Problemen mit der WordPress Self-Hosted Integration schreibe uns an [email protected] mit der URL deiner Website und den bereits versuchten Schritten.