BitelioBitelio
Referencia de API

Códigos de error

Todos los códigos de error que puede devolver la API de Bitelio, qué significan y cómo solucionarlos

Resumen

Los errores de la API de Bitelio siguen una forma consistente, diseñada para que puedas identificar el problema rápido. Cada error trae:

  • Un código de error legible por máquina sobre el que tu código puede ramificar
  • Un mensaje legible por humanos que describe el fallo
  • Una sugerencia que apunta a la solución probable
  • Un ID de solicitud para depuración y conversaciones de soporte
  • Detalles de validación a nivel de campo cuando aplican

Códigos de estado HTTP

200 OK

La solicitud se procesó correctamente.

201 Created

El recurso fue creado.

400 Bad Request

Algo está mal en el formato de la solicitud o en sus parámetros — los detalles del error indican qué.

401 Unauthorized

Falta la autenticación o no tuvo éxito. Verifica tu clave de API.

402 Payment Required

Se alcanzó un límite de facturación, o la operación requiere un plan superior. Acompaña a BILLING_LIMIT_EXCEEDED y UPGRADE_REQUIRED.

403 Forbidden

No tienes permitido tocar este recurso — revisa los permisos y el estado del proyecto. También se usa cuando aún falta verificar el correo de la cuenta (EMAIL_VERIFICATION_REQUIRED) o el proyecto fue deshabilitado (PROJECT_DISABLED).

404 Not Found

No existe ningún recurso con ese ID. Confirma que el ID sea correcto.

409 Conflict

La solicitud choca con el estado existente — p. ej., crear un contacto cuyo correo ya está registrado, o renombrarlo a un correo que ya está en uso. Acompaña a CONFLICT.

422 Unprocessable Entity

La validación rechazó la solicitud. El array errors enumera los campos problemáticos.

429 Too Many Requests

Superaste un límite de tasa. Espera antes de reintentar, o pasa a un plan superior.

500 Internal Server Error

Algo se rompió de nuestro lado. Contacta a soporte con el ID de la solicitud.

Formato de respuesta de error

Todos los errores usan esta única estructura:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "statusCode": 422,
    "requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "errors": [
      {
        "field": "email",
        "message": "Invalid email",
        "code": "invalid_string"
      }
    ],
    "suggestion": "One or more fields have incorrect types. Check that strings are quoted, numbers are unquoted, and booleans are true/false."
  },
  "timestamp": "2025-11-30T10:30:00.000Z"
}

Campos de la respuesta

CampoTipoDescripción
successbooleanEn errores siempre es false
error.codestringIdentificador legible por máquina (catalogado abajo)
error.messagestringExplicación en lenguaje llano de lo que falló
error.statusCodenumberEl estado HTTP
error.requestIdstringIdentificador por solicitud para depuración
error.errorsarrayDesglose por campo (solo fallos de validación)
error.detailsobjectContexto adicional, cuando está disponible (opcional)
error.suggestionstringUna pista hacia la solución (opcional)
timestampstringCuándo ocurrió el error, en ISO 8601

Referencia de códigos de error

El campo code está presente en todos los errores para que puedas manejarlos programáticamente. El conjunto completo:

Autenticación y autorización

CódigoEstadoDescripción
UNAUTHORIZED401Falló la autenticación por un motivo no especificado
INVALID_CREDENTIALS401Los datos de inicio de sesión no coinciden
MISSING_AUTH401No hay un encabezado Authorization utilizable en la solicitud
INVALID_API_KEY401Esa clave de API no existe o no es válida
REVOKED_API_KEY401Esa clave era válida y se ha revocado: emite una nueva
EXPIRED_API_KEY401Esa clave pasó su fecha de expiración: emite una nueva
FORBIDDEN403Esta acción no está permitida
PROJECT_ACCESS_DENIED403No tienes acceso a este proyecto
PROJECT_DISABLED403El proyecto está actualmente deshabilitado
EMAIL_VERIFICATION_REQUIRED403Verifica la dirección de correo de la cuenta antes de hacer esto

Errores de validación y de entrada

CódigoEstadoDescripción
BAD_REQUEST400Problema genérico con la solicitud
VALIDATION_ERROR422La validación rechazó la solicitud (con errores de campo adjuntos)
INVALID_EMAIL422La dirección de correo no tiene un formato válido
INVALID_REQUEST_BODY400El cuerpo no se pudo interpretar
MISSING_REQUIRED_FIELD422No se proporcionó un campo obligatorio

Errores de recursos

CódigoEstadoDescripción
RESOURCE_NOT_FOUND404Ningún recurso coincide (genérico)
CONTACT_NOT_FOUND404No existe ese contacto
TEMPLATE_NOT_FOUND404No existe esa plantilla
CAMPAIGN_NOT_FOUND404No existe esa campaña
WORKFLOW_NOT_FOUND404No existe ese workflow
CONFLICT409Choca con el estado existente (p. ej., un duplicado)

