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

# Gerenciar chamadas do WhatsApp

> Configure o WhatsApp Calling, gerencie a sinalização de chamadas de entrada e saída, processe eventos de chamadas e baixe gravações ou transcrições.

## O que é

A WhatsApp Calling API da YCloud gerencia a sinalização de chamadas de voz entre um usuário do WhatsApp e um número de telefone comercial. Seu aplicativo troca SDP por meio da YCloud, enquanto sua implementação WebRTC lida com a conexão de áudio.

As chamadas podem começar em qualquer direção:

* **Iniciadas pelo usuário:** Um usuário do WhatsApp liga para a sua empresa. Seu aplicativo recebe uma oferta e aceita ou rejeita a chamada.
* **Iniciadas pela empresa:** Seu aplicativo cria uma oferta e solicita à YCloud que ligue para um usuário do WhatsApp.

<Info>
  A Calling API gerencia a sinalização da chamada, não a pilha de mídia WebRTC. Seu aplicativo é responsável pela configuração da peer connection, captura e reprodução de áudio, geração de SDP e limpeza de recursos do WebRTC.
</Info>

## Mapa da API

As APIs de Calling e os eventos de webhook seguem o mesmo ciclo de vida, mas não formam uma sequência única aplicável a todas as chamadas. Conclua a configuração compartilhada e, em seguida, siga o fluxo iniciado pelo usuário ou iniciado pela empresa. Use o ID da chamada, `wacid`, para correlacionar cada operação e evento.

### Configuração compartilhada

| API | Quando usar | O que acontece a seguir |
| - | - | - |
| [`GET settings`](/api-reference/whatsapp-phone-numbers/retrieve-phone-number-settings) ou [`POST settings`](/api-reference/whatsapp-phone-numbers/save-phone-number-settings) | Antes de gerenciar chamadas ou quando as configurações de Calling e captura forem alteradas. | Configure webhooks e prepare sua implementação WebRTC; em seguida, siga o fluxo correspondente à direção da chamada. |

### Chamadas iniciadas pelo usuário

| Ordem | API ou evento | O que acontece a seguir |
| - | - | - |
| 1 | [`whatsapp.call.connect`](/pt/api-reference/guides/examples/webhook-examples/whatsapp-calling-connect-webhook-examples) | Receba a oferta SDP, `phoneId` e `wacid`; em seguida, crie uma resposta SDP. |
| 2 (opcional) | [`POST /whatsapp/calls/preAccept`](/api-reference/whatsapp-calling/pre-accept-a-call) | Se planeja aceitar a chamada, envie a resposta SDP para preparar o caminho de mídia. Isso não atende a chamada. |
| 3 | [`POST /whatsapp/calls/accept`](/api-reference/whatsapp-calling/accept-a-call) ou [`POST /whatsapp/calls/reject`](/api-reference/whatsapp-calling/reject-a-call) | Escolha uma opção: aceite a chamada com a resposta SDP ou rejeite-a. |

### Chamadas iniciadas pela empresa

| Ordem | API ou evento | O que acontece a seguir |
| - | - | - |
| 1 | [`POST /whatsapp/calls/connect`](/api-reference/whatsapp-calling/connect-a-call) | Envie sua oferta SDP, inicie a chamada e armazene o `wacid` retornado. |
| 2 | [`whatsapp.call.connect`](/pt/api-reference/guides/examples/webhook-examples/whatsapp-calling-connect-webhook-examples) | Receba a resposta SDP remota e aplique-a à mesma peer connection do WebRTC. |
| 3 | [`whatsapp.call.status.updated`](/pt/api-reference/guides/examples/webhook-examples/whatsapp-calling-status-update-webhook-examples) | Monitore `RINGING`, `ACCEPTED` ou `REJECTED`. Este evento pode chegar mais de uma vez conforme a tentativa muda de estado. |

### Conclusão compartilhada de chamadas

