# Abrir ponte WebSocket de vídeo `GET /call/{id}/video` Upgrade WebSocket. Mensagens binárias nos dois sentidos: uma unidade de acesso H.264 (Annex-B) por mensagem, precedida por cabeçalho de 8 bytes — byte 0 versão (1); byte 1 flags (bit 0 = keyframe, informado na descida); byte 2 orientação da câmera do contato (0..3, descida); byte 3 reservado; bytes 4..7 duração do quadro em microssegundos, big-endian (na subida avança o relógio do fluxo; 0 = passo padrão de 1/30 s). A API não codifica nem decodifica pixels: o cliente usa WebCodecs, ffmpeg ou codec de hardware. Mensagens de texto da API são avisos JSON: {\"event\":\"keyframe\"} quando o contato precisa de um IDR no próximo quadro e {\"event\":\"video\",\"video\":{...}} a cada mudança de videoState (o primeiro aviso é o estado atual). Pode ser aberta antes de haver vídeo: assim a ponte não perde o keyframe que abre o fluxo do contato. Quadros enviados com o fluxo fechado são descartados. Perder o socket mantém a chamada e a negociação de vídeo por 30 segundos aguardando reconexão com o mesmo callId; um novo socket de vídeo cancela o prazo, substitui o primeiro (4003) e pede um keyframe. Sem retorno, encerra com hangup/local. Para desligar só a câmera, use POST /call/video com action: stop. Códigos 4000 encerrada, 4001 cabeçalho inválido, 4002 falha de escrita, 4003 substituído. Mesma autenticação e origens da ponte de áudio. Exige capabilities.calls_video=true. ## Autenticação Header obrigatório: `token`. Use o token da instância. Base URL: a API do servidor selecionado, como `https://1.atendro.cloud`. O domínio `wpp.atendro.cloud` hospeda a documentação e o console. ## Parâmetros de caminho | Campo | Tipo | Presença | Descrição | |---|---|---|---| | `id` | `string` | obrigatório | callId retornado pela API. Comprimento mínimo: `1` | ## Headers adicionais | Campo | Tipo | Presença | Descrição | |---|---|---|---| | `X-Request-Id` | `string` | opcional | ASCII visível sem espaços, 1–128 caracteres. Inválido/ausente é substituído por UUID. Ecoado na resposta. Comprimento máximo: `128` | ## Corpo da requisição Não há corpo de requisição definido para esta operação. ## Resposta 101 WebSocket estabelecido; mensagens binárias H.264 com cabeçalho e avisos JSON em texto. ## Resposta 400 Upgrade WebSocket inválido. | Campo | Tipo | Presença | Descrição | |---|---|---|---| | `error` | `string` | obrigatório | — | | `message` | `string` | opcional | — | | `messageid` | `string` | opcional | ID para reconciliação quando o resultado é ambíguo. | | `messageId` | `string` | opcional | — | | `id` | `string` | opcional | — | | `provider_code` | `integer` | opcional | — | | `error_key` | `string` | opcional | — | | `error_source` | `string` | opcional | — | | `details` | `object` | opcional | — | | `instance` | `object` | opcional | Modelo: [Instance](https://wpp.atendro.cloud/docs/modelos/instance.md). | ## Resposta 401 unauthorized: header ausente, inválido ou duplicado. Bearer/query/instancekey não substituem admintoken/token. | Campo | Tipo | Presença | Descrição | |---|---|---|---| | `error` | `string` | obrigatório | — | | `message` | `string` | opcional | — | | `messageid` | `string` | opcional | ID para reconciliação quando o resultado é ambíguo. | | `messageId` | `string` | opcional | — | | `id` | `string` | opcional | — | | `provider_code` | `integer` | opcional | — | | `error_key` | `string` | opcional | — | | `error_source` | `string` | opcional | — | | `details` | `object` | opcional | — | | `instance` | `object` | opcional | Modelo: [Instance](https://wpp.atendro.cloud/docs/modelos/instance.md). | Exemplo ilustrativo, com valores sintéticos: ```json { "error": "unauthorized" } ``` ## Resposta 403 Origem de navegador não autorizada. | Campo | Tipo | Presença | Descrição | |---|---|---|---| | `error` | `string` | obrigatório | — | | `message` | `string` | opcional | — | | `messageid` | `string` | opcional | ID para reconciliação quando o resultado é ambíguo. | | `messageId` | `string` | opcional | — | | `id` | `string` | opcional | — | | `provider_code` | `integer` | opcional | — | | `error_key` | `string` | opcional | — | | `error_source` | `string` | opcional | — | | `details` | `object` | opcional | — | | `instance` | `object` | opcional | Modelo: [Instance](https://wpp.atendro.cloud/docs/modelos/instance.md). | ## Resposta 404 call_not_found. | Campo | Tipo | Presença | Descrição | |---|---|---|---| | `error` | `string` | obrigatório | — | | `message` | `string` | opcional | — | | `messageid` | `string` | opcional | ID para reconciliação quando o resultado é ambíguo. | | `messageId` | `string` | opcional | — | | `id` | `string` | opcional | — | | `provider_code` | `integer` | opcional | — | | `error_key` | `string` | opcional | — | | `error_source` | `string` | opcional | — | | `details` | `object` | opcional | — | | `instance` | `object` | opcional | Modelo: [Instance](https://wpp.atendro.cloud/docs/modelos/instance.md). | ## Resposta 409 wrong_instance_kind, not_connected, owned_elsewhere ou chamada já encerrada. | Campo | Tipo | Presença | Descrição | |---|---|---|---| | `error` | `string` | obrigatório | — | | `message` | `string` | opcional | — | | `messageid` | `string` | opcional | ID para reconciliação quando o resultado é ambíguo. | | `messageId` | `string` | opcional | — | | `id` | `string` | opcional | — | | `provider_code` | `integer` | opcional | — | | `error_key` | `string` | opcional | — | | `error_source` | `string` | opcional | — | | `details` | `object` | opcional | — | | `instance` | `object` | opcional | Modelo: [Instance](https://wpp.atendro.cloud/docs/modelos/instance.md). | ## Resposta 501 calls_not_supported: módulo desligado; calls_video_not_supported: vídeo desligado no worker (ATENDROZAP_CALLS_VIDEO_ENABLED) ou motor sem vídeo. | Campo | Tipo | Presença | Descrição | |---|---|---|---| | `error` | `string` | obrigatório | — | | `message` | `string` | opcional | — | | `messageid` | `string` | opcional | ID para reconciliação quando o resultado é ambíguo. | | `messageId` | `string` | opcional | — | | `id` | `string` | opcional | — | | `provider_code` | `integer` | opcional | — | | `error_key` | `string` | opcional | — | | `error_source` | `string` | opcional | — | | `details` | `object` | opcional | — | | `instance` | `object` | opcional | Modelo: [Instance](https://wpp.atendro.cloud/docs/modelos/instance.md). | Exemplo ilustrativo, com valores sintéticos: ```json { "error": "calls_not_supported" } ``` ## Resposta default Falha; usar HTTP status e error. 404 rota inexistente; 405 método inválido com Allow. Ver catálogo no guia de integração. | Campo | Tipo | Presença | Descrição | |---|---|---|---| | `error` | `string` | obrigatório | — | | `message` | `string` | opcional | — | | `messageid` | `string` | opcional | ID para reconciliação quando o resultado é ambíguo. | | `messageId` | `string` | opcional | — | | `id` | `string` | opcional | — | | `provider_code` | `integer` | opcional | — | | `error_key` | `string` | opcional | — | | `error_source` | `string` | opcional | — | | `details` | `object` | opcional | — | | `instance` | `object` | opcional | Modelo: [Instance](https://wpp.atendro.cloud/docs/modelos/instance.md). | ## Exemplos de requisição Defina as variáveis no ambiente privado e substitua os dados sintéticos antes de usar. Os exemplos não executam operações nesta página. ### cURL ```sh curl --request GET "$ATENDROZAP_URL/call/${ID}/video" \ --header "token: $ATENDROZAP_INSTANCE_TOKEN" ``` ### JavaScript ```javascript const baseUrl = process.env.ATENDROZAP_URL; let path = "/call/{id}/video"; path = path.replace("{id}", encodeURIComponent(process.env.ID)); const url = new URL(path, baseUrl); const response = await fetch(url, { method: "GET", headers: { "token": process.env.ATENDROZAP_INSTANCE_TOKEN }, }); if (!response.ok) { throw new Error(`AtendroZAP: HTTP ${response.status}`); } const result = await response.json(); ``` ## Relacionados - [Chamadas de voz e vídeo](https://wpp.atendro.cloud/docs/api/ligacoes.md) - [Autenticação](https://wpp.atendro.cloud/docs/guias/autenticacao.md) - [Erros e idempotência](https://wpp.atendro.cloud/docs/guias/erros-e-idempotencia.md)