# Webhooks (/es/docs/automate/workflow-webhooks)

Los webhooks envían una solicitud HTTPS firmada a tu servidor cuando algo ocurre en Sift. Un endpoint puede suscribirse a eventos de acciones, como una etiqueta añadida o un cambio de estado. Una regla de notificación también puede enviar a un endpoint.

## De un vistazo [#de-un-vistazo]

| | |
| --- | --- |
| Disponible para superadministradores | ✅ |
| Endpoints HTTPS públicos | ✅ obligatorio |
| Suscripción a eventos de acciones | ✅ etiquetas, estado, responsable, cola de trabajo, campos, formularios, moderación |
| Solo para acciones que coincidan con una búsqueda guardada | ✅ opcional |
| Envío desde reglas de notificación | ✅ |
| Secreto de firma generado | ✅ se muestra una vez, 24 horas de solapamiento al rotar |
| Registro de envíos, prueba y reenvío | ✅ |
| Reintentos automáticos ante fallos temporales | ✅ hasta 24 horas |
| Orden de los eventos de una acción | ✅ en orden por endpoint |
| Entrega exactamente una vez | ❌ al menos una vez |

## Configurarlo [#configurarlo]

1. Ve a **Configuración → Acceso de desarrollador → Webhooks**.
2. Selecciona **Nuevo endpoint**. Escribe un nombre y una URL HTTPS pública, y elige los eventos que quieres recibir.
3. Copia el secreto de firma. Sift solo lo muestra una vez.
4. Opcional: abre el endpoint y elige una búsqueda guardada en **Solo para acciones que coincidan**. No se envían eventos de otras acciones.
5. Selecciona **Enviar prueba**. El endpoint debe responder con un estado entre `200` y `299`.

Para enviar desde una regla, abre **Configuración → Workflows → Notificaciones**, edita una notificación y selecciona el endpoint en **Webhooks**.

## Eventos [#eventos]

| Evento | Se envía cuando |
| --- | --- |
| `action.created` | Se abre una acción nueva |
| `action.tag_added` / `action.tag_removed` | Una persona, una regla, la IA o la API cambia una etiqueta |
| `action.status_changed` | Cambia el estado de la acción |
| `action.assigned` | Cambia el responsable |
| `action.queue_changed` | La acción pasa a otra cola de trabajo |
| `action.field_changed` | Cambia el valor de un campo personalizado |
| `form.submitted` | Se envía un formulario de acción |
| `moderation.decided` | Se registra una decisión de moderación |
| `workflow.notification` | Una regla de notificación envía al endpoint |
| `webhook.test` | Seleccionas **Enviar prueba** |

El cuerpo de un evento tiene este aspecto. `change` describe lo que ocurrió. `action` es el estado de la acción cuando Sift creó el evento; un reintento envía el mismo cuerpo.

```json
{
  "id": "evt_qy1b3lsr19x0qjoljxgiys9k",
  "type": "action.tag_added",
  "apiVersion": "2026-11-01",
  "occurredAt": "2026-10-28T18:55:19.175Z",
  "orgId": "org_...",
  "data": {
    "action": {
      "id": "act_...",
      "displayId": "ACME-1842",
      "url": "https://app.getsift.ai/app/record/act_...?entity=action",
      "status": "OPEN",
      "platform": "CUSTOM_API",
      "channel": "social-ai-api-DEV",
      "queueId": "queue_...",
      "assigneeId": null,
      "externalId": "post-184",
      "sourceId": "src_...",
      "tags": [{ "id": "tag_...", "name": "Remove post" }],
      "customFields": []
    },
    "change": {
      "tag": { "id": "tag_...", "name": "Remove post" },
      "actor": { "type": "USER", "id": "user_...", "name": "Dana Kim" }
    }
  }
}
```

`apiVersion` es una fecha. Pueden aparecer campos nuevos sin una fecha nueva. Un cambio incompatible llega con una fecha nueva.

## Formato de las notificaciones de reglas [#formato-de-las-notificaciones-de-reglas]

Sift envía un sobre JSON. El objeto `data` contiene la notificación de workflow.

```json
{
  "subjectType": "workflow_webhook",
  "subjectId": "organization",
  "orgId": "org_...",
  "deliveredAt": "2026-09-01T18:02:11.000Z",
  "data": {
    "id": "workflow-notification:...",
    "type": "workflow.notification",
    "version": 1,
    "occurredAt": "2026-09-01T18:02:11.000Z",
    "orgId": "org_...",
    "message": "Mensaje personalizado opcional",
    "workflow": {
      "id": "wf_...",
      "executionId": "wfx_...",
      "triggerId": "trg_...",
      "name": "Escalar señales de compra"
    },
    "action": {
      "id": "act_...",
      "easyId": "ACME-1842",
      "status": "OPEN",
      "queueId": "queue_...",
      "assigneeId": null,
      "platform": "x",
      "externalId": "feedback-184",
      "sourceId": "src_feedback",
      "customFields": [
        {
          "fieldName": "decision",
          "displayName": "Decisión",
          "fieldType": "string",
          "value": "Eliminar",
          "provenance": { "source": "human", "at": "2026-09-01T18:01:40.000Z" }
        }
      ]
    }
  }
}
```

