Piloterr

Gestión de errores

Comprenda las respuestas de error de la API Piloterr y aprenda a gestionar cada caso correctamente.

Cada solicitud a la API Piloterr devuelve un código de estado HTTP estándar. Esta guía explica qué significa cada código, cuándo se consumen créditos y cómo gestionar los fallos en su integración.

Formato de respuesta

Las respuestas exitosas devuelven un objeto JSON con los datos del endpoint. Las respuestas de error siguen una estructura consistente:

{
  "error": "Human-readable description of what went wrong"
}

Siempre compruebe el código de estado HTTP antes de leer el cuerpo.


Códigos de estado

200 Éxito

Facturado. La solicitud se completó correctamente. Los créditos se deducen de su saldo.

const res = await fetch(url, { headers: { "x-api-key": API_KEY } })

if (res.status === 200) {
  const data = await res.json()
  // process data
}

201 Trabajo creado

Facturado. Se creó y aceptó un trabajo asíncrono. Su saldo se comprueba antes de poner el trabajo en cola, de modo que un trabajo nunca se inicia sin los créditos necesarios para pagarlo.

202 Aceptado (async)

No facturado. La solicitud fue aceptada y puesta en cola para su procesamiento. Use el ID de trabajo devuelto para consultar el resultado: consultar el estado del trabajo es gratuito.

400 Solicitud incorrecta

No facturado. Su solicitud contiene parámetros inválidos o faltantes.

Causas comunes:

  • Falta un parámetro de consulta obligatorio
  • Un valor de parámetro tiene el tipo o formato incorrecto
  • El cuerpo de la solicitud está malformado

Qué hacer: Relea la documentación del endpoint y verifique cada parámetro obligatorio. Registre la URL completa de la solicitud para detectar errores tipográficos.

if (res.status === 400) {
  const { error } = await res.json()
  console.error("Bad request:", error)
  // do not retry, fix the parameters first
}

401 No autorizado

No facturado. Devuelto por problemas de autenticación y limitación de tasa. Compruebe el mensaje de error para distinguirlos.

Su encabezado x-api-key falta o contiene un valor no reconocido.

Corrección: Copie su clave desde su panel de control → Claves API y asegúrese de que el encabezado x-api-key esté presente en cada solicitud.

La clave existe pero ha sido desactivada.

Corrección: Vaya a su panel de control → Claves API y active la clave, o genere una nueva.

La clave ha superado su fecha de expiración.

Corrección: Genere una nueva clave o amplíe la expiración desde su panel de control.

Ha enviado demasiadas solicitudes en un corto período. Los límites del plan se ven como Rate limit exceeded: You've exceeded the … rate limit on your subscription. Las cuotas por clave se ven como Rate limit exceeded for the API key: quota daily (o total / weekly / monthly).

Corrección: Espere y reintente tras una pausa. Si esto ocurre con frecuencia, mejore su plan o aumente las cuotas de la clave. Estos límites devuelven 401, no 429.

if (res.status === 401) {
  const { error } = await res.json()
  if (error.toLowerCase().includes("rate limit")) {
    await new Promise(r => setTimeout(r, 2000))
    // retry
  }
}

402 Payment required

No facturado. La solicitud no se ejecutó. La cadena error indica el motivo:

  • Payment required — la cuota API y los créditos pay-as-you-go no pueden cubrir la llamada
  • You have open invoices: … — una factura impagada bloquea la cuenta
  • Insufficient credits: X required, Y available — un endpoint por filas devolvería más filas de las que puede pagar

Qué hacer:

  1. Compre un pack puntual o mejore su plan desde su panel de control, o liquide las facturas pendientes en Ajustes → Facturas.
  2. O active la Recarga automática para evitar que el saldo se agote de nuevo.

