Documentation Index Fetch the complete documentation index at: https://docs.wapizap.com.br/llms.txt
Use this file to discover all available pages before exploring further.
Tratamento de Erros
Este guia explica como a Wapizap API reporta erros e como tratá-los corretamente em sua aplicação.
Formato de Resposta de Erro
Todas as respostas de erro seguem este formato:
{
"success" : false ,
"error" : {
"code" : "ERROR_CODE" ,
"message" : "Descrição legível do erro" ,
"details" : {}
}
}
Campo Tipo Descrição successboolean Sempre false para erros error.codestring Código único do erro (use para lógica) error.messagestring Mensagem legível (use para logs/debug) error.detailsobject Informações adicionais (opcional)
Códigos HTTP
Código Significado Quando Ocorre 400Bad Request Dados inválidos ou faltando 401Unauthorized Token ausente ou inválido 403Forbidden Sem permissão para a ação 404Not Found Recurso não existe 409Conflict Conflito (ex: nome duplicado) 422Unprocessable Dados válidos mas não processáveis 429Too Many Requests Rate limit excedido 500Internal Error Erro interno do servidor 503Service Unavailable Serviço temporariamente indisponível
Erros Comuns
Autenticação (401)
{
"success" : false ,
"error" : {
"code" : "UNAUTHORIZED" ,
"message" : "Invalid API key provided"
}
}
Solução: Verifique se o header Authorization: Bearer SEU_TOKEN está correto.
Instância Não Encontrada (404)
{
"success" : false ,
"error" : {
"code" : "INSTANCE_NOT_FOUND" ,
"message" : "Instance 'minha-instancia' not found"
}
}
Solução: Verifique se o instanceId está correto e se a instância existe.
Instância Desconectada (422)
{
"success" : false ,
"error" : {
"code" : "INSTANCE_NOT_CONNECTED" ,
"message" : "Instance is not connected to WhatsApp"
}
}
Solução: Reconecte a instância usando o endpoint de conexão.
Número Inválido (400)
{
"success" : false ,
"error" : {
"code" : "INVALID_NUMBER" ,
"message" : "The phone number is not registered on WhatsApp" ,
"details" : {
"number" : "5511999999999"
}
}
}
Solução: Use /contacts/check para validar números antes de enviar.
Rate Limit (429)
{
"success" : false ,
"error" : {
"code" : "RATE_LIMIT_EXCEEDED" ,
"message" : "Too many requests. Please retry after 60 seconds." ,
"details" : {
"retryAfter" : 60 ,
"limit" : 30 ,
"remaining" : 0
}
}
}
Solução: Aguarde o tempo indicado em retryAfter e implemente exponential backoff.
Mídia Muito Grande (400)
{
"success" : false ,
"error" : {
"code" : "MEDIA_TOO_LARGE" ,
"message" : "Media file exceeds maximum size" ,
"details" : {
"maxSize" : "16MB" ,
"receivedSize" : "25MB"
}
}
}
Solução: Reduza o tamanho do arquivo antes de enviar.
Tratamento em Código
JavaScript/TypeScript
async function sendMessage ( instanceId , to , text ) {
try {
const response = await fetch ( 'https://api.wapizap.com/api/v2/messages' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'Authorization' : `Bearer ${ API_KEY } `
},
body: JSON . stringify ({ instanceId , to , type: 'text' , text })
});
const data = await response . json ();
if ( ! data . success ) {
// Tratar erro baseado no código
switch ( data . error . code ) {
case 'INSTANCE_NOT_CONNECTED' :
await reconnectInstance ( instanceId );
return sendMessage ( instanceId , to , text ); // Retry
case 'INVALID_NUMBER' :
console . error ( `Número inválido: ${ to } ` );
return null ;
case 'RATE_LIMIT_EXCEEDED' :
const retryAfter = data . error . details ?. retryAfter || 60 ;
await sleep ( retryAfter * 1000 );
return sendMessage ( instanceId , to , text ); // Retry
default :
throw new Error ( data . error . message );
}
}
return data . data ;
} catch ( error ) {
console . error ( 'Erro ao enviar mensagem:' , error );
throw error ;
}
}
function sleep ( ms ) {
return new Promise ( resolve => setTimeout ( resolve , ms ));
}
Python
import requests
import time
def send_message ( instance_id , to , text ):
try :
response = requests.post(
'https://api.wapizap.com/api/v2/messages' ,
headers = {
'Content-Type' : 'application/json' ,
'Authorization' : f 'Bearer { API_KEY } '
},
json = {
'instanceId' : instance_id,
'to' : to,
'type' : 'text' ,
'text' : text
}
)
data = response.json()
if not data.get( 'success' ):
error_code = data.get( 'error' , {}).get( 'code' )
if error_code == 'INSTANCE_NOT_CONNECTED' :
reconnect_instance(instance_id)
return send_message(instance_id, to, text) # Retry
elif error_code == 'INVALID_NUMBER' :
print ( f 'Número inválido: { to } ' )
return None
elif error_code == 'RATE_LIMIT_EXCEEDED' :
retry_after = data.get( 'error' , {}).get( 'details' , {}).get( 'retryAfter' , 60 )
time.sleep(retry_after)
return send_message(instance_id, to, text) # Retry
else :
raise Exception (data.get( 'error' , {}).get( 'message' ))
return data.get( 'data' )
except Exception as e:
print ( f 'Erro ao enviar mensagem: { e } ' )
raise
Exponential Backoff
Para erros temporários (429, 500, 503), implemente exponential backoff:
async function fetchWithRetry ( url , options , maxRetries = 3 ) {
let lastError ;
for ( let attempt = 0 ; attempt < maxRetries ; attempt ++ ) {
try {
const response = await fetch ( url , options );
const data = await response . json ();
if ( data . success ) {
return data ;
}
// Erros que não devem ser retentados
const nonRetryable = [ 'UNAUTHORIZED' , 'INVALID_NUMBER' , 'NOT_FOUND' ];
if ( nonRetryable . includes ( data . error ?. code )) {
throw new Error ( data . error . message );
}
// Rate limit - usar tempo específico
if ( data . error ?. code === 'RATE_LIMIT_EXCEEDED' ) {
const waitTime = data . error . details ?. retryAfter || 60 ;
await sleep ( waitTime * 1000 );
continue ;
}
lastError = new Error ( data . error ?. message );
} catch ( error ) {
lastError = error ;
}
// Exponential backoff: 1s, 2s, 4s, 8s...
const waitTime = Math . pow ( 2 , attempt ) * 1000 ;
console . log ( `Tentativa ${ attempt + 1 } falhou. Aguardando ${ waitTime } ms...` );
await sleep ( waitTime );
}
throw lastError ;
}
Códigos de Erro por Categoria
Autenticação
Código Descrição UNAUTHORIZEDToken inválido ou ausente TOKEN_EXPIREDToken expirado INSUFFICIENT_PERMISSIONSSem permissão para a ação
Instâncias
Código Descrição INSTANCE_NOT_FOUNDInstância não existe INSTANCE_NOT_CONNECTEDInstância desconectada INSTANCE_ALREADY_EXISTSNome já em uso INSTANCE_LIMIT_EXCEEDEDLimite do plano atingido QR_CODE_EXPIREDQR code expirou
Mensagens
Código Descrição INVALID_NUMBERNúmero não está no WhatsApp MESSAGE_NOT_FOUNDMensagem não encontrada MEDIA_TOO_LARGEArquivo excede limite INVALID_MEDIA_TYPETipo de mídia não suportado MESSAGE_FAILEDFalha ao enviar mensagem
Grupos
Código Descrição GROUP_NOT_FOUNDGrupo não encontrado NOT_GROUP_ADMINAção requer ser admin PARTICIPANT_NOT_FOUNDParticipante não está no grupo ALREADY_GROUP_MEMBERJá é membro do grupo
Rate Limiting
Código Descrição RATE_LIMIT_EXCEEDEDMuitas requisições DAILY_LIMIT_EXCEEDEDLimite diário atingido
Logs e Monitoramento
Estrutura de Log Recomendada
function logApiError ( error , context ) {
console . error ( JSON . stringify ({
timestamp: new Date (). toISOString (),
level: 'error' ,
code: error . code ,
message: error . message ,
context: {
endpoint: context . endpoint ,
instanceId: context . instanceId ,
requestId: context . requestId
},
details: error . details
}));
}
Alertas Recomendados
Configure alertas para:
Taxa de erros > 5% em 5 minutos
Erros INSTANCE_NOT_CONNECTED (reconectar automaticamente)
Rate limits frequentes (ajustar throttling)
Erros 500 (problema no servidor)
Melhores Práticas
Use Códigos de Erro Base sua lógica no error.code, não na mensagem (que pode mudar).
Implemente Retry Use exponential backoff para erros temporários (429, 500, 503).
Valide Antes Valide números com /contacts/check antes de enviar mensagens.
Monitore Erros Registre e monitore erros para identificar padrões.
Próximos Passos
Rate Limits Entenda os limites da API
Troubleshooting Soluções para problemas comuns