`action.customFields` enumera los valores de campos personalizados del acción en el momento en que se disparó el workflow, una entrada por valor, con el nombre y el tipo actuales del campo. Los campos sin valor no aparecen. Solo aparecen los campos registrados en Settings → Custom fields; las claves internas de Sift nunca aparecen. `action.externalId` es el id del elemento en el sistema de origen y `action.sourceId` es el id de la fuente de Custom API; ambos son `null` en otras plataformas. Un suscriptor puede actuar sobre un cambio de etiqueta sin una segunda lectura.

`action.status` es el estado operativo del acción, tal como se muestra en la bandeja de entrada: `OPEN`, `RESPONDED`, `WAITING_FOR_USER`, `RESOLVED`, `CLOSED`, `DISMISSED`, `SNOOZED` u otro token de estado personalizado como `CUSTOM_STATUS_1`. Es `null` cuando el acción no tiene estado operativo. `action.easyId` es el ID del acción con el prefijo de tu organización, tal como se muestra en la app.

Algunos campos pueden faltar cuando no se aplican a la action o al workflow. Pueden aparecer campos adicionales en la versión `1`. Usa el campo `version` antes de depender de una nueva versión del payload.

## Verificar la firma [#verificar-la-firma]

Cada solicitud lleva cabeceras de [Standard Webhooks](https://www.standardwebhooks.com). Usa cualquier biblioteca de Standard Webhooks con el secreto de firma del endpoint.

```text
webhook-id: evt_...                 (estable entre reintentos; úsalo para descartar duplicados)
webhook-timestamp: 1793210097       (segundos; rechaza solicitudes de más de cinco minutos)
webhook-signature: v1,<base64> v1,<base64>
x-sift-event: action.tag_added
x-sift-signature: sha256=<hex>      (HMAC-SHA256 del cuerpo, para receptores anteriores a Standard Webhooks)
```

```js
import { Webhook } from "standardwebhooks"

export function verifySiftWebhook(rawBody, headers, secret) {
  // Lanza un error si la firma o la marca de tiempo no son válidas.
  return new Webhook(secret).verify(rawBody, headers)
}
```

Verifica el cuerpo sin procesar antes de analizar el JSON. Después de rotar un secreto, el anterior también firma durante 24 horas, así que `webhook-signature` puede llevar dos firmas. Acepta la solicitud si una coincide.

## Entrega y reintentos [#entrega-y-reintentos]

Sift envía un evento alrededor de un segundo después del cambio. La entrega es al menos una vez: usa `webhook-id` para descartar duplicados. Los eventos de una acción llegan a un endpoint en el orden en que ocurrieron.

Sift reintenta los fallos de red, los tiempos de espera y las respuestas `408`, `425`, `429` y `5xx` durante un máximo de 24 horas. Las demás respuestas `4xx` son definitivas. Un `410 Gone` desactiva el endpoint. Devuelve una respuesta `2xx` solo cuando tu sistema acepte el evento.

Cada endpoint muestra sus envíos de los últimos días. Selecciona **Reenviar** en un evento fallido para enviar de nuevo el mismo cuerpo. Si todos los envíos fallan durante cinco días, Sift desactiva el endpoint y avisa por correo a tus administradores. Vuelve a activarlo desde el endpoint.

## Seguridad del endpoint [#seguridad-del-endpoint]

Los endpoints de webhook deben usar HTTPS y resolver solo a direcciones públicas. Sift rechaza URLs con credenciales, direcciones privadas o reservadas, resultados DNS públicos y privados combinados y redirecciones.

## Consejos [#consejos]

- Guarda el secreto de firma en tu gestor de secretos.
- Responde rápidamente. Procesa el trabajo largo después de devolver una respuesta `2xx`.
- Usa la `webhook-id` como clave única de tu handler.
- Desactiva el destino antes de un mantenimiento planificado si no quieres reintentos.
- Rota el secreto cuando un miembro del equipo o una integración pierda acceso.

## Relacionado [#relacionado]

<Cards>
  <Card href="/docs/automate/workflows" title="Workflows">Crea pasos de automatización ordenados.</Card>
  <Card href="/docs/automate/workflow-triggers" title="Workflow Triggers">Elige cuándo se ejecuta un workflow.</Card>
  <Card href="/docs/configure/automation" title="Automation Settings">Gestiona los ajustes de workflows y notificaciones.</Card>
</Cards>
