Zacznij za darmo
Dokumentacja API · v1

API rewriter.io

Pobieraj opublikowane artykuły ze swojego projektu przez proste, dobrze udokumentowane API tylko do odczytu - prosto na własnego bloga. REST, JSON, klucz API, filtrowanie, sortowanie i paginacja.

Wprowadzenie

Bazowy adres API to https://public-api.rewriter.io/v1. Wszystkie odpowiedzi zwracane są w formacie JSON (klucze w stylu snake_case), a treść artykułu dostępna jest jako markdown i html. Każde żądanie wymaga klucza API. API obsługuje wyłącznie odczyt opublikowanych treści.

Wskazówka: klucz API wygenerujesz w panelu w sekcji Konto → API i integracje. Trzymaj go po stronie serwera - nie umieszczaj w kodzie front-endu.

W środowisku testowym używaj adresu https://dev-hooks.rewriter.io/v1.

Dla agentów AI i modeli LLM udostępniamy maszynowy indeks tej dokumentacji w pliku llms.txt.

Uwierzytelnianie

Przekaż klucz w nagłówku Authorization jako Bearer token. Klucz jest powiązany z jednym projektem.

terminal
# Sprawdź, do którego projektu należy klucz
curl https://public-api.rewriter.io/v1/me \
  -H "Authorization: Bearer rw_live_3f8a…"

Limity i wersjonowanie

API jest wersjonowane w ścieżce (/v1). Limit zapytań jest zależny od planu i liczony osobno dla każdego klucza API.

PlanLimit / min
Start60
Solo150
Pro300
Max1000

Odpowiedzi dla planów z limitem zawierają nagłówki X-RateLimit-Limit, X-RateLimit-Remaining i X-RateLimit-Reset. Przy planie bez limitu nagłówki X-RateLimit-* nie są wysyłane.

  • Żądania GET są dostępne z przeglądarki (CORS).
  • Wszystkie znaczniki czasu w formacie ISO 8601 (UTC).

Błędy

Błędy zwracamy z odpowiednim kodem HTTP i jednolitą strukturą:

error
{
  "error": {
    "code": "not_found",
    "message": "Article not found."
  }
}
  • 400 - nieprawidłowe parametry zapytania
  • 401 - brak lub nieprawidłowy klucz API
  • 403 - Twój plan nie obejmuje dostępu do API
  • 404 - nie znaleziono (artykuł nieopublikowany lub spoza projektu)
  • 429 - przekroczono limit zapytań
  • 500 - błąd serwera

Paginacja i sortowanie

Listy zwracamy w kopercie z polami danych i metadanymi stron:

GET /v1/articles
{
  "data": [
    "…"
  ],
  "page": 1,
  "per_page": 10,
  "total": 42
}

Paginację sterujesz parametrami page (od 1) oraz limit (domyślnie 10, maks. 100). Sortowanie ustawiasz parametrem sort - prefiks „-” oznacza kolejność malejącą. Dozwolone wartości: published_at, -published_at, title, -title, updated_at, -updated_at.

Projekt

GET/v1/me

Zwraca informacje o projekcie powiązanym z kluczem oraz dostępne języki. Przydatne do weryfikacji klucza.

GET /v1/me
{
  "id": "k17a9c…",
  "name": "Kawiarnia Pod Lipą",
  "primary_language": "pl",
  "available_languages": [
    "pl",
    "en"
  ],
  "plan": "Pro",
  "rate_limit_per_minute": 300
}

Tematy

GET/v1/topics

Zwraca listę tematów projektu. Użyj pola id jako wartości filtra topic_id na liście artykułów.

GET /v1/topics
{
  "data": [
    {
      "id": "j57b2…",
      "title": "Lokalne SEO"
    },
    {
      "id": "j58c1…",
      "title": "Porady baristów"
    }
  ]
}

Kategorie

GET/v1/categories

Zwraca listę kategorii projektu. Użyj pola id jako wartości filtra category_id na liście artykułów. Nazwy są w języku z parametru language (domyślnie język główny).

