> ## 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

> Receba eventos da YCloud no seu endpoint HTTPS.

## O que é

Webhooks são solicitações HTTPS que a YCloud envia para o seu aplicativo quando a entrega de mensagens, mensagens recebidas, contatos, modelos, chamadas e outros recursos mudam.

## Antes de começar

* Armazene sua chave de API da YCloud em `YCLOUD_API_KEY`.
* Implante um endpoint HTTPS acessível publicamente.
* Preserve o corpo bruto da solicitação para verificação de assinatura.
* Decida quais tipos de evento seu aplicativo precisa.

## Como funciona

1. Crie um endpoint de Webhook e inscreva-o nos tipos de eventos.
2. Armazene o `secret` retornado do endpoint.
3. A YCloud envia uma solicitação de evento para o seu endpoint.
4. Verifique o `YCloud-Signature` antes de confiar na solicitação.
5. Retorne uma resposta `2xx` imediatamente.
6. Processe o evento de forma idempotente, pois a entrega pode ser repetida.

## Solicitação

Crie um endpoint com `POST /webhookEndpoints`.

### Campos da solicitação

| Campo | Obrigatório | Descrição |
| - | - | - |
| `url` | Sim | URL HTTPS pública que recebe solicitações de evento. Máximo de 500 caracteres. |
| `enabledEvents` | Sim | Tipos de evento entregues a este endpoint. |
| `eventProperties` | Condicional | Propriedades incluídas para tipos de evento selecionados. Obrigatório para `contact.attributes_changed`. |
| `description` | Não | Descrição do endpoint. Máximo de 400 caracteres. |
| `status` | Não | Status inicial do endpoint. |

### Exemplo de solicitação

```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"
}'
```

### Inscrever-se em eventos de echo e handover

Para Agents integrados por meio da API REST pública, crie um endpoint com as seguintes assinaturas. Agents criados no Console não emitem esses três eventos. Para alterar um endpoint existente, preserve as assinaturas de eventos que você ainda precisa.

```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"
  }'
```

Os dois tipos de evento echo contêm uma carga útil padrão `whatsappMessage` no formato de mensagem. O evento de handover contém `whatsappMetaBusinessAgent` e mantém suas informações de Agent/controle. Eles não usam o contrato do aplicativo WhatsApp Business `whatsapp.smb.message.echoes`. Consulte [detalhes dos eventos de echo e handover](/pt/api-reference/guides/examples/webhook-examples/overview#echo-and-agent-handover-events) para definições de campo, exemplos, ordenação e limites de correlação de handover.

## Resposta

A resposta retorna o endpoint criado e seu segredo de assinatura `secret`. Armazene o segredo com segurança. A YCloud o utiliza para gerar assinaturas de Webhook.

### Exemplo de resposta

```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 da resposta

| Campo | Descrição |
| - | - |
| `id` | ID do endpoint de Webhook usado para recuperar, atualizar, excluir ou alternar o segredo do endpoint. |
| `url` | URL de destino para entrega de eventos. |
| `enabledEvents` | Tipos de eventos atualmente habilitados. |
| `status` | Estado atual do endpoint. |
| `secret` | Segredo usado para verificar `YCloud-Signature`. Armazene-o com segurança. |
| `createTime`, `updateTime` | Carimbos de data/hora do endpoint no formato RFC 3339. |

## Receber eventos

### Solicitação de evento

A YCloud envia um objeto de evento JSON para a `url` configurada. O evento inclui campos comuns, como `id`, `type`, `apiVersion` e `createTime`, além de uma carga útil específica do tipo.

O seu manipulador deve:

1. Ler o corpo bruto da solicitação.
2. Validar o cabeçalho `YCloud-Signature` com o segredo do endpoint antes de confiar na carga útil.
3. Retornar uma resposta bem-sucedida `2xx` imediatamente.
4. Mover o processamento lento para uma fila.
5. Tornar o processamento de eventos idempotente para que entregas repetidas não executem ações de negócios duplicadas.

<Warning>
  Não faça parse nem modifique o corpo da solicitação antes da validação da assinatura. Use exatamente os bytes brutos recebidos pelo seu servidor.
</Warning>

### Resposta do receptor

Retorne uma resposta HTTP bem-sucedida `2xx` assim que a assinatura e a solicitação forem aceitas. O corpo da resposta pode ficar vazio.

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

Mova o processamento de negócios lento para uma fila. Um tempo limite esgotado ou uma resposta diferente de `2xx` pode fazer com que a YCloud tente reenviar o evento; portanto, deduplique pelo `id` do evento.

## Exemplos comuns de payload

Expanda um evento para inspecionar o exemplo completo de carga útil. Esses exemplos vêm da especificação de webhook da OpenAPI. Consulte [todos os exemplos de payloads de webhook](/pt/api-reference/guides/examples/webhook-examples/webhook-payload-examples) para cada tipo de evento compatível.

<AccordionGroup>
  <Accordion title="Evento de atributos de contato alterados">
    Exemplo de carga útil quando os atributos de contato são alterados

    ```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 contato criado">
    Exemplo de carga útil quando um novo contato é criado

    ```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 contato excluído">
    Exemplo de carga útil quando um contato é excluído

    ```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 cancelamento de assinatura pelo cliente">
    Exemplo de carga útil quando um cliente cancela a assinatura

    ```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="O cliente retoma a assinatura">
    Exemplo de carga útil quando um cliente retoma a assinatura

    ```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 modelo do WhatsApp arquivado">
    Exemplo de carga útil quando um modelo do WhatsApp é arquivado

    ```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 modelo do WhatsApp desarquivado">
    Exemplo de carga útil quando um modelo do WhatsApp é desarquivado. O status do modelo é o status atual retornado pela Meta e não representa uma nova análise de aprovação.

    ```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 chamada do WhatsApp conectada">
    Exemplo de carga útil quando uma chamada do WhatsApp é conectada

    ```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 chamada do WhatsApp encerrada">
    Exemplo de payload quando uma chamada do WhatsApp é encerrada

    ```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 status de chamada do WhatsApp atualizado">
    Exemplo de payload quando o status de uma chamada do WhatsApp é atualizado

    ```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>

Consulte [Payloads de eventos de Webhook](/pt/api-reference/webhooks/test-webhooks) para ver o esquema completo em `Event` e a referência interativa de payloads.

## Alternar o segredo do endpoint

Alterne um segredo se ele for exposto ou como parte da sua política de segurança:

```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"
```

Implante o novo segredo no seu receptor imediatamente após a alternância.

<Note>
  Um endpoint que falha repetidamente ao receber notificações pode mudar para o status `pending` e parar de receber eventos. Monitore as falhas de webhook e o status do endpoint.
</Note>

Para obter o código de verificação de assinatura, intervalos de repetição e implementação do receptor, consulte
[Implementar um receptor de webhook](/pt/api-reference/guides/api-fundamentals/implement-a-webhook-receiver).


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