> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ycloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configurar webhooks

> Reciba eventos de YCloud en su endpoint HTTPS.

## Qué es

Los webhooks son solicitudes HTTPS que YCloud envía a su aplicación cuando cambian la entrega de mensajes, los mensajes entrantes, los contactos, las plantillas, las llamadas y otros recursos.

## Antes de comenzar

* Guarde su clave de API de YCloud en `YCLOUD_API_KEY`.
* Despliegue un endpoint HTTPS públicamente accesible.
* Conserve el cuerpo sin procesar de la solicitud para la verificación de firmas.
* Decida qué tipos de eventos necesita su aplicación.

## Cómo funciona

1. Cree un endpoint de Webhook y suscríbalo a tipos de eventos.
2. Guarde el `secret` del endpoint devuelto.
3. YCloud envía una solicitud de evento a su endpoint.
4. Verifique `YCloud-Signature` antes de confiar en la solicitud.
5. Devuelva una respuesta `2xx` de inmediato.
6. Procese el evento de forma idempotente, ya que la entrega puede repetirse.

## Solicitud

Cree un endpoint con `POST /webhookEndpoints`.

### Campos de solicitud

| Campo | Requerido | Descripción |
| - | - | - |
| `url` | Sí | URL HTTPS pública que recibe solicitudes de eventos. Máximo 500 caracteres. |
| `enabledEvents` | Sí | Tipos de eventos entregados a este endpoint. |
| `eventProperties` | Condicional | Propiedades incluidas para tipos de eventos seleccionados. Requerido para `contact.attributes_changed`. |
| `description` | No | Descripción del endpoint. Máximo 400 caracteres. |
| `status` | No | Estado inicial del endpoint. |

### Ejemplo de solicitud

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.ycloud.com/v2/webhookEndpoints \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "url": "https://example.com/webhooks/ycloud",
    "enabledEvents": [
      "whatsapp.inbound_message.received",
      "whatsapp.message.updated",
      "sms.message.updated"
    ],
    "description": "Production messaging events"
}'
```

### Suscribirse a eventos de echo y handover

Para los agentes incorporados a través de la API REST pública, cree un endpoint con las siguientes suscripciones. Los agentes creados desde la consola no emiten estos tres eventos. Para modificar un endpoint existente, conserve las suscripciones a eventos que aún necesite.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.ycloud.com/v2/webhookEndpoints \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "url": "https://example.com/webhooks/ycloud",
    "enabledEvents": [
      "whatsapp.echo_message.created",
      "whatsapp.echo_message.updated",
      "whatsapp.meta_business_agent.handover.updated",
      "whatsapp.inbound_message.received"
    ],
    "description": "API Agent echo and handover events"
  }'
```

