CheaperGen

Guías

Errores

Todos los códigos de error y estados HTTP de la API de CheaperGen (400, 401, 402, 404, 409, 429, 502 y 503), con sus causas y cómo gestionar o reintentar cada uno.

La API usa los códigos de estado HTTP habituales: 2xx indica éxito, 4xx que debes modificar la solicitud y 5xx que se produjo un error en nuestro sistema o en un servicio externo. Todas las respuestas de error tienen el mismo formato JSON, así que puedes gestionarlas en un solo lugar.

Formato de error#

400 Bad Request
{
  "error": {
    "code": "invalid_request",
    "message": "\"resolution\" must be one of: 480p, 720p",
    "param": "resolution"
  }
}
  • code: una cadena estable y legible por máquinas. Usa este valor para tomar decisiones en el código, no el mensaje.
  • message: una explicación legible por personas y segura para incluir en los registros. La redacción puede cambiar.
  • param: aparece cuando un campo específico de la solicitud causó el error.

Códigos de error#

HTTPcódigoSignificadoQué hacer¿Reintentar?
400invalid_requestEl cuerpo no es JSON válido, falta un campo obligatorio, un valor está fuera del rango o no está permitido, el cuerpo contiene un parámetro desconocido, una mención del prompt no apunta a nada o un archivo de video o audio de referencia no se puede leer o supera los límites del modelo (duración, tamaño, resolución o frecuencia de fotogramas). param indica el campo que causa el error.Corrige la solicitud. El mensaje indica exactamente qué está mal.Después de corregirlo
401unauthorizedFalta la clave de API, está mal formada o fue revocada.Comprueba el encabezado Authorization: Bearer y que la clave esté activa.Después de corregirlo
402insufficient_balanceTu saldo no alcanza para cubrir el precio de esta generación. No se te cobró nada.Añade créditos o activa la recarga automática en Panel → Facturación. Consulta Facturación.Después de corregirlo
404not_foundEl ID del endpoint, el modelo o la generación no existe, o la generación pertenece a otra cuenta.Comprueba el ID en la lista de modelos.No
409conflictLa solicitud entra en conflicto con el estado del recurso; por lo general, se debe a que se intenta cancelar una generación que ya está en curso o terminó.Consulta la generación para ver su estado actual.No
410model_delistedEl modelo ya no está disponible. No se envió ni cobró nada; puedes seguir consultando las generaciones anteriores.Elige otro modelo en la lista de modelos.No
429rate_limitedSe enviaron demasiadas solicitudes por segundo o tu cola de generaciones en espera está llena.Espera y vuelve a intentarlo. Consulta Límites de solicitudes.Con espera incremental
500internal_errorSe produjo un error de nuestro lado.Vuelve a intentarlo con una espera incremental. Si el problema persiste, contacta con soporte e indica la hora de la solicitud.Con espera incremental
501direct_upload_unavailableLa carga directa con URL prefirmada no está disponible en esta implementación.Vuelve a cargarlo con multipart/form-data. Consulta Cargas.No
502—Un error de red o de una puerta de enlace ocurrió antes de que la solicitud llegara a nuestra API (poco frecuente). Los fallos del modelo en el servicio externo no aparecen como errores HTTP: la generación falla con un motivo de error.Vuelve a intentarlo con una espera incremental. No se te cobró nada.Con espera incremental
503model_unavailableEl modelo no acepta generaciones nuevas temporalmente.Vuelve a intentarlo más tarde o cambia de modelo. Comprueba página de estado.Con espera incremental
503pricing_unavailableNo se pudieron consultar los precios temporalmente, así que no se calculó el precio de la solicitud. No se envió ni se cobró nada.Vuelve a intentar la misma solicitud en unos segundos (la respuesta incluye una cabecera Retry-After), con el mismo Idempotency-Key.Con espera incremental
503fallback_price_declinedLa capacidad habitual no está disponible; ahora solo se ofrece el precio de emergencia (como máximo, el precio oficial) y enviaste allow_fallback_price: false. No se te cobró nada; el mensaje muestra ambos precios.Vuelve a intentarlo más tarde para obtener el precio estándar o envía allow_fallback_price: true (el valor predeterminado) para aceptar el precio de emergencia.Con espera incremental
400max_cost_exceededEl precio, incluido el de emergencia, supera tu max_cost_usd. No se te cobró nada.Reduce la resolución o la duración, o confirma el precio y aumenta max_cost_usd.Después de corregirlo

