EvoluAIv2 Docs

Erros e Limites

Códigos de erro, rate limit, limites de uso e estratégias de retry para a API da EvoluAI.

Erros e Limites


Códigos HTTP

CódigoSignificadoCausa mais comum
200OKSucesso
400Bad RequestParâmetros inválidos ou ausentes
401UnauthorizedAPI Key inválida, expirada ou ausente
403ForbiddenSem permissão para o recurso
404Not FoundRecurso não existe
422UnprocessableÁudio inválido ou transcrição falhou
429Too Many RequestsRate limit atingido
500Internal Server ErrorErro interno — tente novamente

Formato das respostas de erro

Todos os erros seguem o mesmo formato:

{
  "error": {
    "message": "Descrição do erro",
    "code": "CODIGO_TRPC",
    "data": {
      "httpStatus": 400,
      "issues": []
    }
  }
}

Erros comuns

401 — Unauthorized

{
  "error": {
    "message": "Unauthorized",
    "code": "UNAUTHORIZED"
  }
}

Causas:

  • X-API-Key ausente no header
  • API Key inválida ou mal formatada
  • API Key revogada pelo administrador
  • API Key expirada (se foi criada com data de expiração)

Solução: Verifique a chave via GET /trpc/user.me. Se retornar 401, gere uma nova chave no dashboard.


403 — Forbidden

{
  "error": {
    "message": "Access denied",
    "code": "FORBIDDEN"
  }
}

Causas:

  • Tentativa de acessar análises de outra empresa
  • Papel (role) sem permissão para a operação (ex: salesperson tentando listar outros usuários)
  • Tentativa de deletar recurso de outro usuário

400 — Bad Request

{
  "error": {
    "message": "Invalid input",
    "code": "BAD_REQUEST",
    "data": {
      "issues": [
        {
          "path": ["salespersonId"],
          "message": "Required"
        },
        {
          "path": ["audioUrl"],
          "message": "Must be a valid HTTPS URL"
        }
      ]
    }
  }
}

Causas frequentes:

  • salespersonId não informado em analysis.create
  • Nenhum dos campos audioUrl, audioKey ou transcript informado
  • URL de áudio usando HTTP (não HTTPS)
  • Formato de data inválido em filtros

422 — Unprocessable

{
  "error": {
    "message": "Audio processing failed",
    "code": "UNPROCESSABLE_CONTENT"
  }
}

Causas:

  • Arquivo de áudio corrompido ou formato não suportado
  • Áudio muito curto (menos de 5 segundos)
  • Áudio sem voz detectável (silêncio total)
  • URL do áudio inacessível no momento do processamento

Formatos aceitos: MP3, WAV, M4A, OGG, FLAC, WebM


429 — Rate Limit

{
  "error": {
    "message": "Rate limit exceeded",
    "code": "TOO_MANY_REQUESTS"
  }
}

Limite: 60 requisições por minuto por API Key.

Quando atingido, aguarde 60 segundos antes de tentar novamente. Use a estratégia de retry com backoff exponencial abaixo.


Créditos insuficientes

{
  "error": {
    "message": "Insufficient credits to process analysis",
    "code": "PAYMENT_REQUIRED"
  }
}

Causa: Saldo de créditos zerado ou abaixo do mínimo para processar o áudio.

Solução: Verifique o saldo com GET /trpc/credits.getSummary e adquira mais créditos pelo dashboard antes de continuar.

Créditos não são debitados em caso de erro. Se uma análise falhar (422, 500), nenhum crédito é consumido.


Limites da API

Rate limit

RecursoLimite
Requisições por minuto60 req/min por API Key
API Keys simultâneas10 por empresa

Limites de arquivo e áudio

RecursoLimite
Tamanho máximo do arquivo40 MB
Duração máxima do áudio2 horas
Duração mínima do áudio5 segundos

Limites de paginação

RecursoPadrãoMáximo
analysis.list — itens por página20100
credits.getHistory — itens por página2020 (fixo)

Estratégia de retry com backoff exponencial

Para erros 429 (rate limit) e 500 (erro interno), use retry com backoff exponencial para evitar sobrecarga:

async function fetchComRetry(url, options, maxTentativas = 3) {
  for (let tentativa = 0; tentativa < maxTentativas; tentativa++) {
    const res = await fetch(url, options);

    // Sucesso
    if (res.ok) return res.json();

    const erro = await res.json();

    // Rate limit — aguarda e tenta novamente
    if (res.status === 429) {
      const espera = Math.pow(2, tentativa) * 1000; // 1s, 2s, 4s
      console.warn(`Rate limit atingido. Aguardando ${espera}ms...`);
      await new Promise(r => setTimeout(r, espera));
      continue;
    }

    // Erro interno — tenta novamente com backoff
    if (res.status === 500) {
      if (tentativa === maxTentativas - 1) throw new Error(`Erro 500 após ${maxTentativas} tentativas`);
      const espera = Math.pow(2, tentativa) * 2000; // 2s, 4s, 8s
      await new Promise(r => setTimeout(r, espera));
      continue;
    }

    // Erros 4xx (exceto 429) — não tenta novamente
    throw Object.assign(new Error(erro.error?.message || 'Erro na requisição'), {
      status: res.status,
      code: erro.error?.code
    });
  }
}

// Uso
const dados = await fetchComRetry(
  'https://api.evolu-ai.com/trpc/analysis.create',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': process.env.EVOLUA_API_KEY
    },
    body: JSON.stringify({ json: { salespersonId: 'user_abc', audioUrl: '...' } })
  }
);

Erros de validação Zod

Para requisições POST, os erros de validação incluem detalhes por campo:

{
  "error": {
    "message": "Invalid input",
    "code": "BAD_REQUEST",
    "data": {
      "issues": [
        {
          "path": ["audioUrl"],
          "message": "Invalid url"
        },
        {
          "path": ["clientName"],
          "message": "String must contain at most 255 character(s)"
        }
      ]
    }
  }
}

Use o array issues para identificar exatamente qual campo está inválido e exibir mensagens de erro precisas ao usuário final.

On this page