Los dos tipos de eventos echo incluyen una carga útil `whatsappMessage` con formato estándar de mensaje. El evento handover incluye `whatsappMetaBusinessAgent` y conserva su información de agente/control. No utilizan el contrato `whatsapp.smb.message.echoes` de la aplicación WhatsApp Business. Consulte los [detalles de los eventos echo y handover](/es/api-reference/guides/examples/webhook-examples/overview#echo-and-agent-handover-events) para obtener definiciones de campos, ejemplos, orden y límites de correlación de handover.

## Respuesta

La respuesta devuelve el endpoint creado y su `secret` de firma. Guarde el secreto de forma segura. YCloud lo utiliza para generar firmas de Webhook.

### Ejemplo de respuesta

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "WEBHOOK_ENDPOINT_ID",
  "url": "https://example.com/webhooks/ycloud",
  "enabledEvents": [
    "whatsapp.inbound_message.received",
    "whatsapp.message.updated",
    "sms.message.updated"
  ],
  "description": "Production messaging events",
  "status": "active",
  "secret": "whsec_REPLACE_WITH_RETURNED_SECRET",
  "createTime": "2026-07-16T12:00:00.000Z",
  "updateTime": "2026-07-16T12:00:00.000Z"
}
```

### Campos de respuesta

| Campo | Descripción |
| - | - |
| `id` | ID del endpoint de Webhook utilizado para recuperar, actualizar, eliminar o rotar el secreto del endpoint. |
| `url` | URL de destino para la entrega de eventos. |
| `enabledEvents` | Tipos de eventos actualmente habilitados. |
| `status` | Estado actual del endpoint. |
| `secret` | Secreto utilizado para verificar `YCloud-Signature`. Guárdelo de forma segura. |
| `createTime`, `updateTime` | Marcas de tiempo del endpoint en formato RFC 3339. |

## Recibir eventos

### Solicitud de evento

YCloud envía un objeto de evento JSON al `url` configurado. El evento incluye campos comunes como `id`, `type`, `apiVersion` y `createTime`, además de una carga útil específica del tipo.

Su controlador debe:

1. Leer el cuerpo de la solicitud sin procesar.
2. Validar el encabezado `YCloud-Signature` con el secreto del endpoint antes de confiar en la carga útil.
3. Devolver una respuesta `2xx` exitosa de inmediato.
4. Mover el procesamiento lento a una cola.
5. Hacer que el procesamiento de eventos sea idempotente para que la entrega repetida no duplique acciones comerciales.

<Warning>
  No analice ni modifique el cuerpo de la solicitud antes de validar la firma. Utilice exactamente los bytes sin procesar recibidos por su servidor.
</Warning>

### Respuesta del receptor

Devuelva una respuesta HTTP `2xx` exitosa tan pronto como se acepten la firma y la solicitud. El cuerpo de la respuesta puede estar vacío.

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
HTTP/1.1 204 No Content
```

Mueva el procesamiento comercial lento a una cola. Un tiempo de espera agotado o una respuesta distinta de `2xx` pueden provocar que YCloud reintente el evento, por lo que debe desduplicar por el `id` del evento.

## Ejemplos comunes de carga útil

Despliegue un evento para inspeccionar el ejemplo completo de su carga útil. Estos ejemplos proceden de la especificación de OpenAPI para webhooks. Consulte [todos los ejemplos de carga útil de webhook](/es/api-reference/guides/examples/webhook-examples/webhook-payload-examples) para ver cada tipo de evento admitido.