Errores durante una generación#

Un error HTTP significa que se rechazó la solicitud y no se cobró nada. Es distinto de una generación aceptada que falla más tarde: la llamada a la API se realizó correctamente (incluso POST /run devuelve 202 si una tarea falla de inmediato) y el status de la generación pasa a ser failed, con un objeto error. El importe reservado se reembolsa automáticamente. El mismo objeto aparece en GET /generations, en la carga webhook y en los resultados de las herramientas MCP.

Una generación fallida
{
  "status": "failed",
  "error": {
    "code": "generation_failed",
    "message": "ByteDance's safety review for Seedance 2.0 Fast rejected this request (the prompt or an input file).",
    "reason": "content_blocked",
    "hint": "Describe the character's look instead of naming a copyrighted character or real person, keep it non-explicit, or try another model.",
    "retryable": false,
    "refunded": true,
    "detail": "Tu solicitud no superó la revisión de seguridad del contenido. Ajusta el prompt y vuelve a intentarlo."
  }
}

code es la categoría general (los cuatro valores documentados desde el lanzamiento). reason explica exactamente el motivo; úsalo en el código y muestra message y hint a tus usuarios. retryable indica si se puede volver a enviar la misma solicitud; param especifica qué campo cambiar, si se puede determinar, y detail contiene el texto del proveedor del modelo.

error.reasonerror.codeQué ocurrióQué hacer¿Reenviar sin cambios?
content_blockedgeneration_failedEl filtro de seguridad del proveedor del modelo rechazó el prompt, un archivo de entrada o el resultado generado (por ejemplo, por un personaje con derechos de autor, una persona real o contenido explícito). El mensaje indica de quién era el filtro.Reformula el prompt (describe el aspecto en vez de mencionar a un personaje, una marca o una persona real), usa otros archivos de entrada o prueba un modelo de otro proveedor. Si lo envías sin cambios, volverá a fallar por el mismo motivo.No; primero haz un cambio
invalid_inputgeneration_failedEl modelo no pudo aceptar una de las entradas o los ajustes: un archivo demasiado grande, en un formato no admitido, con dimensiones o relación de aspecto incorrectas, demasiado largo o con un valor no compatible. param indica el campo cuando podemos identificarlo.Corrige el campo indicado (consulta los límites del modelo en su página de API) y vuelve a enviar la solicitud, o prueba otro modelo.No; primero haz un cambio
input_unreachablegeneration_failedNo se pudo descargar una URL de entrada: requiere iniciar sesión, el enlace firmado ha caducado, no apunta directamente al archivo o el servidor de origen rechazó la solicitud. Cuando el proveedor del modelo no puede descargar un archivo, normalmente lo descargamos nosotros y volvemos a intentarlo con nuestra copia; por eso, este mensaje suele significar que no se pudo descargar el archivo en absoluto.Usa una URL pública y directa al archivo (o súbelo con POST /api/v1/uploads) y vuelve a enviar la solicitud.No; primero haz un cambio
upstream_unavailableupstream_errorEl proveedor del modelo estaba caído, sobrecargado o sin capacidad, y probamos todas las rutas disponibles.Vuelve a intentarlo en uno o dos minutos o usa otro modelo.Sí
upstream_errorupstream_errorEl proveedor encontró un error interno durante la generación, después de que probáramos todas las rutas disponibles.Vuelve a intentarlo; estos errores suelen ser temporales. Si sigue fallando, prueba otro modelo.Sí
timeouttimeoutLa generación no terminó a tiempo (por el límite del proveedor o por nuestro límite de 40 minutos).Vuelve a intentarlo. Los clips más cortos o de menor resolución terminan antes.Sí
output_unavailableupstream_errorEl modelo terminó, pero no devolvió ningún archivo utilizable o no se pudo descargar y guardar el resultado.Retry.Sí
model_unavailablemodel_unavailableEl modelo o esta modalidad dejó de estar disponible mientras se procesaba la generación.Elige otro modelo o vuelve a intentarlo más tarde.No; primero haz un cambio
canceledupstream_errorEl proveedor canceló la tarea o hizo que caducara antes de terminar. (Si cancelas tú la generación, su estado es canceled y no se informa de ningún error.)Retry.Sí
generation_failedgeneration_failedEl modelo se detuvo sin generar un resultado ni indicar el motivo.Vuelve a intentarlo una vez; si vuelve a fallar, simplifica el prompt o las entradas, o prueba otro modelo.Sí

