Pular para o conteúdo principal

Referência da API de Chamadas

URL base: https://pilotstatus.com.br/v1 Cabeçalhos: Content-Type: application/json, x-api-key: <your_api_key> (ou x-api-key-id).
As chamadas funcionam em dois provedores: números Meta Cloud API e números não oficiais (Pilot Status web) (conectados por QR). Qualquer outro provedor retorna 400 FEATURE_NOT_SUPPORTED. Todos os endpoints exigem uma chave com escopo de número. Veja a visão geral.
Meta exige SDP. No provedor Meta a mídia flui pelo navegador via WebRTC — você fornece uma oferta SDP ao iniciar e uma resposta SDP ao atender. O provedor não oficial não usa SDP: a mídia é tratada no servidor, então sdpOffer/sdpAnswer permanecem null e não há modelo de permissão BIC nem superfície de configurações de chamada.

Endpoints

Os provedores marcados são os que suportam cada endpoint. Chamar um endpoint em um provedor não suportado retorna 400 FEATURE_NOT_SUPPORTED. Se um número não oficial não estiver conectado, os endpoints retornam 409 WHATSAPP_INSTANCE_NOT_CONNECTED.
MétodoEndpointProvedoresDescrição
POST/v1/callsMETA, não oficialInicia uma chamada iniciada pela empresa (BIC).
GET/v1/callsMETA, não oficialLista as chamadas do número (mais recentes primeiro; limit 1–100, before cursor ISO 8601).
GET/v1/calls/{callId}META, não oficialUma chamada; adicione ?includeSdp=1 para receber sdpOffer/sdpAnswer (Meta).
POST/v1/calls/{callId}/acceptMETA, não oficialAtende uma chamada recebida (UIC). No Meta, com resposta SDP; no não oficial, sem SDP.
POST/v1/calls/{callId}/rejectMETA, não oficialRecusa uma chamada recebida (sem corpo).
POST/v1/calls/{callId}/terminateMETA, não oficialDesliga uma chamada ativa (sem corpo).
POST/v1/calls/{callId}/pre-acceptSomente METAResposta SDP antecipada OPCIONAL (reduz cortes no áudio; a chamada só conecta ao aceitar).
GET/v1/calls/settingsSomente METALê o objeto de configurações calling do número.
PUT/v1/calls/settingsSomente METAAtualização parcial das configurações calling.
GET/v1/calls/permissions?to=<phone>Somente METAVerifica se a empresa pode ligar para to.
POST/v1/calls/permissions/requestSomente METAEnvia a solicitação interativa de permissão de chamada (dentro da janela de 24h).
POST/v1/calls/{callId}/playSomente não oficialReproduz um arquivo de áudio na chamada (mídia no servidor).
POST/v1/calls/{callId}/realtime-sessionSomente não oficialAbre uma sessão WebSocket full-duplex de áudio PCM16.
{callId} aceita ou o id de chamada do Pilot Status (call_...) ou o id de chamada da Meta (wacid...).

1. Iniciar uma chamada (BIC)

curl -X POST "https://pilotstatus.com.br/v1/calls" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ps_your_key_here" \
  -d '{
    "to": "+5511999999999",
    "sdp": "v=0\r\no=- 4611731400430051336 2 IN IP4 127.0.0.1\r\n...",
    "sdpType": "offer",
    "bizOpaqueCallbackData": "order-42"
  }'
HTTP 201
{ "id": "call_01HZX...", "externalCallId": "wacid.ABGG...", "status": "INITIATED" }
  • Meta: sdp é a oferta RFC 8866 produzida pelo SEU cliente WebRTC. O SDP do lado da empresa deve usar a=setup:active. Sem permissão, a Meta retorna 138006 → o endpoint expõe code: "META_CALL_PERMISSION_REQUIRED".
  • não oficial: não envie sdp — a mídia é tratada no servidor. Não há modelo de permissão BIC.
  • bizOpaqueCallbackData (opcional, Meta) é devolvido no webhook de encerramento.