<AccordionGroup>
  <Accordion title="Evento de atributos de contacto cambiados">
    Carga útil de ejemplo cuando se cambian los atributos de un contacto

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "evt_1234567890",
      "type": "contact.attributes_changed",
      "apiVersion": "v2",
      "createTime": "2024-01-01T12:00:00.000Z",
      "contactAttributesChanged": {
        "id": "1824266594102064128",
        "updateTime": "2024-01-01T12:00:00.000Z",
        "changedAttributes": {
          "nickName": {
            "oldValue": "John Doe",
            "newValue": "Johnny Doe"
          },
          "email": {
            "oldValue": "john.doe@example.com",
            "newValue": "johnny.doe@example.com"
          },
          "tags": {
            "oldValue": [
              "premium",
              "newsletter"
            ],
            "newValue": [
              "premium",
              "newsletter",
              "vip"
            ],
            "extra": [
              {
                "action": "ADDED",
                "id": "686dd294334be8606a5bf312",
                "value": "vip"
              }
            ]
          }
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Evento de contacto creado">
    Carga útil de ejemplo cuando se crea un nuevo contacto

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "evt_2345678901",
      "type": "contact.created",
      "apiVersion": "v2",
      "createTime": "2024-01-01T12:00:00.000Z",
      "contactCreated": {
        "id": "1824266594102064128",
        "nickName": "John Doe",
        "realName": "John Smith",
        "phoneNumber": "+16315551111",
        "countryCode": "US",
        "countryName": "United States",
        "email": "john.doe@example.com",
        "sourceType": "api",
        "sourceId": "import_batch_123",
        "sourceUrl": "https://example.com/signup",
        "lastSeen": "2024-01-01T11:59:00.000Z",
        "lastConnectedNumber": "+16315552222",
        "ownerEmail": "owner@example.com",
        "tags": [
          "premium",
          "newsletter"
        ],
        "createTime": "2024-01-01T12:00:00.000Z",
        "updateTime": "2024-01-01T12:00:00.000Z",
        "blocked": false,
        "customAttributes": {
          "attr1": "value1",
          "attr2": "value2",
          "attr3": 123
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Evento de contacto eliminado">
    Carga útil de ejemplo cuando se elimina un contacto

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "evt_3456789012",
      "type": "contact.deleted",
      "apiVersion": "v2",
      "createTime": "2024-01-01T12:00:00.000Z",
      "contactDeleted": {
        "id": "1824266594102064128",
        "nickName": "John Doe",
        "phoneNumber": "+16315551111",
        "updateTime": "2024-01-01T12:00:00.000Z"
      }
    }
    ```
  </Accordion>

  <Accordion title="Evento de cliente que cancela la suscripción">
    Carga útil de ejemplo cuando un cliente cancela la suscripción

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "evt_3456789012",
      "type": "contact.unsubscribe.created",
      "apiVersion": "v2",
      "createTime": "2024-01-01T12:00:00.000Z",
      "unsubscriberChanged": {
        "phoneNumber": "+16315551111",
        "source": "Whatsapp",
        "updateTime": "2024-01-01T12:00:00.000Z"
      }
    }
    ```
  </Accordion>

  <Accordion title="Cliente reanuda la suscripción">
    Carga útil de ejemplo cuando un cliente reanuda la suscripción

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "evt_3456789012",
      "type": "contact.unsubscribe.deleted",
      "apiVersion": "v2",
      "createTime": "2024-01-01T12:00:00.000Z",
      "unsubscriberChanged": {
        "phoneNumber": "+16315551111",
        "source": "Whatsapp",
        "updateTime": "2024-01-01T12:00:00.000Z"
      }
    }
    ```
  </Accordion>

  <Accordion title="Evento de plantilla de WhatsApp archivada">
    Carga útil de ejemplo cuando se archiva una plantilla de WhatsApp

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "evt_template_archived_123",
      "type": "whatsapp.template.reviewed",
      "apiVersion": "v2",
      "createTime": "2024-01-01T12:00:00.000Z",
      "whatsappTemplate": {
        "id": "template-id",
        "officialTemplateId": "official-template-id",
        "wabaId": "whatsapp-business-account-id",
        "name": "sample_whatsapp_template",
        "language": "en",
        "category": "MARKETING",
        "status": "ARCHIVED",
        "statusUpdateEvent": "ARCHIVED",
        "createTime": "2024-01-01T12:00:00.000Z",
        "updateTime": "2024-01-01T12:00:00.000Z"
      }
    }
    ```
  </Accordion>

  <Accordion title="Evento de plantilla de WhatsApp desarchivada">
    Carga útil de ejemplo cuando se desarchiva una plantilla de WhatsApp. El estado de la plantilla es el estado actual devuelto por Meta y no representa una nueva revisión de aprobación.

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "evt_template_unarchived_123",
      "type": "whatsapp.template.reviewed",
      "apiVersion": "v2",
      "createTime": "2024-01-01T12:00:00.000Z",
      "whatsappTemplate": {
        "id": "template-id",
        "officialTemplateId": "official-template-id",
        "wabaId": "whatsapp-business-account-id",
        "name": "sample_whatsapp_template",
        "language": "en",
        "category": "MARKETING",
        "status": "APPROVED",
        "statusUpdateEvent": "UNARCHIVED",
        "createTime": "2024-01-01T12:00:00.000Z",
        "updateTime": "2024-01-01T12:00:00.000Z"
      }
    }
    ```
  </Accordion>

  <Accordion title="Evento de llamada de WhatsApp conectada">
    Carga útil de ejemplo cuando se conecta una llamada de WhatsApp

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "evt_call_connect_123",
      "type": "whatsapp.call.connect",
      "apiVersion": "v2",
      "createTime": "2024-01-01T12:00:00.000Z",
      "callingConnect": {
        "id": "6757b723960b25543b9ecc66",
        "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABIYIEF",
        "phoneId": "461269257068832",
        "from": "+6281361905133",
        "to": "+6283138205150",
        "direction": "USER_INITIATED",
        "dialTime": 1733826430000,
        "sdpType": "offer",
        "sdp": "v=0\r\no=- 1732169627243 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE audio\r\na=msid-semantic: WMS af3b01e3-eb42-4244-812e-db903c062ae7\r\na=ice-lite\r\nm=audio 3480 UDP/TLS/RTP/SAVPF 111 126\r\nc=IN IP4 31.13.87.130\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=candidate:785588535 1 udp 2122260223 31.13.87.130 3480 typ host generation 0 network-cost 50\r\na=candidate:1906600321 1 udp 2122262783 2a03:2880:f217:d0:face:b00c:0:699c 3480 typ host generation 0 network-cost 50\r\na=ice-ufrag:CvRXRnInnWhQzLIE\r\na=ice-pwd:HGXUGAFI8wK6seuVknBT2Q==\r\na=fingerprint:sha-256 FB:56:A1:C5:37:35:6C:5C:1B:05:23:B0:DD:BB:2E:C9:5F:E4:70:61:7B:D9:1D:09:84:76:46:23:12:38:B7:01\r\na=setup:actpass\r\na=mid:audio\r\na=sendrecv\r\na=msid:af3b01e3-eb42-4244-812e-db903c062ae7 WhatsAppTrack1\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1\r\na=rtpmap:126 telephone-event/8000\r\na=maxptime:20\r\na=ptime:20\r\na=ssrc:659928310 cname:WhatsAppAudioStream1\r\n"
      }
    }
    ```
  </Accordion>

  <Accordion title="Evento de llamada de WhatsApp finalizada">
    Ejemplo de payload cuando se finaliza una llamada de WhatsApp

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "evt_6757b889a5a42d369ef48481",
      "type": "whatsapp.call.terminate",
      "apiVersion": "v2",
      "createTime": "2024-12-10T03:42:01.822Z",
      "callingTerminate": {
        "id": "6757b889960b25543b9ecc67",
        "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABIYIEFENjB",
        "phoneId": "461269257068832",
        "from": "+6281361905133",
        "to": "+6283138205150",
        "direction": "USER_INITIATED",
        "startTime": 1733734738000,
        "endTime": 1733734771000,
        "duration": 33,
        "status": "COMPLETED"
      }
    }
    ```
  </Accordion>

  <Accordion title="Evento de actualización del estado de una llamada de WhatsApp">
    Ejemplo de payload cuando se actualiza el estado de una llamada de WhatsApp

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "evt_676e5ab57a9cb742d02d7646",
      "type": "whatsapp.call.status.updated",
      "apiVersion": "v2",
      "createTime": "2024-12-27T07:41:28.422Z",
      "callingStatusUpdated": {
        "wabaId": "188234691048809",
        "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABE",
        "status": "RINGING",
        "recipientPhone": "+6281361905133"
      }
    }
    ```
  </Accordion>
</AccordionGroup>

Consulta [Payloads de eventos de Webhook](/es/api-reference/webhooks/test-webhooks) para ver el esquema completo de `Event` y la referencia interactiva de payloads.

## Rotar el secreto del endpoint

Rota un secreto si queda expuesto o como parte de tu política de seguridad:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  https://api.ycloud.com/v2/webhookEndpoints/WEBHOOK_ENDPOINT_ID/rotateSecret \
  --header "X-API-Key: $YCLOUD_API_KEY"
```

Implementa el nuevo secreto en tu receptor inmediatamente después de la rotación.

<Note>
  Un endpoint que falla repetidamente al recibir notificaciones puede pasar al estado `pending` y dejar de recibir eventos. Monitorea los fallos de webhook y el estado del endpoint.
</Note>

Para consultar el código de verificación de firma, los intervalos de reintento y la implementación del receptor, consulta
[Implementar un receptor de webhook](/es/api-reference/guides/api-fundamentals/implement-a-webhook-receiver).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.