Contrato de Callback Webhook
Este documento solo describe lo que los usuarios del callback reciben en su URL de webhook.
Antes de los callbacks: configura el endpoint webhook
Completa esta configuración primero. La entrega de callbacks requiere una URL webhook habilitada y un secreto de firma válido.
- Abre Espacio de trabajo -> Configuración -> Webhooks.
- Configura tu URL de callback (se requiere HTTPS). Esta URL recibe todos los eventos webhook.
- Habilita webhooks y guarda la configuración.
- Copia tu secreto de firma (`whsec_...`) y guárdalo de forma segura. Necesitas este secreto para verificar `X-ContentKit-Signature`.
- Envía un evento de prueba y confirma que tu endpoint devuelve una respuesta `2xx`.
Si falta la URL de callback, el webhook está deshabilitado, o tu endpoint devuelve no-2xx, la entrega se trata como fallida.
Formato de solicitud del callback
Método
POST
Encabezados comunes del callback
Content-Type: application/jsonX-ContentKit-Signature: t=<timestamp>,v1=<hmac_sha256>X-ContentKit-Timestamp: <timestamp>
1) Callback de publicación (`event: content.generated`)
Payload enviado al usuario del callback:
{
"id": "evt_0f1d2c3b4a5e6f70",
"event": "content.generated",
"created": 1739865600,
"data": {
"job_id": "job_1739865600",
"workspace_id": "workspace-id-or-unknown",
"domain": "keyword-or-title",
"status": "SUCCESS",
"summary": {
"total": 1,
"processed": 1,
"failed": 0
},
"result": {
"id": "generated-article-id",
"keyword": "best ai seo tools",
"title": "Best AI SEO Tools in 2026",
"slug": "best-ai-seo-tools-in-2026",
"content": "<h1>...</h1>",
"meta_description": "...",
"json_ld": {}
}
}
}`data.result` es el objeto bruto del artículo generado.
El usuario del callback debe devolver JSON `2xx`:
{
"id": "external-post-id-123",
"link": "https://client.example.com/blog/my-published-post"
}Se acepta `url` en lugar de `link`.
2) Callback de aplicación de fixes (`event: fix.apply`)
Cuando fix apply usa `integration_type=webhook`, el payload incluye:
{
"id": "evt_214a2f9bdc294df1",
"event": "fix.apply",
"created": 1739866600,
"data": {
"target_url": "https://client.example.com/blog/my-post",
"summary": {
"total": 3,
"processed": 3,
"failed": 0
},
"fixes": [
{
"type": "meta",
"location": "<head>",
"action": "replace",
"suggested_value": "<title>Updated Title</title>"
},
{
"type": "schema",
"location": "<head>",
"action": "after",
"suggested_value": "{\"@context\":\"https://schema.org\",\"@type\":\"Article\"}"
},
{
"type": "image_alt",
"location": "https://cdn.example.com/image.jpg",
"action": "replace",
"suggested_value": "Descriptive alt text"
}
]
}
}El usuario del callback debe devolver JSON `2xx`:
{
"id": "external-fix-op-456",
"link": "https://client.example.com/blog/my-post"
}Se acepta `url` en lugar de `link`.
3) Formas exactas de fixes por origen
Esta sección define la forma exacta de `data.fixes` según el endpoint de origen.
A) Si el origen es `/apply-fix` (fixes manuales)
`data.fixes` se pasa exactamente como lo envía el cliente.
Valores `type` soportados:
metaschemacontent_additioncontent_replacementstructuralimage_altfaq
Campos típicos por fix:
- requerido: `type`, `location`, `suggested_value`
- opcional: `action` (`before|after|replace`, por defecto `after`)
- opcional: `current_value`, `reasoning`, `location_heading`
B) Si el origen es `/apply-seo` (fixes generados)
`data.fixes` se genera con este mapeo exacto:
- Meta title -> `type: "meta"`, `action: "replace"`, `suggested_value: "<title>...</title>"`
- Meta description -> `type: "meta"`, `action: "replace"`, `suggested_value: "<meta name=\"description\" content=\"...\">"`
- Schema item -> `type: "schema"`, `action: "after"`, `suggested_value: "<json string>"`
- Alt text item -> `type: "image_alt"`, `action: "replace"`, `location: <image_url>`, `suggested_value: <alt_text>`
- Bloque FAQ -> se generan dos fixes: (1) `type: "content_addition"`, `action: "after"`, `suggested_value: "<div class=\"faq-section\">...</div>"`; (2) `type: "schema"`, `action: "after"`, `suggested_value: "<FAQPage json string>"`
Importante: el FAQ de `/apply-seo` no se envía como `type: "faq"`; se envía como `content_addition` más `schema`.
4) Callback de estado al completar fixes (`event: fix.generated`)
Después de completar el trabajo de fix, se puede enviar un callback de estado:
{
"id": "evt_65e5d1e6c83d4040",
"event": "fix.generated",
"created": 1739866000,
"data": {
"job_id": "7c937cd0-a110-4f08-9a10-fdb03f1caef3",
"workspace_id": "workspace-id",
"domain": "https://example.com/page-being-fixed",
"status": "SUCCESS",
"summary": {
"total": 1,
"processed": 1,
"failed": 0
},
"result": {
"status": "success",
"id": "cms-resource-id"
}
}
}Regla de fallo de entrega
Si el usuario del callback devuelve un estado no-2xx, esa entrega se trata como fallida.