| API ou evento | Quando usar | O que acontece a seguir |
| - | - | - |
| [`POST /whatsapp/calls/terminate`](/api-reference/whatsapp-calling/terminate-a-call) | Opcional. Chame quando seu aplicativo precisar encerrar uma chamada ativa de entrada ou de saída. | Mantenha o registro da chamada aberto enquanto aguarda o evento final. |
| [`whatsapp.call.terminate`](/pt/api-reference/guides/examples/webhook-examples/whatsapp-calling-terminate-webhook-examples) | Receba-o para obter o resultado terminal da chamada. | Registre o desfecho final de `COMPLETED` ou `FAILED` e a duração; em seguida, libere os recursos restantes da chamada. |

### Processamento de mídia opcional

| API ou evento | Quando usar | O que acontece a seguir |
| - | - | - |
| [`whatsapp.call.recording.updated`](/pt/api-reference/webhooks/test-webhooks) ou [`whatsapp.call.transcription.updated`](/pt/api-reference/webhooks/test-webhooks) | Quando a captura estiver habilitada e o processamento terminar. | Se o evento reportar `AVAILABLE`, leia seu `mediaAssetId`. Um resultado `FAILED` é terminal para esse ativo. |
| [`GET /whatsapp/calls/media/{mediaAssetId}`](/api-reference/whatsapp-calling/download-call-media) | Apenas após o evento correspondente reportar `AVAILABLE`. | Baixe o arquivo de gravação ou transcrição. |

Essas tabelas descrevem o fluxo de trabalho do aplicativo. Elas não garantem que os webhooks serão entregues na mesma ordem das linhas. Correlacione eventos por `wacid` e trate a reentrega de forma idempotente.

## Antes de começar

Antes de fazer uma solicitação de Calling, prepare o seguinte:

1. Uma chave de API da conta YCloud. Envie-a no cabeçalho `X-API-Key`. Consulte [Autenticação](/pt/api-reference/guides/api-fundamentals/authentication).
2. Uma conta do WhatsApp Business e um número de telefone comercial registrado na YCloud.
3. Calling habilitado para esse número de telefone.
4. Uma implementação de áudio WebRTC capaz de criar e aplicar ofertas e respostas SDP.
5. Um endpoint de webhook da YCloud inscrito nos eventos de Calling utilizados pela sua integração. Consulte [Configurar webhooks](/pt/api-reference/guides/api-fundamentals/configure-webhooks).
6. Permissão de chamada do usuário quando for exigida para uma chamada iniciada pela empresa.

