API rewriter.io
Rufe über eine einfache, gut dokumentierte Read-only-API veröffentlichte Artikel aus deinem Projekt ab - direkt in deinen eigenen Blog. REST, JSON, API-Schlüssel, Filterung, Sortierung und Paginierung.
Einführung
Die Basis-URL der API lautet https://public-api.rewriter.io/v1. Alle Antworten werden im JSON-Format zurückgegeben (Schlüssel im snake_case-Stil), und der Artikeltext ist verfügbar als markdown und html. Jede Anfrage erfordert einen API-Schlüssel. Die API unterstützt ausschließlich den Lesezugriff auf veröffentlichte Inhalte.
Verwende in der Testumgebung die Adresse https://dev-hooks.rewriter.io/v1.
Für KI-Agenten und LLMs stellen wir einen maschinenlesbaren Index dieser Dokumentation bereit unter llms.txt.
Authentifizierung
Übergib den Schlüssel im Header Authorization als Bearer-Token. Der Schlüssel ist mit einem einzigen Projekt verknüpft.
# Prüfen, zu welchem Projekt der Schlüssel gehört curl https://public-api.rewriter.io/v1/me \ -H "Authorization: Bearer rw_live_3f8a…"
Limits und Versionierung
Die API ist im Pfad versioniert (/v1). Das Anfragelimit hängt vom Tarif ab und wird für jeden API-Schlüssel separat gezählt.
| Tarif | Limit / Min. |
|---|---|
| Start | 60 |
| Solo | 150 |
| Pro | 300 |
| Max | 1.000 |
Antworten für Tarife mit Limit enthalten die Header X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset. Bei einem unbegrenzten Tarif werden keine X-RateLimit-*-Header gesendet.
- GET-Anfragen sind aus dem Browser zugänglich (CORS).
- Alle Zeitstempel im Format ISO 8601 (UTC).
Fehler
Fehler geben wir mit dem passenden HTTP-Code und einer einheitlichen Struktur zurück:
{
"error": {
"code": "not_found",
"message": "Article not found."
}
}400- ungültige Abfrageparameter401- fehlender oder ungültiger API-Schlüssel403- dein Tarif umfasst keinen API-Zugriff404- nicht gefunden (Artikel nicht veröffentlicht oder außerhalb des Projekts)429- Anfragelimit überschritten500- Serverfehler
Paginierung und Sortierung
Listen geben wir in einem Umschlag mit Datenfeldern und Seiten-Metadaten zurück:
{
"data": [
"…"
],
"page": 1,
"per_page": 10,
"total": 42
}Die Paginierung steuerst du mit den Parametern page (ab 1) und limit (Standard 10, max. 100). Die Sortierung legst du mit dem Parameter sort fest - das Präfix „-” bedeutet absteigende Reihenfolge. Zulässige Werte: published_at, -published_at, title, -title, updated_at, -updated_at.
Projekt
Gibt Informationen über das mit dem Schlüssel verknüpfte Projekt sowie die verfügbaren Sprachen zurück. Nützlich zur Überprüfung des Schlüssels.
{
"id": "k17a9c…",
"name": "Kawiarnia Pod Lipą",
"primary_language": "pl",
"available_languages": [
"pl",
"en"
],
"plan": "Pro",
"rate_limit_per_minute": 300
}Themen
Gibt die Liste der Projektthemen zurück. Verwende das Feld id als Wert des Filters topic_id in der Artikelliste.
{
"data": [
{
"id": "j57b2…",
"title": "Lokalne SEO"
},
{
"id": "j58c1…",
"title": "Porady baristów"
}
]
}Kategorien
Gibt die Liste der Projektkategorien zurück. Verwende das Feld id als Wert des Filters category_id in der Artikelliste. Die Namen folgen dem Parameter language (Standard: Hauptsprache).
{
"data": [
{
"id": "k20a1…",
"name": "Pielęgnacja ogrodu",
"slug": "pielegnacja-ogrodu"
},
{
"id": "k20a2…",
"name": "Porady",
"slug": "porady"
}
]
}Artikel auflisten
Gibt eine paginierte Liste veröffentlichter Artikel zurück (Zusammenfassungsfelder, ohne Text).
Abfrageparameter
topic_id- string, optional. Nach Themen-Identifikator filtern.category_id- string, optional. Nach Kategorie-Identifikator filtern.language- string, optional. Sprachcode; standardmäßig die Hauptsprache des Projekts. Ein anderer Code gibt veröffentlichte Übersetzungen zurück.q- string, optional. Suche nach Titel (ohne Unterscheidung von Groß- und Kleinschreibung).published_after- ISO-8601-Datum, optional. Nur Artikel, die ab diesem Datum veröffentlicht wurden.published_before- ISO-8601-Datum, optional. Nur Artikel, die bis zu diesem Datum veröffentlicht wurden.sort- string, Standard -published_at. Siehe Abschnitt Paginierung und Sortierung.page- Zahl, Standard 1.limit- Zahl, Standard 10, max. 100.
Lass einen Parameter, den du nicht brauchst, einfach weg - ein leerer Wert (z. B. sort=) wird genauso behandelt wie ein fehlender Parameter.
{
"data": [
{
"id": "m93f7…",
"title": "10 sposobów na lokalne SEO",
"slug": "10-sposobow-na-lokalne-seo",
"language": "pl",
"topic_id": "j57b2…",
"category": {
"id": "k20a1…",
"name": "Pielęgnacja ogrodu",
"slug": "pielegnacja-ogrodu"
},
"status": "published",
"seo_score": 96,
"readability_score": 72,
"fact_check_status": "passed",
"cover_image": "https://cdn.example.com/articles/m93f7/cover.png",
"published_at": "2026-05-21T09:12:00.000Z",
"updated_at": "2026-05-22T10:00:00.000Z"
}
],
"page": 1,
"per_page": 10,
"total": 42
}Artikel abrufen
Gibt den vollständigen Text eines veröffentlichten Artikels samt SEO-Metadaten zurück. Der Text ist als Markdown und als HTML-Fragment verfügbar. Der Parameter :id akzeptiert die vollständige Artikel-ID; der rewriter.io-Blog akzeptiert zusätzlich eine slug-8-Zeichen-Referenz.
Abfrageparameter
language- string, optional. Sprachcode, um eine veröffentlichte Übersetzung statt der Version in der Hauptsprache abzurufen.format- markdown oder html, optional. Standardmäßig geben wir beide Textfelder zurück.
{
"id": "m93f7…",
"title": "10 sposobów na lokalne SEO",
"slug": "10-sposobow-na-lokalne-seo",
"topic_id": "j57b2…",
"category": {
"id": "k20a1…",
"name": "Pielęgnacja ogrodu",
"slug": "pielegnacja-ogrodu"
},
"language": "pl",
"status": "published",
"body_markdown": "## Wstęp\n\nLokalne SEO to…",
"body_html": "<h2>Wstęp</h2>\n<p>Lokalne SEO to…</p>",
"cover_image": "https://cdn.example.com/articles/m93f7/cover.png",
"meta_title": "Lokalne SEO dla kawiarni",
"meta_description": "Praktyczny przewodnik po lokalnym SEO.",
"seo_score": 96,
"readability_score": 72,
"readability_label": "łatwy",
"fact_check_status": "passed",
"uniqueness_score": 98,
"alternate_slugs": [
{
"language": "pl",
"slug": "10-sposobow-na-lokalne-seo"
},
{
"language": "en",
"slug": "10-ways-to-improve-local-seo"
}
],
"json_ld": {
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "10 sposobów na lokalne SEO",
"inLanguage": "pl",
"wordCount": 1240,
"…": "…"
},
"published_at": "2026-05-21T09:12:00.000Z",
"updated_at": "2026-05-22T10:00:00.000Z"
}Artikel in einer HTML-Vorlage
Gibt eine fertige HTML-Seite des veröffentlichten Artikels zurück, eingebettet in die Projektvorlage (text/html statt JSON). Unterstützt den Parameter language. Ideal zur direkten Einbettung auf einer Website.
curl https://public-api.rewriter.io/v1/articles/m93f7…/html \
-H "Authorization: Bearer rw_live_3f8a…"Webhooks
Webhooks senden signierte POST-Anfragen an deine URL, wenn in deinem Projekt Inhaltsereignisse auftreten. Konfiguriere sie im Dashboard im Bereich Konto → API & Integrationen.
Du kannst sie auch programmatisch registrieren, allein mit einem API-Schlüssel - ohne Schritt im Dashboard. Siehe Webhook-Abonnements.
Verfügbare Ereignisse
article.published- ein Artikel wurde veröffentlicht.article.scheduled- ein Artikel wurde zur Veröffentlichung geplant.article.unpublished- die Veröffentlichung eines Artikels wurde zurückgenommen.article.archived- ein Artikel wurde archiviert.article.restored- ein Artikel wurde aus dem Archiv wiederhergestellt.article.translated- eine Artikelübersetzung wurde veröffentlicht.topic.created- ein neues Thema wurde erstellt.headline.created- neue Artikelvorschläge (Überschriften) wurden generiert.
Anfragetext
Jede Anfrage enthält einen JSON-Umschlag mit id (die Zustellungs-ID - nutze sie zur Deduplizierung), event, created_at, project_id und data mit den Ereignisdetails:
{
"id": "whd_4f2a…",
"event": "article.published",
"created_at": "2026-05-21T09:12:00.000Z",
"project_id": "k17a9c…",
"data": {
"id": "m93f7…",
"title": "10 sposobów na lokalne SEO",
"slug": "10-sposobow-na-lokalne-seo",
"language": "pl",
"status": "published",
"topic_id": "j57b2…",
"category": {
"id": "k20a1…",
"name": "Pielęgnacja ogrodu",
"slug": "pielegnacja-ogrodu"
},
"seo_score": 96,
"readability_score": 72,
"fact_check_status": "passed",
"published_at": "2026-05-21T09:12:00.000Z",
"updated_at": "2026-05-21T09:12:00.000Z"
}
}Signaturprüfung
Jede Anfrage enthält den Header X-Rewriter-Webhook-Signature mit einer HMAC-SHA256-Signatur über den Zeitstempel (Header X-Rewriter-Webhook-Timestamp), einen Punkt und den Anfragetext im Format sha256=<hex>. Berechne sie mit deinem Secret neu und vergleiche zeitkonstant.
const ts = req.headers["x-rewriter-webhook-timestamp"];
const sig = req.headers["x-rewriter-webhook-signature"];
const expected = "sha256=" + crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(ts + "." + rawBody)
.digest("hex");
const ok = crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));Wiederholungen und automatische Deaktivierung
Fehlgeschlagene Zustellungen werden mit zunehmendem Abstand wiederholt (bis zu 5 Versuche), wobei bei jedem Versuch dieselbe Zustellungs-ID gesendet wird. Nach vielen aufeinanderfolgenden Fehlern wird der Webhook automatisch deaktiviert - aktiviere ihn im Dashboard erneut.
Webhook-Abonnements
Du kannst Webhook-Callbacks programmatisch registrieren und entfernen, allein mit einem API-Schlüssel - ohne Schritt im Dashboard. Diese Endpunkte treiben die sofortigen Trigger unserer Zapier- und Make.com-Apps an und lassen sich auch in deiner eigenen Integration nutzen.
POST und GET setzen zusätzlich einen Tarif mit Webhooks voraus - andernfalls antworten sie mit 403 forbidden. DELETE wird allein über den API-Schlüssel autorisiert, sodass das Entfernen eines Abonnements auch nach einem Tarifwechsel funktioniert.
Abonnement anlegen
Registriert eine Callback-URL für genau ein Ereignis und liefert das Abonnement-Objekt mit Status 201 zurück (ohne data-Hülle). Speichere die zurückgegebene id - du übergibst sie beim Löschen des Abonnements.
Anfragetext
target_url- erforderlich. Eine HTTPS-Callback-URL auf einem der erlaubten Hosts.event- erforderlich. Ein Ereignis aus der Liste oben.
curl -X POST https://public-api.rewriter.io/v1/webhooks \ -H "Authorization: Bearer rw_live_3f8a…" \ -H "Content-Type: application/json" \ -d '{"target_url":"https://hook.eu2.make.com/abc123","event":"article.published"}'
{
"id": "n41c8…",
"event": "article.published",
"target_url": "https://hook.eu2.make.com/abc123",
"status": "enabled"
}Abonnement-Objekt
id- die Abonnement-ID - übergib sie an DELETE.event- das Ereignis, für das das Abonnement registriert ist.target_url- die registrierte Callback-URL.status- enabled oder disabled - ein Abonnement wird nach wiederholt fehlgeschlagenen Zustellungen automatisch deaktiviert.
Erlaubte target_url-Hosts
target_url muss eine HTTPS-Hook-URL einer Automatisierungsplattform auf einem dieser Hosts sein:
hooks.zapier.com- Zapier Catch-Hook-URLs.hook.make.com, hook.<zone>.make.com- Make.com-Webhooks, zum Beispiel hook.eu2.make.com.
Jeder andere Host, eine Nicht-HTTPS-URL, eine URL mit Zugangsdaten sowie private, Loopback- oder Metadaten-Adressen werden mit 400 bad_request abgelehnt.
Dieselbe Kombination aus target_url und event erneut zu senden erzeugt kein Duplikat: Das bestehende Abonnement wird reaktiviert und mit derselben id zurückgegeben. Ein Projekt kann bis zu 20 Abonnements pro Plattform halten.
Abonnements auflisten
Liefert die mit diesem API-Schlüssel in diesem Projekt erstellten Abonnements. Abonnements anderer Schlüssel und im Dashboard konfigurierte Webhooks werden nie zurückgegeben.
{
"data": [
{
"id": "n41c8…",
"event": "article.published",
"target_url": "https://hook.eu2.make.com/abc123",
"status": "enabled"
}
]
}Abonnement löschen
Löscht das Abonnement mit der angegebenen id. Idempotent: eine unbekannte, bereits gelöschte oder fremde id liefert 200 mit deleted: false statt 404, sodass das Aufräumen nie fehlschlägt.
{
"id": "n41c8…",
"deleted": true
}Fehler
400 bad_request- target_url oder event fehlt, unbekanntes Ereignis oder eine target_url außerhalb der erlaubten Hosts.401 unauthorized- fehlender oder ungültiger API-Schlüssel.403 forbidden- der Tarif enthält keine Webhooks oder das Limit von 20 Abonnements ist erreicht.
Diese Antworten enthalten dieselben Header X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset wie die Lese-Endpunkte.