Los fallos causados por tu solicitud —content_blocked, un archivo rechazado en invalid_input o input_unreachable— no se reintentan en otros proveedores, porque volverían a rechazarse. Primero se reintentan los cortes del servicio y los errores del proveedor en todas las rutas compatibles, al mismo precio. Consulta Fallos y reembolsos.

Cuando un proveedor indica que no puede descargar uno de tus archivos de entrada, normalmente intentamos descargarlo nosotros. Si podemos, volvemos a intentar el trabajo con una copia alojada por nosotros, al mismo precio y sin que tengas que cambiar nada; la generación sigue mostrando las URL que enviaste y la copia se elimina junto con la generación según su retención. Por eso, input_unreachable suele significar que no se pudo descargar el archivo en absoluto: requiere iniciar sesión, el enlace firmado ha caducado, no apunta directamente al archivo o el servidor de origen rechazó la solicitud. Copiamos imágenes de hasta 30 MB, videos de hasta 200 MB y audio de hasta 50 MB; los archivos más grandes o ilegibles fallan con invalid_input.

Reintentar de forma segura#

Reintenta los errores 429, 500, 502 y 503 con retroceso exponencial y fluctuación aleatoria. No reintentes sin cambios otros errores 4xx; volverán a fallar por el mismo motivo.

Las solicitudes de envío no son idempotentes

Cada envío correcto con POST /run/{endpoint} crea y factura una nueva generación. Si se agota el tiempo de espera de la red al enviar y no sabes si se aceptó, consulta tus generaciones recientes antes de volver a enviarla.

const RETRYABLE = new Set([429, 500, 502, 503]);

export async function postWithRetry(url, headers, body, attempts = 5) {
  let resp;
  for (let attempt = 0; attempt < attempts; attempt++) {
    resp = await fetch(url, { method: "POST", headers, body: JSON.stringify(body) });
    if (!RETRYABLE.has(resp.status)) break;
    // exponential backoff with jitter: ~1s, 2s, 4s, 8s…
    await new Promise((r) => setTimeout(r, Math.min(2 ** attempt, 30) * 1000 + Math.random() * 1000));
  }
  const data = await resp.json();
  if (!resp.ok) throw new Error(`${resp.status} ${data.error.code}: ${data.error.message}`);
  return data;
}

Ejemplos de validación#

Los mensajes de validación indican el campo y los valores permitidos, así que puedes mostrárselos directamente a los desarrolladores:

[
  {
    "error": {
      "code": "invalid_request",
      "message": "\"prompt\" is required",
      "param": "prompt"
    }
  },
  {
    "error": {
      "code": "invalid_request",
      "message": "Unknown parameter \"resoluton\"",
      "param": "resoluton"
    }
  },
  {
    "error": {
      "code": "not_found",
      "message": "Unknown endpoint \"bytedance/seedance-2.0-fast/text-to-gif\". See GET /api/v1/models."
    }
  }
]

También puedes consultar el precio sin ejecutar la solicitud: POST /api/v1/quote/{endpoint} valida los campos que afectan al precio y devuelve el coste. Consulta referencia de la API.

¿Algo no está claro o falta información? Escribe a support@cheapergen.com; leemos todos los mensajes.