Entre em contato com o seu representante da YCloud para ativar o acesso à Calling API. Para elegibilidade
de chamadas de saída, siga os [requisitos atuais de Calling](/pt/documentation/calling/overview#business-initiated-calls-outbound),
incluindo o nível de mensagens de 2.000 clientes do Portfólio empresarial e os países
com suporte para números de telefone comerciais. O antigo limite de 1.000 conversas foi substituído
pelos requisitos atuais.

Os exemplos abaixo usam estas variáveis de ambiente:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
export YCLOUD_API_KEY="YOUR_API_KEY"
export WABA_ID="YOUR_WABA_ID"
export BUSINESS_PHONE_NUMBER="+16315551111"
```

Mantenha a chave de API no seu servidor. Não a inclua no código do navegador ou do aplicativo móvel.

## Como funciona

Comece configurando o número de telefone comercial. Em seguida, troque o SDP de acordo com a direção da chamada. As respostas da API confirmam operações de sinalização individuais, enquanto os eventos de webhook relatam mudanças de estado e o resultado final. Se a captura estiver ativada, eventos separados indicam quando uma gravação ou transcrição está pronta para download.

## Requisição

## Configurar o número de telefone comercial

As configurações de chamada e captura pertencem a um número de telefone comercial do WhatsApp específico. Configure-as antes de processar chamadas.

### Ler configurações de Calling

Use [`GET /whatsapp/phoneNumbers/{wabaId}/{phoneNumber}/settings`](/api-reference/whatsapp-phone-numbers/retrieve-phone-number-settings) para verificar se o Calling está ativado e se o ícone de Calling está visível:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request GET \
  "https://api.ycloud.com/v2/whatsapp/phoneNumbers/$WABA_ID/$BUSINESS_PHONE_NUMBER/settings?type=calling" \
  --header "X-API-Key: $YCLOUD_API_KEY"
```

Se você omitir `type`, a YCloud retornará a resposta com as configurações de Calling.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "calling": {
    "id": "19213232132",
    "status": "ENABLED",
    "iconVisibility": "DEFAULT"
  }
}
```

| Campo | Valores | Descrição |
| - | - | - |
| `calling.id` | String | ID do número de telefone comercial do WhatsApp. |
| `calling.status` | `ENABLED`, `DISABLED` | Indica se o Calling está ativado para o número de telefone. |
| `calling.iconVisibility` | `DEFAULT`, `DISABLE_ALL` | Indica se o WhatsApp usa o comportamento padrão do ícone de Calling ou oculta todos os ícones de Calling. |

### Ativar Calling

Salve as configurações de Calling com [`POST /whatsapp/phoneNumbers/{wabaId}/{phoneNumber}/settings`](/api-reference/whatsapp-phone-numbers/save-phone-number-settings) antes de começar a aceitar ou fazer chamadas:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  "https://api.ycloud.com/v2/whatsapp/phoneNumbers/$WABA_ID/$BUSINESS_PHONE_NUMBER/settings" \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "calling": {
      "status": "ENABLED",
      "iconVisibility": "DEFAULT"
    }
  }'
```

A resposta contém o objeto `calling` salvo. Antes de processar chamadas ativas, conclua a configuração dos seus webhooks e sessões WebRTC.

### Configurar gravação e transcrição

As configurações de captura se aplicam a novas chamadas originadas via API. Você pode ativar a gravação, a transcrição ou ambas.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  "https://api.ycloud.com/v2/whatsapp/phoneNumbers/$WABA_ID/$BUSINESS_PHONE_NUMBER/settings" \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "capture": {
      "recordingEnabled": true,
      "transcriptionEnabled": true,
      "purpose": "quality_assurance",
      "announcementLanguage": "en_US"
    }
  }'
```

| Campo | Tipo | Obrigatório | Descrição |
| - | - | - | - |
| `capture.recordingEnabled` | Boolean | Sim | Ativa ou desativa a captura de gravação. |
| `capture.transcriptionEnabled` | Boolean | Sim | Ativa ou desativa a captura de transcrição. |
| `capture.purpose` | String | Condicional | Obrigatório quando qualquer opção de captura estiver ativada. Máximo de 250 caracteres. |
| `capture.announcementLanguage` | String | Condicional | Obrigatório quando qualquer opção de captura estiver ativada. Valores suportados: `en`, `en_US`, `en_AU`, `en_CA`, `en_GB`, `en_IN`, `en_NZ`, `nl`, `fr`, `de`, `hi`, `it`, `kn`, `pt`, `es`, `es_ES`, `te`, `vi`. |

Para ler as configurações de captura, use `type=capture`:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request GET \
  "https://api.ycloud.com/v2/whatsapp/phoneNumbers/$WABA_ID/$BUSINESS_PHONE_NUMBER/settings?type=capture" \
  --header "X-API-Key: $YCLOUD_API_KEY"
```

Você pode incluir `calling` e `capture` na mesma requisição `POST`. Após validar o acesso ao número de telefone, a YCloud tenta salvar cada seção de forma independente. Se uma das gravações falhar, a outra seção já pode ter sido salva. Leia ambas as configurações após um erro e tente novamente apenas para a seção que ainda precisa de atualização.

## Processar uma chamada iniciada pelo usuário