2. Atender uma chamada recebida (UIC)

Quando um usuário liga para o seu número, você recebe o webhook call.ringing. Então:
# busca a chamada com a oferta SDP
curl "https://pilotstatus.com.br/v1/calls/wacid.ABGG...?includeSdp=1" \
  -H "x-api-key: ps_your_key_here"

# atende (corpo: sua resposta SDP; sdpType usa "answer" como padrão)
curl -X POST "https://pilotstatus.com.br/v1/calls/wacid.ABGG.../accept" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ps_your_key_here" \
  -d '{ "sdp": "v=0\r\n..." }'
# recusa / desliga (sem corpo, ambos provedores)
curl -X POST "https://pilotstatus.com.br/v1/calls/wacid.ABGG.../reject" -H "x-api-key: ps_your_key_here"
curl -X POST "https://pilotstatus.com.br/v1/calls/wacid.ABGG.../terminate" -H "x-api-key: ps_your_key_here"
accept/pre-accept/reject/terminate respondem { "success": true, "id": "call_...", "status": "..." }. O pre-accept (somente Meta) é opcional (resposta SDP antecipada para reduzir cortes); a chamada só conecta no accept.

3. Habilitar chamadas e configurações (somente Meta)

As seções 3 e 4 aplicam-se apenas a números Meta. No provedor não oficial não há superfície de configurações de chamada nem modelo de permissão BIC — chamar esses endpoints retorna 400 FEATURE_NOT_SUPPORTED.
O Pilot Status tenta habilitar chamadas automaticamente quando um número Meta conecta. Leia/ajuste a qualquer momento:
curl "https://pilotstatus.com.br/v1/calls/settings" \
  -H "x-api-key: ps_your_key_here"

curl -X PUT "https://pilotstatus.com.br/v1/calls/settings" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ps_your_key_here" \
  -d '{ "status": "ENABLED", "call_icon_visibility": "DEFAULT" }'
  • O PUT é parcial: envie apenas status, call_icon_visibility, callback_permission_status, call_hours, voicemail (o objeto sip é rejeitado).
  • Um call_hours enviado substitui o objeto armazenado por completo (semântica da Meta).
  • Números com um limite de mensagens abaixo de 2.000/dia ainda não podem habilitar chamadas (erro 138015 da Meta).
  • Credenciais SIP nunca são solicitadas nem retornadas.

4. Permissão de chamada (somente Meta, obrigatória antes de uma BIC)

# verificar
curl "https://pilotstatus.com.br/v1/calls/permissions?to=%2B5511999999999" \
  -H "x-api-key: ps_your_key_here"

# solicitar (dentro da janela de atendimento de 24h)
curl -X POST "https://pilotstatus.com.br/v1/calls/permissions/request" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ps_your_key_here" \
  -d '{ "to": "+5511999999999", "text": "May we call you about your order?" }'
Resposta da verificação:
{
  "permission": { "status": "temporary", "expiration_time": 1768550400 },
  "actions": [
    {
      "action_name": "start_call",
      "can_perform_action": true,
      "limits": [{ "time_period": "PT24H", "max_allowed": 1, "current_usage": 0 }]
    }
  ]
}
A resposta do usuário chega como o evento de webhook call.permission_updated (status: NO_PERMISSION | TEMPORARY | PERMANENT). A Meta limita a taxa de solicitações de permissão (erro 138009) e o volume de BIC (100 chamadas/24h por número — erro 138012).

5. Reproduzir áudio na chamada (somente não oficial)

Nos números não oficiais a mídia é tratada no servidor, então você pode instruir o backend a baixar um arquivo de áudio e reproduzi-lo na chamada ativa. O backend busca a URL através de um guard de SSRF.
curl -X POST "https://pilotstatus.com.br/v1/calls/call_01HZX.../play" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ps_your_key_here" \
  -d '{ "url": "https://example.com/audio.ogg" }'