Límites de tasa y facturación

CódigoEstadoDescripción
RATE_LIMIT_EXCEEDED429La tasa de solicitudes es demasiado alta
BILLING_LIMIT_EXCEEDED402Se alcanzó un límite de facturación
UPGRADE_REQUIRED402La función requiere un plan superior

Errores de servidor

CódigoEstadoDescripción
INTERNAL_SERVER_ERROR500Fallo inesperado de nuestro lado
DATABASE_ERROR500Una operación de base de datos no se completó
EXTERNAL_SERVICE_ERROR500Un servicio externo no estuvo disponible

Ejemplos comunes de error

Errores de autenticación

Clave de API inválida

{
  "success": false,
  "error": {
    "code": "INVALID_API_KEY",
    "message": "Invalid secret API key. This endpoint requires a secret key (sk_*), not a public key.",
    "statusCode": 401,
    "requestId": "abc-123",
    "suggestion": "Verify your API key is correct and starts with \"sk_\" for secret keys or \"pk_\" for public keys."
  },
  "timestamp": "2025-11-30T10:30:00.000Z"
}

Solución: Confirma la clave en sí y su tipo — los endpoints que requieren una clave secreta esperan un prefijo sk_, mientras que el registro de eventos usa claves pk_.

Falta el encabezado Authorization

{
  "success": false,
  "error": {
    "code": "MISSING_AUTH",
    "message": "Authorization header is required",
    "statusCode": 401,
    "requestId": "abc-123",
    "suggestion": "Include an Authorization header with format: \"Authorization: Bearer YOUR_API_KEY\""
  },
  "timestamp": "2025-11-30T10:30:00.000Z"
}

Solución: Envía tu clave como token Bearer en el encabezado Authorization.

Errores de validación

Formato de correo inválido

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "statusCode": 422,
    "requestId": "abc-123",
    "errors": [
      {
        "field": "email",
        "message": "Invalid email",
        "code": "invalid_string"
      }
    ],
    "suggestion": "One or more fields have incorrect types. Check that strings are quoted, numbers are unquoted, and booleans are true/false."
  },
  "timestamp": "2025-11-30T10:30:00.000Z"
}

Solución: Envía una dirección de correo bien formada. Revisa el array errors para ver exactamente qué campos fueron rechazados.

Faltan campos obligatorios

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "statusCode": 422,
    "requestId": "abc-123",
    "errors": [
      {
        "field": "event",
        "message": "Required",
        "code": "invalid_type"
      },
      {
        "field": "email",
        "message": "Required",
        "code": "invalid_type"
      }
    ],
    "suggestion": "Required fields are missing. Ensure all required fields are included in your request."
  },
  "timestamp": "2025-11-30T10:30:00.000Z"
}

Solución: Añade todos los campos obligatorios al cuerpo de la solicitud.

Errores de recursos

Plantilla no encontrada

{
  "success": false,
  "error": {
    "code": "TEMPLATE_NOT_FOUND",
    "message": "Template with ID \"tpl_abc123\" was not found",
    "statusCode": 404,
    "requestId": "abc-123",
    "details": {
      "resource": "Template",
      "id": "tpl_abc123"
    },
    "suggestion": "Ensure the template ID is correct and belongs to your project. You can list available templates via the API."
  },
  "timestamp": "2025-11-30T10:30:00.000Z"
}

Solución: Asegúrate de que el ID de la plantilla exista y pertenezca a tu proyecto.

Límite de tasa

Límite de tasa superado

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Please try again later.",
    "statusCode": 429,
    "requestId": "abc-123",
    "suggestion": "You have exceeded the rate limit. Wait a moment before retrying, or upgrade your plan."
  },
  "timestamp": "2025-11-30T10:30:00.000Z"
}

Solución: Añade lógica de reintento con backoff exponencial. Si sueles chocar con el techo, un cambio de plan lo eleva.

Formato de respuesta de éxito

Cuando una solicitud tiene éxito, la respuesta llega como success: true con un objeto data:

{
  "success": true,
  "data": {
    "contact": "cnt_abc123",
    "event": "evt_xyz789",
    "timestamp": "2025-11-30T10:30:00.000Z"
  }
}

Campos de la respuesta

CampoTipoDescripción
successbooleanEn éxito siempre es true
dataobjectPayload específico del endpoint

Manejo de errores en tu código

Ejemplo en JavaScript/TypeScript

