Referência de Erros HTTP
Esta página documenta os códigos de erro HTTP que você pode encontrar ao interagir com a API da Videochamada.com.br, com os cenários reais que os produzem e como resolvê-los.
Estrutura de resposta de erro
Todas as respostas de erro seguem o formato JSON:
{
"statusCode": 400,
"timestamp": "2026-08-30T14:22:01.000Z",
"path": "/api/calls",
"message": "Descrição legível do erro"
}
Códigos de erro por categoria
400 — Bad Request
Parâmetros inválidos ou operação que não faz sentido no estado atual do recurso.
| Mensagem | Cenário | Solução |
|---|---|---|
startDate and endDate are required |
GET /api/calls sem os parâmetros de período |
Informe startDate e endDate na listagem de chamadas |
Call is already ended |
POST /api/calls/{id}/end em uma chamada já encerrada |
Consulte GET /api/calls/{id}/status antes de encerrar |
Failed to end call: ... |
Falha durante o encerramento da chamada | Verifique a mensagem detalhada e tente novamente |
Expected exactly one participant role |
POST /api/calls/{id}/access com corpo diferente de {"role": "..."} |
Envie exatamente um campo role no corpo |
Invalid participant role |
role fora dos valores aceitos |
Use customer, attendant ou supervisor |
Idempotency-Key must contain 1 to 200 printable characters |
Header Idempotency-Key vazio, longo demais ou com caracteres de controle |
Use uma chave de 1 a 200 caracteres imprimíveis |
Exemplo de resposta:
{
"statusCode": 400,
"timestamp": "2026-08-30T14:22:01.000Z",
"path": "/api/calls/9f3b2a1c-7d4e-4c8a-b5f6-2e1d0c9b8a7f/end",
"message": "Call is already ended"
}
401 — Unauthorized
Credencial ausente, inválida ou não autorizada para a operação.
| Mensagem | Cenário | Solução |
|---|---|---|
API key is missing |
Header Authorization não foi enviado |
Adicione Authorization: Bearer {API_TOKEN} à requisição |
Invalid API key |
API key inexistente, revogada — ou requisição vinda de um IP fora da lista de IPs permitidos da chave (a resposta não distingue os dois casos) | Verifique a chave no painel e, se a chave tem restrição de IP, confirme que o IP de origem está na lista |
Organization subscription is suspended. Please update your payment information. |
Assinatura da organização suspensa | Atualize os dados de pagamento no painel |
Expiration date must be in the future |
POST /api/calls com expiresAt no passado ou inválido |
Envie uma data futura em formato ISO 8601. Observação: hoje este cenário retorna 401, embora seja um erro de validação — trate-o como um dado inválido |
Call does not belong to this project |
POST /api/calls/{id}/end, GET /api/calls/{id}/status, GET /api/calls/{id}/events ou GET /api/calls/{id}/participants com uma chamada de outro projeto |
Use a API key do projeto ao qual a chamada pertence |
Exemplo de resposta:
{
"statusCode": 401,
"timestamp": "2026-08-30T14:22:01.000Z",
"path": "/api/calls",
"message": "API key is missing"
}
403 — Forbidden
Você está autenticado, mas a operação não é permitida.
| Mensagem | Cenário | Solução |
|---|---|---|
Maximum spending limit reached for this month |
Limite de gastos mensal da assinatura atingido ao criar uma chamada | Aumente o limite de gastos no painel ou aguarde o próximo ciclo |
Call does not belong to this project |
POST/DELETE /api/calls/{id}/recordings ou POST /api/calls/{id}/access com uma chamada de outro projeto |
Use a API key do projeto correto |
Recording does not belong to this project |
GET /api/calls/{id}/recordings, GET /api/calls/{id}/transcriptions ou GET /recordings/files/{fileId}/download-url com recurso de outro projeto |
Use a API key do projeto correto |
Recording is not enabled for this call |
Tentativa de gravação em chamada sem gravação habilitada | Habilite a gravação da chamada antes |
O mesmo cenário pode retornar 401 ou 403
O cenário "recurso de outro projeto" pode retornar 401 ou 403 dependendo do endpoint (por exemplo, POST /api/calls/{id}/end responde 401 e POST /api/calls/{id}/recordings responde 403, ambos com mensagens equivalentes). Na sua integração, trate os dois códigos da mesma forma: a credencial usada não está autorizada para este recurso — quase sempre é uma API key do projeto errado.
Exemplo de resposta:
{
"statusCode": 403,
"timestamp": "2026-08-30T14:22:01.000Z",
"path": "/api/calls",
"message": "Maximum spending limit reached for this month"
}
404 — Not Found
O recurso solicitado não foi encontrado.
| Mensagem | Cenário | Solução |
|---|---|---|
Call not found |
ID de chamada inexistente | Verifique o ID da chamada |
Recording file not found |
ID de arquivo de gravação inexistente em GET /recordings/files/{fileId}/download-url |
Verifique o ID do arquivo retornado na listagem de gravações |
Call does not have recording enabled |
GET /api/calls/{id}/transcriptions em chamada sem gravação habilitada |
Habilite a gravação antes de consultar transcrições |
Organization not found / Subscription not found |
Conta com configuração incompleta ao criar uma chamada | Entre em contato com o suporte |
Exemplo de resposta:
{
"statusCode": 404,
"timestamp": "2026-08-30T14:22:01.000Z",
"path": "/api/calls/9f3b2a1c-7d4e-4c8a-b5f6-2e1d0c9b8a7f/status",
"message": "Call not found"
}
409 — Conflict
| Mensagem | Cenário | Solução |
|---|---|---|
Idempotency-Key was already used with a different request |
A mesma Idempotency-Key foi reutilizada em POST /api/calls com um corpo diferente do original |
Gere uma chave nova para cada requisição distinta; reutilize a chave apenas para reenviar exatamente a mesma requisição |
Exemplo de resposta:
{
"statusCode": 409,
"timestamp": "2026-08-30T14:22:01.000Z",
"path": "/api/calls",
"message": "Idempotency-Key was already used with a different request"
}
410 — Gone
O recurso existiu, mas não está mais disponível. Diferente do 404, o 410 é definitivo — não adianta repetir a requisição.
| Mensagem | Cenário | Solução |
|---|---|---|
Recording expired on {data}. Retention period: {N} days |
Download de gravação após o fim do período de retenção | Baixe e armazene as gravações dentro do período de retenção do seu plano |
Call access has expired |
POST /api/calls/{id}/access para uma chamada cujo expiresAt já passou |
Crie uma nova chamada; tokens de acesso não podem ser emitidos para chamadas expiradas |
Exemplo de resposta:
{
"statusCode": 410,
"timestamp": "2026-08-30T14:22:01.000Z",
"path": "/api/calls/9f3b2a1c-7d4e-4c8a-b5f6-2e1d0c9b8a7f/access",
"message": "Call access has expired"
}
5xx — Erros do servidor
Erros 500/503 indicam uma falha temporária do lado da plataforma. Eles são monitorados internamente; na sua integração, trate-os com nova tentativa e backoff exponencial (veja abaixo). Em erros 500, o campo message retorna sempre o texto genérico "Internal server error" — os detalhes ficam apenas nos logs internos.
Uso responsável
Não há limites rígidos de requisições (rate limiting) publicados hoje — a API não retorna 429. Ainda assim:
- Prefira webhooks a polling constante para acompanhar chamadas.
- Aplique backoff exponencial ao repetir requisições que falharam com erros
5xx. - Use cache no seu lado para dados que mudam pouco.
Boas práticas de tratamento de erros
1. Sempre verifique o status HTTP
const response = await fetch(
'https://api.videochamada.com.br/api/calls?startDate=2025-10-01&endDate=2025-10-31',
{ headers: { Authorization: 'Bearer ' + apiToken } },
);
if (!response.ok) {
const error = await response.json();
console.error(`Erro ${error.statusCode}: ${error.message}`);
// Trate o erro apropriadamente
}
2. Implemente retry com backoff exponencial para 5xx
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.ok) {
return response;
}
// Repita apenas erros de servidor; erros 4xx não mudam ao repetir
if (response.status >= 500) {
await new Promise((resolve) => setTimeout(resolve, Math.pow(2, i) * 1000));
continue;
}
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
}
3. Registre erros para análise
import logging
import requests
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
except requests.exceptions.HTTPError as e:
logging.error(f"HTTP Error: {e.response.status_code} - {e.response.text}")
# Trate o erro apropriadamente
4. Use webhooks em vez de polling
// ❌ Evite: polling a cada 5 segundos
setInterval(async () => {
const status = await getCallStatus(callId);
}, 5000);
// ✅ Prefira: configure um webhook para call.ended
// Você receberá a notificação automaticamente quando a chamada encerrar
Suporte
Se você continuar enfrentando erros após seguir este guia:
- 📧 Email: suporte@videochamada.com.br
- 📚 Documentação: https://documentacao.videochamada.com.br
Ao entrar em contato, inclua:
- Endpoint acessado
- Código de status HTTP recebido
- Mensagem de erro completa
- Data e hora aproximada da requisição