![Sequência de Calling iniciada pelo usuário](https://files.readme.io/65fa96a2414cfde54dbf36c30af6e6392ca36093d478674c23547879a14f9c4c-image.png)

Em uma chamada iniciada pelo usuário, o WhatsApp envia a oferta SDP. O seu aplicativo responde a essa oferta e depois aceita ou rejeita a chamada.

### 1. Receber o evento connect

Inscreva-se em [`whatsapp.call.connect`](/pt/api-reference/guides/examples/webhook-examples/whatsapp-calling-connect-webhook-examples). Um evento iniciado pelo usuário tem `direction` definido como `USER_INITIATED` e inclui uma oferta SDP (`offer`).

```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": "SDP_OFFER"
  }
}
```

Armazene `callingConnect.wacid` e `callingConnect.phoneId` juntos. Aplique a oferta SDP recebida à sua conexão peer WebRTC e crie uma resposta SDP.

### 2. Pré-aceitar a chamada

Chame pre-accept após criar uma resposta SDP, mas antes que o agente atenda a chamada. Isso prepara o caminho de mídia e pode reduzir o corte de áudio quando a chamada for atendida.

**Endpoint:** [`POST /whatsapp/calls/preAccept`](/api-reference/whatsapp-calling/pre-accept-a-call)

| Campo | Tipo | Obrigatório | Descrição |
| - | - | - | - |
| `phoneId` | String | Sim | ID do número de telefone comercial a partir do evento connect. |
| `wacid` | String | Sim | ID da chamada do WhatsApp a partir do evento connect. |
| `sdpType` | String | Sim | Deve ser `answer`. |
| `sdp` | String | Sim | Resposta SDP criada pela sua implementação WebRTC. |

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.ycloud.com/v2/whatsapp/calls/preAccept \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "phoneId": "461269257068832",
    "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABIYIEF",
    "sdpType": "answer",
    "sdp": "SDP_ANSWER"
  }'
```

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABIYIEF",
  "success": true
}
```

Depois que o pré-aceite for bem-sucedido, mantenha a chamada em estado de chamando ou pronto. O pré-aceite não atende a chamada para o usuário.

### 3. Aceitar a chamada

Quando o agente atender, envie o mesmo `phoneId`, `wacid`, tipo de SDP e resposta SDP para o endpoint de aceite.

**Endpoint:** [`POST /whatsapp/calls/accept`](/api-reference/whatsapp-calling/accept-a-call)

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.ycloud.com/v2/whatsapp/calls/accept \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "phoneId": "461269257068832",
    "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABIYIEF",
    "sdpType": "answer",
    "sdp": "SDP_ANSWER"
  }'
```

Os campos da requisição e o formato da resposta são os mesmos do pré-aceite. Após uma resposta bem-sucedida, use o estado da conexão WebRTC para prontidão de mídia e aguarde por `whatsapp.call.terminate` para o resultado final da chamada.

A janela de aceite de entrada documentada é de aproximadamente 30 a 60 segundos após o webhook de conexão. Aceite prontamente; uma chamada não atendida termina do lado do usuário com uma notificação **Not Answered** e um webhook de encerramento.

Mesmo que a conexão WebRTC já esteja estabelecida, inicie o áudio somente após a requisição de aceite retornar HTTP `200`. Iniciar antes pode cortar as primeiras palavras; iniciar muito tarde causa silêncio.

### Rejeitar em vez de aceitar

Se o agente não puder atender à chamada de entrada, rejeite-a em vez de criar uma sessão ativa.

**Endpoint:** [`POST /whatsapp/calls/reject`](/api-reference/whatsapp-calling/reject-a-call)

| Campo | Tipo | Obrigatório | Descrição |
| - | - | - | - |
| `phoneId` | String | Sim | ID do número de telefone comercial do evento de conexão. |
| `wacid` | String | Sim | ID da chamada do WhatsApp do evento de conexão. |

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.ycloud.com/v2/whatsapp/calls/reject \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "phoneId": "461269257068832",
    "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABIYIEF"
  }'
```