try {
  const response = await fetch('https://api.bitelio.com/v1/track', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${publicKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      event: 'purchase',
      email: 'user@example.com'
    })
  });

  const data = await response.json();

  if (!data.success) {
    // Algo salió mal
    console.error(`Error [${data.error.code}]:`, data.error.message);

    // Muestra la solución sugerida por la API
    if (data.error.suggestion) {
      console.log('Suggestion:', data.error.suggestion);
    }

    // Conserva el ID de la solicitud para soporte
    console.log('Request ID:', data.error.requestId);

    // Ramifica según el código específico
    switch (data.error.code) {
      case 'VALIDATION_ERROR':
        // Imprime cada campo que falló
        data.error.errors?.forEach(err => {
          console.log(`${err.field}: ${err.message}`);
        });
        break;
      case 'INVALID_API_KEY':
        // Pide al usuario que revise su clave
        break;
      case 'REVOKED_API_KEY':
      case 'EXPIRED_API_KEY':
        // La clave ERA válida: rótala, en vez de pedir que busquen una errata
        break;
      case 'RATE_LIMIT_EXCEEDED':
        // Reintenta más tarde con backoff
        break;
    }

    return;
  }

  // Camino de éxito
  console.log('Event tracked:', data.data);
} catch (error) {
  console.error('Network error:', error);
}

Ejemplo en Python

import requests

response = requests.post(
    'https://api.bitelio.com/v1/track',
    headers={
        'Authorization': f'Bearer {public_key}',
        'Content-Type': 'application/json'
    },
    json={
        'event': 'purchase',
        'email': 'user@example.com'
    }
)

data = response.json()

if not data.get('success'):
    error = data['error']
    print(f"Error [{error['code']}]: {error['message']}")

    # Muestra la solución sugerida
    if 'suggestion' in error:
        print(f"Suggestion: {error['suggestion']}")

    # Conserva el ID de la solicitud
    print(f"Request ID: {error['requestId']}")

    # Imprime los fallos a nivel de campo
    if error['code'] == 'VALIDATION_ERROR':
        for err in error.get('errors', []):
            print(f"{err['field']}: {err['message']}")
else:
    print(f"Event tracked: {data['data']}")

Guía de resolución de problemas

Uso de los IDs de solicitud

Cada error viene con un requestId que sigue la solicitud a través de todo nuestro stack. Eso lo hace valioso en dos frentes:

Para desarrolladores:

  • El ID queda grabado en cada línea de log de esa solicitud
  • Busca por ID en tus logs y aparece de golpe cada entrada relacionada
  • Sigue una solicitud a través de API → Base de datos → Cola → Worker

Para soporte:

  1. Pega el ID de la solicitud en tu mensaje
  2. Explica qué estabas intentando hacer
  3. Adjunta la respuesta de error completa cuando puedas

Ejemplo: Dado el ID de solicitud f47ac10b-58cc-4372-a567-0e02b2c3d479, una búsqueda en los logs de nuestro lado revela:

  • El cuerpo de la solicitud tal como llegó
  • Las consultas de base de datos que se ejecutaron
  • Cualquier job en segundo plano que haya generado
  • El stack trace completo, si existe alguno

Eso significa que normalmente podemos diagnosticar el problema de inmediato, sin ida y vuelta pidiéndote más detalles.

Cómo encontrar los IDs de solicitud

El ID de solicitud aparece en tres lugares:

  • Respuestas de error: el campo error.requestId
  • Encabezados de respuesta: el encabezado X-Request-ID (presente también en éxitos)
  • Los logs de tu aplicación: escribe el encabezado en tus propios logs para poder correlacionar
// Captura el ID de la solicitud en tu propio logging
const response = await fetch('https://api.bitelio.com/v1/send', {
  // ... tu solicitud
});

const requestId = response.headers.get('X-Request-ID');
console.log('Request ID:', requestId);  // Guárdalo para correlación

const data = await response.json();
if (!data.success) {
  console.error('Error:', data.error.message);
  console.error('Request ID:', data.error.requestId);  // Coincide con el encabezado
}

Problemas comunes y soluciones

Buenas prácticas

  1. Revisa success primero, antes de tocar el resto de la respuesta
  2. Registra los IDs de solicitud para que la depuración y las solicitudes de soporte vayan más rápido
  3. Falla con elegancia, traduciendo los errores en mensajes que tus usuarios entiendan
  4. Reintenta los fallos transitorios usando backoff exponencial
  5. Vigila tus tasas de error para que los problemas salgan a la luz temprano
  6. Ramifica según los códigos de error, no solo según los estados HTTP, en tu manejo

Obtener ayuda

¿Sigues atascado? Recorre esta lista:

  1. Empieza por el campo suggestion del propio error
  2. Compara tu solicitud contra la Referencia de la API
  3. Busca tu código de error exacto en esta documentación
  4. Escribe a soporte e incluye tu ID de solicitud
  5. Pregunta a la comunidad — otros desarrolladores a menudo se han topado con lo mismo