Endpoint somente não oficial — em um número Meta retorna 400 FEATURE_NOT_SUPPORTED.

6. Sessão de áudio em tempo real (somente não oficial)

Abre uma sessão WebSocket full-duplex de áudio PCM16 para transmitir áudio de/para a chamada ao vivo.
curl -X POST "https://pilotstatus.com.br/v1/calls/call_01HZX.../realtime-session" \
  -H "x-api-key: ps_your_key_here"
{ "wsUrl": "wss://<host-de-mídia-dedicado>/...", "token": "...", "expiresIn": 120 }
A wsUrl retornada aponta para um host de mídia dedicado — conecte-se diretamente a ela (não é feito proxy). O token é de uso único com TTL de ~2 minutos. A camada HTTP não faz upgrade de WebSocket. Endpoint somente não oficial (Meta → 400 FEATURE_NOT_SUPPORTED).

7. Objeto de chamada (DTO)

{
  "id": "call_01HZX...",
  "externalCallId": "wacid.ABGG...",
  "direction": "INBOUND",
  "status": "COMPLETED",
  "peerNumber": "5511999999999",
  "fromNumber": "5511999999999",
  "conversationId": "conv_abc",
  "bizOpaqueCallbackData": null,
  "startedAt": "2026-07-03T15:00:00.000Z",
  "connectedAt": "2026-07-03T15:00:05.000Z",
  "endedAt": "2026-07-03T15:02:05.000Z",
  "durationSeconds": 120,
  "errorCode": null,
  "errorMessage": null,
  "createdAt": "2026-07-03T15:00:00.000Z",
  "updatedAt": "2026-07-03T15:02:05.000Z"
}
  • status: INITIATED | RINGING | ACCEPTED | REJECTED | COMPLETED | FAILED | MISSED.
  • direction: INBOUND (UIC) | OUTBOUND (BIC).
  • Os SDPs (sdpOffer/sdpAnswer) aparecem apenas com ?includeSdp=1 em GET /v1/calls/{callId} — nunca na listagem. No provedor não oficial permanecem null (mídia no servidor).
  • durationSeconds é definido apenas quando a chamada foi atendida.

Webhooks

Estes eventos disparam para ambos os provedores (META e não oficial):

Eventos de chamada

call.ringing · call.connected · call.ended (com duration quando atendida) · call.missed · call.permission_updated

Faturamento

  • Meta: as BIC são cobradas pela Meta na WABA (por minuto, pulsos de 6s, apenas quando atendida). As UIC são gratuitas.
  • não oficial: sem cobrança por minuto da Meta.
  • O Pilot Status não cobra nada pelas chamadas em nenhum dos provedores.

Erros comuns

  • 400 FEATURE_NOT_SUPPORTED — o número da chave não suporta o endpoint (ex.: um provedor não suportado, ou um endpoint exclusivo de um provedor chamado no outro).
  • 409 WHATSAPP_INSTANCE_NOT_CONNECTED — número não oficial não conectado.
  • 400 NUMBER_NOT_FOUND — a chave não está vinculada a um número.
  • 400 — validação do corpo, INVALID_LIMIT, INVALID_BEFORE, MISSING_TO.
  • 401x-api-key / x-api-key-id ausente/inválido.
  • 403 — chave com escopo de tenant (os endpoints de chamadas têm escopo de número).
  • 404 CALL_NOT_FOUND — o callId/wacid não pertence ao número da chave.
  • Erros de chamada da Meta são encaminhados com um code mapeado — ex.: META_CALL_PERMISSION_REQUIRED (138006), limite de solicitação de permissão (138009), limite de BIC de 100 chamadas/24h (138012), chamadas não habilitadas (138000), tier de mensagens muito baixo para habilitar (138015).