A resposta usa a resposta padrão de Calling. Libere a conexão peer local após a requisição e ainda assim aceite um evento posterior de encerramento para este `wacid`, caso chegue algum.

## Iniciar uma chamada iniciada pela empresa

Em uma chamada iniciada pela empresa, seu aplicativo cria a oferta SDP e a envia para a YCloud.

### Obter permissão de chamada

Antes de iniciar uma chamada, obtenha a permissão de chamada do usuário. Uma solicitação de permissão interativa pode ser enviada dentro de uma janela de atendimento ao cliente qualificada:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "from": "+16315551111",
  "to": "+16315552222",
  "type": "interactive",
  "interactive": {
    "type": "call_permission_request",
    "action": { "name": "call_permission_request" },
    "body": { "text": "May we call you to help with your order?" }
  }
}
```

Envie este corpo para `POST /v2/whatsapp/messages/sendDirectly` ou enfileire-o com `POST /v2/whatsapp/messages`.

Você também pode criar um modelo de permissão de chamada. Por exemplo, envie este corpo para `POST /v2/whatsapp/templates` e aguarde a aprovação:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "wabaId": "WABA_ID",
  "name": "call_permission_request_template",
  "language": "en_US",
  "category": "UTILITY",
  "components": [
    {
      "type": "BODY",
      "text": "May we call you about order {{1}}?",
      "example": { "body_text": [["ORDER_123"]] }
    },
    { "type": "call_permission_request" }
  ]
}
```

Envie o modelo aprovado com seu parâmetro de corpo:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "from": "+16315551111",
  "to": "+16315552222",
  "type": "template",
  "template": {
    "name": "call_permission_request_template",
    "language": { "code": "en_US", "policy": "deterministic" },
    "components": [
      { "type": "body", "parameters": [{ "type": "text", "text": "ORDER_123" }] }
    ]
  }
}
```

Quando `callback_permission_status` estiver ativado nas configurações de chamada do número de telefone, uma chamada iniciada pelo usuário pode conceder permissão de retorno de chamada. Um usuário também pode conceder permissão de chamada permanente a partir do perfil comercial.

As respostas de permissão chegam como eventos `whatsapp.inbound_message.received`. Inspecione o objeto `interactive.call_permission_reply`, não apenas se a mensagem de solicitação de permissão foi entregue:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "whatsapp.inbound_message.received",
  "whatsappInboundMessage": {
    "from": "+16315552222",
    "to": "+16315551111",
    "type": "interactive",
    "interactive": {
      "type": "call_permission_reply",
      "call_permission_reply": {
        "response": "accept",
        "is_permanent": true,
        "response_source": "user_action"
      }
    }
  }
}
```

| Campo | Significado |
| - | - |
| `response` | O usuário aceitou ou rejeitou a solicitação de permissão. |
| `is_permanent` | Se a concessão é permanente em vez de limitada por tempo. |
| `expiration_timestamp` | Expiração de uma permissão temporária, quando fornecida. |
| `response_source` | Se a resposta veio de uma ação do usuário ou automaticamente. |

Não inicie a chamada após uma rejeição ou uma permissão expirada. O erro da Meta `138006` significa que o número comercial não possui a permissão de chamada necessária. Para obter detalhes sobre erros do provedor, consulte [Erros de Calling da Meta](https://developers.facebook.com/documentation/business-messaging/whatsapp/calling/reference/errors).

### 1. Criar uma oferta SDP

Crie uma conexão peer WebRTC local e anexe a faixa de áudio. Gere a oferta SDP, defina-a como a descrição local e aguarde a conclusão dessa operação antes de enviar a oferta para a YCloud.

### 2. Conectar a chamada

**Endpoint:** [`POST /whatsapp/calls/connect`](/api-reference/whatsapp-calling/connect-a-call)

| Campo | Tipo | Obrigatório | Descrição |
| - | - | - | - |
| `from` | String | Sim | Número de telefone comercial registrado no formato E.164. |
| `to` | String | Condicional | Número de telefone do usuário no formato E.164. Obrigatório quando `recipient` estiver ausente. |
| `recipient` | String | Condicional | BSUID do usuário ou BSUID pai. Obrigatório quando `to` estiver ausente. |
| `sdpType` | String | Sim | Deve ser `offer`. |
| `sdp` | String | Sim | Oferta SDP criada pela sua implementação WebRTC. |

Forneça pelo menos um de `to` ou `recipient`. Se você enviar ambos, a YCloud usará `to` e ignorará `recipient`.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.ycloud.com/v2/whatsapp/calls/connect \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "+16315551111",
    "to": "+16315552222",
    "sdpType": "offer",
    "sdp": "SDP_OFFER"
  }'