GET /v1/categories
{
  "data": [
    {
      "id": "k20a1…",
      "name": "Pielęgnacja ogrodu",
      "slug": "pielegnacja-ogrodu"
    },
    {
      "id": "k20a2…",
      "name": "Porady",
      "slug": "porady"
    }
  ]
}

Lista artykułów

GET/v1/articles

Zwraca stronicowaną listę opublikowanych artykułów (pola podsumowania, bez treści).

Parametry zapytania

  • topic_id - string, opcjonalny. Filtruj po identyfikatorze tematu.
  • category_id - string, opcjonalny. Filtruj po identyfikatorze kategorii.
  • language - string, opcjonalny. Kod języka; domyślnie język główny projektu. Inny kod zwraca opublikowane tłumaczenia.
  • q - string, opcjonalny. Wyszukiwanie po tytule (bez rozróżniania wielkości liter).
  • published_after - data ISO 8601, opcjonalna. Tylko artykuły opublikowane od tej daty.
  • published_before - data ISO 8601, opcjonalna. Tylko artykuły opublikowane do tej daty.
  • sort - string, domyślnie -published_at. Patrz sekcja Paginacja i sortowanie.
  • page - liczba, domyślnie 1.
  • limit - liczba, domyślnie 10, maks. 100.

Parametru, którego nie używasz, po prostu nie wysyłaj - pustą wartość (np. sort=) traktujemy tak samo jak brak parametru.

GET /v1/articles?sort=-published_at&limit=10
{
  "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
}

Pobierz artykuł

GET/v1/articles/:id

Zwraca pełną treść opublikowanego artykułu wraz z metadanymi SEO. Treść dostępna jest jako Markdown i jako fragment HTML. Parametr :id przyjmuje pełne id artykułu; pierwszy blog rewriter.io obsługuje też referencję slug-8znaków.

Parametry zapytania

  • language - string, opcjonalny. Kod języka, aby pobrać opublikowane tłumaczenie zamiast wersji w języku głównym.
  • format - markdown lub html, opcjonalny. Domyślnie zwracamy oba pola treści.
GET /v1/articles/m93f7…
{
  "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"
}

Artykuł w szablonie HTML

GET/v1/articles/:id/html

Zwraca gotową stronę HTML opublikowanego artykułu, opakowaną w szablon projektu (text/html zamiast JSON). Obsługuje parametr language. Idealne do bezpośredniego osadzenia na stronie.

terminal
curl https://public-api.rewriter.io/v1/articles/m93f7…/html \
  -H "Authorization: Bearer rw_live_3f8a…"

Webhooki

Webhooki wysyłają podpisane żądania POST na Twój adres URL, gdy w projekcie zachodzą zdarzenia treści. Skonfiguruj je w panelu w sekcji Konto → API i integracje.

Możesz je też zarejestrować programowo, samym kluczem API - bez wchodzenia do panelu. Zobacz Subskrypcje webhooków.

Dostępne zdarzenia

  • article.published - artykuł został opublikowany.
  • article.scheduled - zaplanowano publikację artykułu.
  • article.unpublished - cofnięto publikację artykułu.
  • article.archived - artykuł zarchiwizowano.
  • article.restored - artykuł przywrócono z archiwum.
  • article.translated - opublikowano tłumaczenie artykułu.
  • topic.created - utworzono nowy temat.
  • headline.created - wygenerowano nowe propozycje artykułów (nagłówki).

Treść żądania

Każde żądanie ma kopertę JSON z polami id (identyfikator dostawy - użyj go do deduplikacji), event, created_at, project_id oraz data ze szczegółami zdarzenia:

POST (webhook)
{
  "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"
  }
}

Weryfikacja podpisu

Każde żądanie zawiera nagłówek X-Rewriter-Webhook-Signature z podpisem HMAC-SHA256 z połączenia znacznika czasu (nagłówek X-Rewriter-Webhook-Timestamp), kropki i treści żądania, w formacie sha256=<hex>. Policz podpis swoim sekretem i porównaj go w sposób odporny na czas.

