Skip to main content

Formato de error

Todos los errores devuelven la misma estructura:
{
  "error": {
    "code": "ERROR_CODE",
    "message": "Descripción legible del error.",
    "status": 400,
    "details": {}
  },
  "meta": {
    "requestId": "550e8400-e29b-41d4-a716-446655440000"
  }
}
  • code: Código de error constante. Usalo para lógica programática.
  • message: Descripción para humanos. Puede cambiar, no lo uses para comparar.
  • status: Status HTTP.
  • details: Información adicional (opcional). En errores de validación, incluye los campos con problemas.
  • requestId: Identificador único de la request. Incluilo si necesitás soporte.

Códigos de error

Validación (400)

CódigoDescripción
VALIDATION_ERRORRequest con datos inválidos. details incluye los campos.
MISSING_REQUIRED_FIELDFalta un campo obligatorio en el body.
INVALID_PHONENúmero de teléfono con formato inválido.
INVALID_CHANNELEl canal (número) no existe o no está conectado.
INVALID_MESSAGE_TYPETipo de mensaje no soportado.
INVALID_CURSORCursor de paginación inválido o expirado.
INVALID_FILTERParámetro de filtro no válido.

Autenticación y permisos (401/403)

CódigoDescripción
INVALID_API_KEYAPI key inválida, expirada o revocada.
INSUFFICIENT_SCOPELa API key no tiene el scope necesario.
CHANNEL_NOT_CONNECTEDEl canal no está conectado o verificado.
SERVICE_WINDOW_EXPIREDLa ventana de 24hs expiró. Solo podés enviar templates.

Recursos (404)

CódigoDescripción
CONTACT_NOT_FOUNDEl contacto no existe.
CONVERSATION_NOT_FOUNDLa conversación no existe.
MESSAGE_NOT_FOUNDEl mensaje no existe.
TEMPLATE_NOT_FOUNDEl template no existe o no está aprobado.

Conflictos (409)

CódigoDescripción
CONTACT_ALREADY_EXISTSYa existe un contacto con ese número de teléfono.
IDEMPOTENCY_CONFLICTOtra request con la misma Idempotency-Key está en proceso.

Límites (429)

CódigoDescripción
RATE_LIMITEDSuperaste el límite de requests. Ver header Retry-After.

Servidor (500)

CódigoDescripción
INTERNAL_ERRORError interno del servidor. Si persiste, contactá soporte con el requestId.

Cómo manejar errores

const res = await fetch('https://api.waspytech.com/api/v2/messages', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer wspy_...',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ ... })
});

if (!res.ok) {
  const { error, meta } = await res.json();

  switch (error.code) {
    case 'RATE_LIMITED':
      // Esperar y reintentar
      break;
    case 'SERVICE_WINDOW_EXPIRED':
      // Enviar un template en vez de texto libre
      break;
    case 'CONTACT_ALREADY_EXISTS':
      // El contacto ya existe, usar el existente
      break;
    default:
      console.error(`Error ${error.code}: ${error.message} (${meta.requestId})`);
  }
}

Errores retryable

Código¿Reintentar?
RATE_LIMITEDSí, después de Retry-After segundos
IDEMPOTENCY_CONFLICTSí, después de unos segundos
INTERNAL_ERRORSí, con backoff exponencial
Todos los demásNo, la request es incorrecta