La recarga automática solo se activa cuando su saldo cae por debajo del umbral configurado. Nunca se ejecuta según un calendario fijo ni a una hora específica. Un período de espera de 72 horas integrado también evita múltiples cobros en poco tiempo: una vez que se realiza una recarga, no puede activarse de nuevo durante 72 horas independientemente de cómo evolucione su saldo. Si un cargo falla, la recarga automática se desactiva automáticamente para proteger su cuenta.

No reintente una respuesta 402 inmediatamente. La llamada fallará de nuevo hasta que añada créditos. Configure una alerta para que su equipo sea notificado cuando esto ocurra.

if (res.status === 402) {
  // alert your team or trigger an auto top-up flow
  throw new Error("Insufficient credits. Top up at https://app.piloterr.com")
}

403 Prohibido

No facturado. La solicitud fue rechazada antes de ejecutarse. Las causas habituales son un endpoint que no está disponible en su plan, una cuenta desactivada o una IP bloqueada temporalmente tras repetidos fallos de autenticación.

Qué hacer: Compruebe la ruta del endpoint en la referencia y confirme después que su cuenta está activa en el panel de control. Contacte con el soporte si cree que es un error.

404 No encontrado

Puede ser facturado (específico del endpoint). El recurso no fue encontrado. Consulte la documentación del endpoint para confirmar si esta respuesta es cobrada.

if (res.status === 404) {
  // handle "no result" gracefully, not as a fatal error
  return null
}

500 Error interno del servidor

No facturado. Ocurrió un error inesperado en nuestro lado.

Qué hacer: Reintente con backoff exponencial. Si el problema persiste, contacte con el soporte.

async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const res = await fetch(url, options)

    if (res.status !== 500 || attempt === maxRetries) return res

    const delay = 500 * 2 ** attempt
    console.warn(`500 error, retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`)
    await new Promise(r => setTimeout(r, delay))
  }
}

Gestor de errores completo

Una función única que cubre cada código de estado:

interface ApiResult<T> {
  data: T | null
  error: string | null
  status: number
  billed: boolean
}

async function apiCall<T>(url: string, apiKey: string): Promise<ApiResult<T>> {
  const res = await fetch(url, {
    headers: { "x-api-key": apiKey },
  })

  // 200 and 201 are always billed; 404 billing is endpoint-specific
  const billed = res.status === 200 || res.status === 201

  if (res.status === 200) {
    return { data: await res.json() as T, error: null, status: 200, billed }
  }

  const body = await res.json().catch(() => ({ error: "Unknown error" }))
  const error = body?.error ?? "Unknown error"

  switch (res.status) {
    case 400:
      console.error("[400] Bad request, fix your parameters:", error)
      break
    case 401:
      if (error.toLowerCase().includes("rate limit")) {
        console.warn("[401] Rate limit, back off and retry")
      } else {
        console.error("[401] Auth error, check your API key:", error)
      }
      break
    case 402:
      console.error("[402] No credits remaining. Top up at https://app.piloterr.com")
      break
    case 403:
      console.error("[403] Forbidden, check your key permissions")
      break
    case 404:
      console.warn("[404] Not found, no result for this request")
      break
    case 500:
      console.error("[500] Server error, retry with backoff")
      break
    default:
      console.error(`[${res.status}] Unexpected status:`, error)
  }

  return { data: null, error, status: res.status, billed }
}

Estrategia de reintento

Estado¿Reintentar?Estrategia
400NoCorregir la solicitud primero
401 (límite de tasa)Esperar 2–5 s, luego reintentar
401 (auth)NoCorregir la clave API
402NoAñadir créditos o liquidar facturas primero
403NoVerificar permisos
404NoTratar como resultado vacío
500Backoff exponencial (máx. 3 intentos)

Resumen de facturación

EstadoFacturado
200
201
404Específico del endpoint (consulte la documentación)
Todos los demás códigosNo

Consulte la página Créditos para un desglose completo de costes por endpoint. Para consejos de integración más amplios, consulte Buenas prácticas.

En esta página