Venflow API

Errores

Errores

Cuando algo sale mal, la API responde con un código HTTP de error y siempre con el mismo cuerpo JSON.

Cuerpo de cualquier error
{
  "code": "not_found",
  "message": "Subscription not found: 550e8400-e29b-41d4-a716-446655440000",
  "details": null
}
CampoTipoPara qué sirve
codestringEs el campo sobre el que debes ramificar. Identificador estable del tipo de error.
messagestringTexto en inglés pensado para que un humano depure. Puede cambiar de redacción sin aviso — no lo compares contra una cadena fija.
detailsobject | nullInformación adicional cuando existe. Hoy es null en la práctica totalidad de los errores.

Ramifica por code, nunca por message ni por el código HTTP. El code es parte del contrato; el mensaje es prosa de diagnóstico que reescribimos cuando mejora la explicación, y un mismo código HTTP puede llegar con distintos code.

Códigos de error

HTTPcodeQué pasóQué hacer
400invalid_argumentEl cuerpo o un parámetro no cumple el contrato: falta un campo obligatorio, un valor está fuera de rango, o mandaste una propiedad que el endpoint no acepta.Corrige la solicitud. Reintentarla igual vuelve a fallar.
401unauthenticatedFalta el header Api-Key, la clave no existe, está revocada, o no corresponde a la organización del header Organization.Revisa ambos headers. Consulta Autenticación.
403permission_deniedLa clave es válida pero no tiene permiso sobre ese recurso.No se resuelve reintentando. Las claves API no ejecutan acciones reservadas a administradores.
404not_foundNo existe un recurso con ese ID dentro de tu organización.Verifica el ID. Ver la nota de abajo.
409already_existsYa existe un recurso con ese identificador único (por ejemplo, un plan con el mismo nombre).Usa otro valor, o actualiza el recurso existente.
4xxfailed_preconditionLa solicitud es válida, pero el recurso no está en el estado que la operación necesita (por ejemplo, reactivar una suscripción que ya dejó de estar cancelada).Vuelve a consultar el recurso y decide con su estado actual.
4xxabortedEl recurso cambió mientras se procesaba tu solicitud, y se descartó para no pisar ese cambio. Ocurre si dos peticiones tocan la misma suscripción a la vez.Vuelve a leer el recurso y reintenta con datos frescos.
500internalError inesperado de nuestro lado.Se puede reintentar. Si persiste, es un incidente nuestro.

Las dos filas marcadas 4xx no llevan número por honestidad: son códigos que la API sí devuelve, pero el número HTTP exacto con el que viajan no está confirmado de nuestro lado, y preferimos no publicar una cifra que nadie verificó. Es justo el motivo de la advertencia de arriba: el campo code es la parte estable del contrato, el número no.

Un ID con formato inválido también responde 404, no 400. Y un ID que existe pero pertenece a otra organización responde 404 igual que uno que no existe. Es deliberado: la API nunca revela si un ID ajeno existe.

Límite de peticiones

Los endpoints /v1 no tienen límite de peticiones: no vas a recibir un 429. No hace falta que implementes espera con reintentos por ese motivo.

Ejemplo de manejo

const response = await fetch('https://api.venflow.app/v1/subscriptions/' + id, {
  headers: {
    'Api-Key': process.env.VENFLOW_API_KEY,
    'Organization': process.env.VENFLOW_ORG_ID,
  },
});

if (!response.ok) {
  const error = await response.json();

  switch (error.code) {
    case 'not_found':
      // El ID no existe en tu organización. No reintentar.
      return null;
    case 'unauthenticated':
    case 'permission_denied':
      // Problema de credenciales. No reintentar.
      throw new Error(`Credenciales de Venflow: ${error.message}`);
    case 'internal':
      // Nuestro lado falló. Este sí vale la pena reintentar.
      throw new RetryableError(error.message);
    default:
      throw new Error(`Venflow ${error.code}: ${error.message}`);
  }
}

Qué errores puede dar cada endpoint

Cada página de la Referencia API lista los códigos concretos de ese endpoint, con la razón específica por la que los devuelve. Los cuatro de arriba (unauthenticated, permission_denied, internal y, cuando el endpoint recibe un ID, not_found) los puede dar cualquier endpoint.