```

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABE",
  "success": true
}
```

Armazene o `wacid` retornado imediatamente. `success: true` significa que a operação de conexão foi aceita; não significa que o usuário atendeu.

### 3. Aplicar a resposta e rastrear a tentativa

A YCloud envia [`whatsapp.call.connect`](/pt/api-reference/guides/examples/webhook-examples/whatsapp-calling-connect-webhook-examples) para a chamada. Para uma chamada iniciada pela empresa, o evento tem `direction: BUSINESS_INITIATED` e contém o SDP remoto `answer`. Aplique essa resposta como a descrição remota para a mesma conexão peer.

Inscreva-se em [`whatsapp.call.status.updated`](/pt/api-reference/guides/examples/webhook-examples/whatsapp-calling-status-update-webhook-examples) para acompanhar a tentativa:

```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",
    "phoneId": "461269257068832",
    "status": "RINGING",
    "recipientPhone": "+16315552222"
  }
}
```

| Status | Significado | Ação recomendada |
| - | - | - |
| `RINGING` | A chamada está tocando para o usuário. | Mantenha a tentativa aberta e continue aguardando. |
| `ACCEPTED` | O usuário aceitou a chamada. | Use o estado da conexão WebRTC para confirmar a prontidão da mídia. |
| `REJECTED` | O usuário rejeitou a chamada. | Interrompa a tentativa e libere os recursos locais de WebRTC. |

Torne o tratamento de eventos idempotente para que um reenvio não repita ações do agente, faturamento ou limpeza.

## Encerrar uma chamada ativa

Chame terminate quando o seu aplicativo precisar encerrar uma chamada ativa recebida ou efetuada.

**Endpoint:** [`POST /whatsapp/calls/terminate`](/api-reference/whatsapp-calling/terminate-a-call)

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.ycloud.com/v2/whatsapp/calls/terminate \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "phoneId": "461269257068832",
    "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABE"
  }'
```

Os campos da requisição coincidem com os da solicitação de rejeição. Uma resposta bem-sucedida confirma que a YCloud processou a operação de encerramento. Mantenha o registro da chamada aberto até receber o evento final de encerramento ou até que sua própria política de recuperação o feche.

## Resposta

Todos os cinco endpoints de sinalização retornam o mesmo formato de resposta:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABE",
  "success": true
}
```

`wacid` identifica a chamada associada à operação. `success: true` confirma que a operação de sinalização foi bem-sucedida; isso não confirma que o outro participante atendeu ou que a chamada foi concluída. Use o estado do WebRTC e os eventos de Webhook de chamadas para esses resultados.

## Processar o evento final da chamada

[`whatsapp.call.terminate`](/pt/api-reference/guides/examples/webhook-examples/whatsapp-calling-terminate-webhook-examples) é o evento final do ciclo de vida de uma chamada.

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

| Campo | Descrição |
| - | - |
| `wacid` | ID da chamada usado para associar o evento ao registro da sua chamada. |
| `direction` | `USER_INITIATED` ou `BUSINESS_INITIATED`. |
| `startTime`, `endTime` | timestamps Unix em milissegundos. |
| `duration` | Duração da chamada em segundos. |
| `status` | Resultado final: `COMPLETED` ou `FAILED`. |
| `errorCode` | Código de erro numérico representado como uma string quando a chamada falhou. |

