Webhooks
Los webhooks permiten que Semantico avise a tus sistemas en el momento en que termina una tarea de generación de producto, sin que tengas que consultar periódicamente. Semantico admite una configuración de webhook por espacio de trabajo.
Configurar un webhook
Sección titulada «Configurar un webhook»Gestiona tu webhook mediante los endpoints de configuración:
GET /settings/webhooks/: obtiene la configuración actual.POST /settings/webhooks/: crea o sustituye la configuración (unPOSTsiempre sustituye la única configuración existente).DELETE /settings/webhooks/: la elimina.
Cuerpo de la petición:
{ "url": "https://example.com/webhook", "hmac_secret": "your-shared-secret", "actions": ["product_generated", "product_generation_failed", "product_generation_no_urls"]}url(obligatorio): dirección a la que se envían las entregas.hmac_secret(opcional): si se define, cada entrega se firma para que puedas verificar que procede de Semantico.actions(opcional): qué eventos se entregan. Si se omite, se activan todos los eventos.
Eventos disponibles:
| Evento | Se dispara cuando |
|---|---|
product_generated |
Un producto ha terminado de generarse correctamente. |
product_generation_failed |
La generación de un producto ha fallado. |
product_generation_no_urls |
No se ha encontrado ninguna URL de origen para el producto. |
Comportamiento de las entregas
Sección titulada «Comportamiento de las entregas»- Las entregas son peticiones
POSTconContent-Type: application/json. - El tiempo de espera es de 10 segundos.
- Las entregas fallidas se reintentan hasta 5 veces con espera progresiva (aproximadamente a los
1 s, 8 s, 60 s, 120 s y 420 s). Un
2xxse considera un éxito; un4xxse considera un error permanente y no se reintenta; el resto de respuestas (5xx, tiempos de espera agotados, errores de conexión) se reintentan. - Semantico no te avisará dos veces por la misma combinación de producto y evento.
Payload
Sección titulada «Payload»Cada entrega contiene:
action: el nombre del evento.status: el estado de la tarea.reason_for_failure: un motivo de fallo opcional.credits: créditos consumidos (consumed) y restantes (remaining).task: metadatos de la tarea (id, marcas de tiempo, URLs de origen).product: el payload completo del producto (onullsi no está disponible). Los atributos personalizados se devuelven en la clavesections.
{ "action": "product_generated", "status": "SUCCESS", "reason_for_failure": "", "credits": { "consumed": 10, "remaining": 1230 }, "task": { "id": "b3b8c9c8-4a62-4b59-9caa-7d7b1f5a1234", "status": "SUCCESS", "created_at": "2026-02-09T10:00:00Z", "updated_at": "2026-02-09T10:01:00Z", "urls": [ { "id": 1, "url": "https://example.com/product", "status": "SUCCESS", "relevant_score": 0.95, "is_user_provided_link": true } ] }, "product": { "id": 123, "sku": "MODEL-001", "is_product_model": true }}Verificar la firma
Sección titulada «Verificar la firma»Si defines un hmac_secret, cada entrega incluye dos cabeceras:
X-Webhook-Timestamp: marca de tiempo Unix (en segundos) de la entrega.X-Webhook-Signature:sha256=<hex>, un HMAC-SHA256 del payload firmado.
El payload firmado es la marca de tiempo y el cuerpo sin procesar de la petición unidos por un punto:
signed_payload = "<X-Webhook-Timestamp>" + "." + "<raw JSON request body>"signature = "sha256=" + HMAC_SHA256(secret, signed_payload) // hex digestPara verificarla, vuelve a calcular la firma sobre el cuerpo sin procesar que has recibido y
compárala con X-Webhook-Signature. Si no hay ningún hmac_secret configurado, estas cabeceras no se envían.
Verificación en Python:
import hashlibimport hmac
def is_valid(secret: str, timestamp: str, raw_body: bytes, signature: str) -> bool: signed = f"{timestamp}.".encode() + raw_body expected = "sha256=" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, signature)