API rewriter.io
Recupera los artículos publicados de tu proyecto mediante una API de solo lectura sencilla y bien documentada, directamente a tu propio blog. REST, JSON, clave de API, filtrado, ordenación y paginación.
Introducción
La URL base de la API es https://public-api.rewriter.io/v1. Todas las respuestas se devuelven en formato JSON (claves en estilo snake_case) y el cuerpo del artículo está disponible como markdown y html. Cada solicitud requiere una clave de API. La API admite únicamente el acceso de lectura a contenido publicado.
En el entorno de pruebas, usa la dirección https://dev-hooks.rewriter.io/v1.
Para agentes de IA y LLM publicamos un índice legible por máquina de esta documentación en llms.txt.
Autenticación
Pasa la clave en el encabezado Authorization como token Bearer. La clave está vinculada a un único proyecto.
# Comprueba a qué proyecto pertenece la clave curl https://public-api.rewriter.io/v1/me \ -H "Authorization: Bearer rw_live_3f8a…"
Límites y versionado
La API está versionada en la ruta (/v1). El límite de solicitudes depende del plan y se cuenta por separado para cada clave de API.
| Plan | Límite / min |
|---|---|
| Start | 60 |
| Solo | 150 |
| Pro | 300 |
| Max | 1000 |
Las respuestas de planes con límite incluyen los encabezados X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset. En un plan sin límite no se envían encabezados X-RateLimit-*.
- Las solicitudes GET son accesibles desde el navegador (CORS).
- Todas las marcas de tiempo en formato ISO 8601 (UTC).
Errores
Devolvemos los errores con el código HTTP correspondiente y una estructura uniforme:
{
"error": {
"code": "not_found",
"message": "Article not found."
}
}400- parámetros de consulta no válidos401- clave de API ausente o no válida403- tu plan no incluye acceso a la API404- no encontrado (artículo no publicado o fuera del proyecto)429- límite de solicitudes superado500- error del servidor
Paginación y ordenación
Devolvemos las listas en un sobre con campos de datos y metadatos de página:
{
"data": [
"…"
],
"page": 1,
"per_page": 10,
"total": 42
}La paginación se controla con los parámetros page (desde 1) y limit (predeterminado 10, máx. 100). La ordenación se establece con el parámetro sort: el prefijo “-” indica orden descendente. Valores permitidos: published_at, -published_at, title, -title, updated_at, -updated_at.
Proyecto
Devuelve información sobre el proyecto vinculado a la clave y los idiomas disponibles. Útil para verificar la clave.
{
"id": "k17a9c…",
"name": "Kawiarnia Pod Lipą",
"primary_language": "pl",
"available_languages": [
"pl",
"en"
],
"plan": "Pro",
"rate_limit_per_minute": 300
}Temas
Devuelve la lista de temas del proyecto. Usa el campo id como valor del filtro topic_id en la lista de artículos.
{
"data": [
{
"id": "j57b2…",
"title": "Lokalne SEO"
},
{
"id": "j58c1…",
"title": "Porady baristów"
}
]
}Categorías
Devuelve la lista de categorías del proyecto. Usa el campo id como valor del filtro category_id en la lista de artículos. Los nombres siguen el parámetro language (por defecto, el idioma principal).
{
"data": [
{
"id": "k20a1…",
"name": "Pielęgnacja ogrodu",
"slug": "pielegnacja-ogrodu"
},
{
"id": "k20a2…",
"name": "Porady",
"slug": "porady"
}
]
}Listar artículos
Devuelve una lista paginada de artículos publicados (campos de resumen, sin el cuerpo).
Parámetros de consulta
topic_id- string, opcional. Filtrar por identificador de tema.category_id- string, opcional. Filtrar por identificador de categoría.language- string, opcional. Código de idioma; por defecto, el idioma principal del proyecto. Otro código devuelve las traducciones publicadas.q- string, opcional. Búsqueda por título (sin distinguir mayúsculas y minúsculas).published_after- fecha ISO 8601, opcional. Solo artículos publicados a partir de esta fecha.published_before- fecha ISO 8601, opcional. Solo artículos publicados hasta esta fecha.sort- string, predeterminado -published_at. Consulta la sección Paginación y ordenación.page- número, predeterminado 1.limit- número, predeterminado 10, máx. 100.
Omite el parámetro que no utilices: un valor vacío (por ejemplo sort=) se trata igual que un parámetro ausente.
{
"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
}Obtener artículo
Devuelve el cuerpo completo de un artículo publicado junto con los metadatos SEO. El cuerpo está disponible como Markdown y como fragmento HTML. El parámetro :id acepta el id completo del artículo; el blog propio de rewriter.io también acepta una referencia slug-8 caracteres.
Parámetros de consulta
language- string, opcional. Código de idioma para obtener una traducción publicada en lugar de la versión en el idioma principal.format- markdown o html, opcional. Por defecto devolvemos ambos campos del cuerpo.
{
"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"
}Artículo en una plantilla HTML
Devuelve una página HTML lista del artículo publicado, envuelta en la plantilla del proyecto (text/html en lugar de JSON). Admite el parámetro language. Ideal para incrustar directamente en un sitio.
curl https://public-api.rewriter.io/v1/articles/m93f7…/html \
-H "Authorization: Bearer rw_live_3f8a…"Webhooks
Los webhooks envían solicitudes POST firmadas a tu URL cuando ocurren eventos de contenido en tu proyecto. Configúralos en el panel, en la sección Cuenta → API e integraciones.
También puedes registrarlos mediante la API, solo con una clave API y sin pasar por el panel. Consulta Suscripciones de webhooks.
Eventos disponibles
article.published- se publicó un artículo.article.scheduled- se programó la publicación de un artículo.article.unpublished- se retiró de la publicación un artículo.article.archived- se archivó un artículo.article.restored- se restauró un artículo desde el archivo.article.translated- se publicó una traducción de un artículo.topic.created- se creó un tema nuevo.headline.created- se generaron nuevas sugerencias de artículos (titulares).
Cuerpo de la solicitud
Cada solicitud lleva un sobre JSON con id (el identificador de entrega - úsalo para deduplicar), event, created_at, project_id y data con los detalles del evento:
{
"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"
}
}Verificación de la firma
Cada solicitud incluye el encabezado X-Rewriter-Webhook-Signature con una firma HMAC-SHA256 de la marca de tiempo (encabezado X-Rewriter-Webhook-Timestamp), un punto y el cuerpo de la solicitud, en el formato sha256=<hex>. Vuelve a calcularla con tu secreto y compárala en tiempo constante.
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));Reintentos y desactivación automática
Las entregas fallidas se reintentan con un intervalo creciente (hasta 5 intentos), enviando el mismo identificador de entrega en cada intento. Tras muchos fallos consecutivos, el webhook se desactiva automáticamente: vuelve a activarlo en el panel.
Suscripciones de webhooks
Puedes registrar y eliminar callbacks de webhook mediante la API, solo con una clave API y sin pasar por el panel. Estos endpoints alimentan los disparadores instantáneos de nuestras apps de Zapier y Make.com, y también puedes usarlos en tu propia integración.
POST y GET requieren además un plan que incluya webhooks; de lo contrario devuelven 403 forbidden. DELETE se autoriza solo con la clave API, así que eliminar una suscripción sigue funcionando tras un cambio de plan.
Crear una suscripción
Registra una URL de callback para exactamente un evento y devuelve el objeto de suscripción con estado 201 (sin envoltorio data). Guarda el id devuelto: lo necesitas para eliminar la suscripción.
Cuerpo de la solicitud
target_url- obligatorio. Una URL de callback HTTPS en uno de los hosts permitidos.event- obligatorio. Un evento de la lista anterior.
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"
}Objeto de suscripción
id- el identificador de la suscripción: pásalo a DELETE.event- el evento para el que está registrada la suscripción.target_url- la URL de callback registrada.status- enabled o disabled: una suscripción se desactiva automáticamente tras varias entregas fallidas.
Hosts permitidos en target_url
target_url debe ser una URL HTTPS de hook de una plataforma de automatización en uno de estos hosts:
hooks.zapier.com- URLs de catch hook de Zapier.hook.make.com, hook.<zona>.make.com- webhooks de Make.com, por ejemplo hook.eu2.make.com.
Cualquier otro host, una URL sin HTTPS, una URL con credenciales o una dirección privada, de bucle local o de metadatos se rechaza con 400 bad_request.
Enviar de nuevo el mismo par target_url y event no crea un duplicado: la suscripción existente se reactiva y se devuelve con el mismo id. Un proyecto admite hasta 20 suscripciones por plataforma.
Listar suscripciones
Devuelve las suscripciones creadas con esta clave API en este proyecto. Las suscripciones creadas con otra clave y los webhooks configurados en el panel nunca se devuelven.
{
"data": [
{
"id": "n41c8…",
"event": "article.published",
"target_url": "https://hook.eu2.make.com/abc123",
"status": "enabled"
}
]
}Eliminar una suscripción
Elimina la suscripción con el id indicado. Es idempotente: un id desconocido, ya eliminado o ajeno devuelve 200 con deleted: false en lugar de 404, así que la limpieza nunca falla.
{
"id": "n41c8…",
"deleted": true
}Errores
400 bad_request- falta target_url o event, evento desconocido o una target_url fuera de los hosts permitidos.401 unauthorized- clave API ausente o no válida.403 forbidden- el plan no incluye webhooks o se alcanzó el límite de 20 suscripciones.
Estas respuestas incluyen las mismas cabeceras X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset que los endpoints de lectura.