Ao receber esse evento, finalize o registro da chamada e libere quaisquer recursos restantes do WebRTC. Uma resposta anterior da API não confirma que a chamada foi concluída.

## Receber gravações e transcrições

Quando a captura está habilitada, o processamento de mídia continua após o ciclo de vida da chamada. A gravação e a transcrição possuem eventos terminais separados:

| Evento | Propriedade do payload | Resultado |
| - | - | - |
| [`whatsapp.call.recording.updated`](/pt/api-reference/webhooks/test-webhooks) | `callingRecording` | A gravação está `AVAILABLE` ou `FAILED` permanentemente. |
| [`whatsapp.call.transcription.updated`](/pt/api-reference/webhooks/test-webhooks) | `callingTranscription` | A transcrição está `AVAILABLE` ou falhou permanentemente (`FAILED`). |

O exemplo a seguir mostra uma gravação disponível:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "evt_call_recording_01JZ8K4V7H3P6Q9R2T5W8X1Y4Z",
  "type": "whatsapp.call.recording.updated",
  "apiVersion": "v2",
  "createTime": "2026-08-04T08:00:00.000Z",
  "callingRecording": {
    "wacid": "wacid.HBgNNjI4MTM2MTkwNTEzMxUCABE",
    "phoneId": "461269257068832",
    "mediaAssetId": "66b1f0c2e4b05c2d8f1a3b47",
    "status": "AVAILABLE"
  }
}
```

Ambas as propriedades do payload usam os mesmos campos:

| Campo | Descrição |
| - | - |
| `wacid` | ID da chamada associado ao ativo de mídia. |
| `phoneId` | ID do número de telefone comercial associado à chamada. |
| `mediaAssetId` | ID do ativo da YCloud usado pela API de download de mídia. |
| `status` | `AVAILABLE` ou `FAILED`. |
| `error.code` | Código estável de falha de processamento. Presente quando `status` for `FAILED`. |
| `error.retryable` | Se tentar novamente a operação de mídia upstream pode ter sucesso. Presente quando `status` for `FAILED`. |

### Baixar um ativo disponível

Chame o endpoint de mídia apenas depois que o evento correspondente reportar `AVAILABLE`.

**Endpoint:** [`GET /whatsapp/calls/media/{mediaAssetId}`](/api-reference/whatsapp-calling/download-call-media)

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request GET \
  "https://api.ycloud.com/v2/whatsapp/calls/media/66b1f0c2e4b05c2d8f1a3b47" \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --output calling-media.ogg
```

O endpoint retorna o arquivo completo como um anexo e não oferece suporte a downloads de intervalos de bytes (byte-range). As gravações usam `.ogg`; as transcrições usam `.json`.

Apenas o locatário proprietário da YCloud pode baixar um ativo. Um ativo permanece disponível por 30 dias a partir da data de criação. Ativos ausentes, indisponíveis, expirados ou que não pertençam ao locatário retornam HTTP 404.

## Construir um receptor de Webhook confiável