verify (node)
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));

Ponawianie i wyłączanie

Nieudane dostawy ponawiamy z rosnącym odstępem (do 5 prób), wysyłając przy każdej próbie ten sam identyfikator dostawy. Po wielu kolejnych niepowodzeniach webhook jest automatycznie wyłączany - włącz go ponownie w panelu.

Subskrypcje webhooków

Webhooki możesz rejestrować i usuwać programowo, samym kluczem API - bez wchodzenia do panelu. Z tych punktów końcowych korzystają nasze aplikacje Zapier i Make.com (wyzwalacze natychmiastowe); możesz ich użyć również we własnej integracji.

Metody POST i GET wymagają dodatkowo planu z obsługą webhooków - w przeciwnym razie zwracamy 403 forbidden. Metoda DELETE jest autoryzowana samym kluczem API, więc usuwanie subskrypcji działa także po zmianie planu.

Utwórz subskrypcję

POST/v1/webhooks

Rejestruje jeden adres zwrotny dla dokładnie jednego zdarzenia i zwraca obiekt subskrypcji z kodem 201 (bez koperty data). Zapisz zwrócone id - podajesz je przy usuwaniu subskrypcji.

Treść żądania

  • target_url - adres zwrotny HTTPS na jednym z dozwolonych hostów, wymagany.
  • event - jedno zdarzenie z listy powyżej, wymagane.
terminal
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"}'
201 Created
{
  "id": "n41c8…",
  "event": "article.published",
  "target_url": "https://hook.eu2.make.com/abc123",
  "status": "enabled"
}

Obiekt subskrypcji

  • id - identyfikator subskrypcji - przekazujesz go do metody DELETE.
  • event - zdarzenie, na które zapisana jest subskrypcja.
  • target_url - zarejestrowany adres zwrotny.
  • status - enabled albo disabled - subskrypcja jest wyłączana automatycznie po wielu nieudanych dostawach.

Dozwolone hosty target_url

Adres target_url musi być adresem HTTPS platformy automatyzacji, na jednym z hostów:

  • hooks.zapier.com - adresy catch hook w Zapier.
  • hook.make.com, hook.<strefa>.make.com - webhooki Make.com, na przykład hook.eu2.make.com.

Inny host, adres bez HTTPS, adres z danymi logowania albo adres prywatny, pętli zwrotnej lub metadanych odrzucamy z kodem 400 bad_request.

Ponowne wysłanie tej samej pary target_url i event nie tworzy duplikatu: istniejąca subskrypcja jest ponownie włączana i zwracana z tym samym id. Projekt może mieć maksymalnie 20 subskrypcji na platformę.

Lista subskrypcji

GET/v1/webhooks

Zwraca subskrypcje utworzone tym kluczem API w tym projekcie. Subskrypcje utworzone innym kluczem oraz webhooki skonfigurowane w panelu nie są zwracane.

GET /v1/webhooks
{
  "data": [
    {
      "id": "n41c8…",
      "event": "article.published",
      "target_url": "https://hook.eu2.make.com/abc123",
      "status": "enabled"
    }
  ]
}

Usuń subskrypcję

DELETE/v1/webhooks/:id

Usuwa subskrypcję o podanym id. Operacja jest idempotentna: nieznane, już usunięte lub cudze id zwraca kod 200 z polem deleted: false zamiast 404, więc usuwanie nigdy nie kończy się błędem.

DELETE /v1/webhooks/n41c8…
{
  "id": "n41c8…",
  "deleted": true
}

Błędy

  • 400 bad_request - brak pola target_url lub event, nieznane zdarzenie albo adres spoza dozwolonych hostów.
  • 401 unauthorized - brak lub nieprawidłowy klucz API.
  • 403 forbidden - plan nie obejmuje webhooków albo osiągnięto limit 20 subskrypcji.

Odpowiedzi tych punktów końcowych zawierają te same nagłówki X-RateLimit-Limit, X-RateLimit-Remaining i X-RateLimit-Reset co punkty końcowe do odczytu.