Inscreva seu endpoint nos eventos de que sua integração precisa:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "enabledEvents": [
    "whatsapp.call.connect",
    "whatsapp.call.status.updated",
    "whatsapp.call.terminate",
    "whatsapp.call.recording.updated",
    "whatsapp.call.transcription.updated"
  ]
}
```

Para cada solicitação:

1. Preserve o corpo bruto da solicitação e verifique `YCloud-Signature` antes de confiar no evento.
2. Persista o evento ou enfileire o trabalho durável.
3. Retorne uma resposta de sucesso `2xx` imediatamente.
4. Elimine a duplicação usando o evento de nível superior `id`.
5. Correlacione os dados da chamada por `wacid`; mantenha `phoneId` com eles para operações posteriores.
6. Trate eventos relacionados que chegam próximos uns dos outros e tolere reenvios.

Consulte [Configurar webhooks](/pt/api-reference/guides/api-fundamentals/configure-webhooks) para criação de endpoint, validação de assinatura e comportamento de entrega. A página [Exemplos de payload de webhook](/pt/api-reference/guides/examples/webhook-examples/webhook-payload-examples) contém os exemplos gerados completos.

## Tratar erros e recuperação

Os endpoints de Calling usam a resposta de erro padrão da API da YCloud. Consulte [Tratar erros](/pt/api-reference/guides/api-fundamentals/handle-errors) para obter a estrutura de resposta e orientações de repetição.

Use estas verificações para falhas comuns de Calling:

| Situação | O que verificar | Recuperação |
| - | - | - |
| Falha na validação da requisição | IDs obrigatórios, formatação E.164, tipo de SDP, conteúdo de SDP ou campos de captura. | Corrija a requisição. Não tente novamente com dados inalterados. |
| O destino de conexão é inválido | É necessário pelo menos um de `to` ou `recipient`. Se ambos estiverem presentes, `to` tem precedência. | Envie um número de telefone E.164 válido ou BSUID. |
| Calling indisponível | Titularidade do número de telefone, registro, configurações de Calling, permissão e destino com suporte. | Corrija a configuração ou a permissão antes de tentar novamente. |
| A Meta rejeita a sinalização | Inspecione os detalhes do erro retornado, incluindo `whatsappApiError` quando presente. | Siga as diretrizes de nova tentativa do erro e corrija a causa upstream. |
| Falha ao salvar configurações combinadas | Uma das configurações, `calling` ou `capture`, pode já ter sido salva. | Leia ambas as configurações e tente novamente apenas a parte que ainda precisa de atualização. |
| O download de mídia retorna 400 | Um cabeçalho `Range` não vazio foi enviado. | Solicite o recurso completo sem `Range`. |
| O download de mídia retorna 404 | O recurso está ausente, ainda não disponível, expirado ou pertence a outro locatário. | Confirme o status do evento, o locatário, o ID do recurso e a janela de 30 dias. |
| Webhook repetido | O mesmo evento foi entregue novamente. | Retorne `2xx` e ignore o processamento de negócios repetido pelo `id` do evento. |

Um tempo limite de requisição (timeout) não comprova que a ação de sinalização falhou. Antes de tentar novamente, reconcilie a requisição com os eventos de webhook e o estado local atual da chamada. A ação já pode ter chegado ao WhatsApp.

## Lista de verificação de integração

* Ative Calling no número de telefone comercial correto.
* Configure e teste todas as assinaturas de webhook de Calling necessárias.
* Verifique assinaturas de webhook e elimine eventos duplicados.
* Armazene `wacid`, `phoneId`, direção e o estado atual juntos.
* Trate `success` da API como aceitação da operação, não como o resultado final da chamada.
* Use `preAccept` apenas como preparação; chame `accept` para atender.
* Finalize chamadas a partir de `whatsapp.call.terminate`.
* Baixe a mídia capturada apenas após um evento `AVAILABLE` e dentro de 30 dias.
* Libere recursos WebRTC em caso de rejeição, encerramento, falha e tempo limite local.
* Evite registrar chaves de API, SDP completo ou identificadores de participantes nos logs gerais da aplicação.

<CardGroup cols={2}>
  <Card title="Referência da API de Calling" icon="phone" href="/api-reference/whatsapp-calling/connect-a-call">
    Examine os esquemas exatos de requisição e resposta de cada endpoint de Calling.
  </Card>

  <Card title="Exemplos de payload de webhook" icon="webhook" href="/pt/api-reference/guides/examples/webhook-examples/webhook-payload-examples">
    Inspecione os exemplos completos de eventos de Calling gerados a partir da especificação do webhook.
  </Card>
</CardGroup>


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