Saltar al contenido principal
Una llamada puede fallar en dos momentos. La solicitud puede rechazarse de inmediato con un error HTTP, o puede aceptarse y terminar más tarde con status: "failed". Los jobs fallidos y cancelados no se facturan. Solo pagas por los jobs completados. En una node app, el job propio de la app nunca se factura. Cada nodo de generación o de LLM se cobra cuando se completa su propio job. Un fallo no cancela los nodos paralelos ni otras ramas, por lo que un nodo que se completa después de que la app ya haya fallado también se cobra, y esos cargos no se reembolsan. Un nodo que falla, se cancela o nunca empieza no se cobra. Consulta Claves de API y facturación.

Errores en la solicitud y jobs fallidos

Los errores en la solicitud devuelven un estado 4xx o 5xx. No se crea ningún job. Lee el cuerpo como se describe a continuación. Los jobs fallidos devuelven un estado de éxito al enviarse. Consulta GET /jobs/{id} o espera un webhook. Cuando el job termina, status es "failed" y el fallo es el objeto error de nivel superior. No leas result en un job fallido: se omite (o es null). Solo contiene la salida cuando status es "completed". Un job cancelled no tiene ni result ni error. Ramifica según error.code. message puede omitirse y, para provider_error e internal, es texto libre del proveedor. No analices message.

Cuerpos de respuesta

En generate, jobs, assets, styles y node apps, lee message ?? error cuando el cuerpo sea JSON. Uno de esos dos campos contiene el resumen. Algunos cuerpos 5xx no son JSON, incluido un 502 cuyo cuerpo es el texto plano error code: 502. Analiza de forma defensiva: si el cuerpo no es JSON, ramifica según el estado HTTP. La mayoría de los fallos usan { "message": "..." }, a veces con campos adicionales (limit, jobType, modelAccessDenial). El JSON inválido y algunos handlers que se indican más abajo usan { "error": "..." } en su lugar. Los endpoints MCP como /mcp devuelven errores JSON-RPC, { "jsonrpc", "id", "error": { "code", "message" } }, no los cuerpos HTTP de esta página.

Envía Accept: application/json

Sin Accept: application/json, algunos errores llegan como una página HTML y un parser de JSON fallará.
Los errores { "message" }, incluidos 401 y 404, son JSON cuando Accept es application/json o */*. Cuando falta Accept, o es text/html, esos estados son una página HTML (Content-Type: text/html) y un parser de JSON fallará. Esto es importante para los clientes que no envían el encabezado Accept. urllib de Python es uno de ellos. curl envía Accept: */* de forma predeterminada, y fetch de Node también, por lo que ambos reciben JSON a menos que sobrescribas Accept. Las solicitudes sin autenticar a POST /generate/..., GET /jobs/{id}, GET /styles y GET /assets devuelven 401 {"message":"Unauthorized"} para */* y application/json, y una página HTML cuando falta Accept o es text/html. Una solicitud autenticada a GET /jobs/{id} con un id desconocido hace lo mismo con el estado: 404 JSON {"message":"Job not found or unauthorized"} cuando Accept pide JSON, y 404 text/html cuando falta Accept. El JSON inválido (400) y la validación (422) usan { "error" } y siguen siendo JSON incluso cuando falta Accept. Lo mismo ocurre con el 422 de campo eliminado, el 410 de retiro, el 402 de Zero Data Retention, las respuestas { "error" } de node apps y los errores mapeados de la API de operaciones de Agent. Los 402 y 429 al admitir un job de POST /generate/... también son JSON, incluso con un Accept de navegador. 413 y 500 usan { "message" } y siguen a Accept, como 401 y 404.

Validación (422)

details enumera todos los problemas. field es la ruta unida con . ("image_style_references.0.url"). Los errores a nivel de objeto usan una cadena vacía, como con la clave desconocida de arriba. Varias claves desconocidas producen Unrecognized keys: ... y el mismo field vacío. expected solo se añade cuando code es "invalid_type". Un encabezado X-Webhook-URL inválido usa este mismo 422. GET /jobs con parámetros de consulta inválidos también devuelve este 422. No es un 400. Una comprobación de entrada de Zero Data Retention que falla dentro de la herramienta devuelve 422 con la explicación en message (el formato { "message" }, así que Accept importa). Consulta Zero Data Retention.

Campos eliminados y obsoletos (422)

El campo eliminado batchSize / batch_size usa un 422 distinto. No hay arreglo details:
batch_size se elimina de la misma manera. field es el nombre que hayas enviado. Un alias de campo obsoleto usa reason "deprecated_field" o "conflicting_fields", además de replacement, sunset_date y migration_url cuando corresponda. Ramifica según error y reason. La frase para mostrar a una persona es message.

Modelos retirados (410)

Un modelo que ha superado su fecha de retiro devuelve 410 con Deprecation: true y un encabezado Sunset (una fecha RFC 1123):
error es el valor estable "model_unavailable". replacement y migration_url se omiten cuando no hay un reemplazo recomendado. Reintentar con el mismo modelo seguirá devolviendo 410. Cambia a replacement cuando esté definido y consulta Deprecaciones. Un modelo obsoleto pero todavía activo envía Deprecation y Sunset en cada respuesta, incluidos los errores. Usar un alias de campo obsoleto hace lo mismo, incluso en su propio 422. Cuando existe una guía de migración, también se envía un encabezado Link: <migration_url>; rel="deprecation".

Códigos de estado

400

El JSON inválido en generate siempre es JSON, sin necesidad del encabezado Accept:
La ejecución de node apps usa { "error" } para una URL de entrada que no puede usar: Invalid URL for input "<key>" o Failed to download URL for <key>: …. El mensaje de descarga también cubre fallos temporales, así que, a diferencia de generate (consulta Descargas de entradas), un fallo de descarga en una node app siempre es 400. Reinténtalo una vez si la URL es válida. El JSON inválido en POST /node-apps/{id}/execute no es el 400 de generate descrito arriba. Se convierte en un 500 { "message": "Internal Error" }, sin texto de la excepción, y sigue a Accept. Otras respuestas 400 en assets y node apps son { "message": "..." } con una explicación breve, por ejemplo No file provided en una subida prefirmada o Invalid pagination parameters en las versiones de una node app. Una subida de asset fallida transmite el estado del servicio de subida (400, 401, 404 o 500) y puede incluir el texto de su respuesta en message. Ese texto a veces es una cadena JSON. Los parámetros de consulta inválidos en GET /jobs son 422, no 400.

401

Generate, jobs, assets, styles y node apps:
Las subidas prefirmadas devuelven { "message": "Presigned upload URL expired" } o { "message": "Invalid presigned upload URL" }.

402 Pago requerido

Para un cliente facturado por API (una clave de API, o MCP con una clave de API) cuyo saldo de API no cubre el job:
Recarga en krea.ai/app/api/ ↗. Los jobs en curso terminan. Consulta Claves de API y facturación. Otros valores de message para 402 en la API pública: Una llamada a generate con Zero Data Retention en un workspace que no lo tiene habilitado devuelve este cuerpo, siempre en JSON:
La API de operaciones de Agent usa sus propios cuerpos 402. Estos se descuentan del saldo de cómputo del workspace, no del saldo de API.

403

404

Todos los 404 son { "message" }, por ejemplo, para un id de job desconocido:
Si falta el encabezado Accept, estas respuestas son HTML, excepto Endpoint not found para un modelo que tu clave o plan no puede usar, que siempre es JSON. Una solicitud autenticada a GET /jobs/{id} con un id desconocido y sin Accept es 404 text/html. Una operación de Agent desconocida también es 404 { "message": "Endpoint not found" }, no el formato { "error", "code" } de Agent.

405

El cuerpo es texto plano sin encabezado Content-Type, no JSON, incluso cuando Accept es application/json. El texto es el método seguido de method not allowed, por ejemplo GET method not allowed. Un encabezado Allow enumera los métodos que acepta la ruta.

413 Carga demasiado grande

Un cuerpo de solicitud demasiado grande se rechaza con 413. Desde la propia API, el cuerpo sigue a Accept:
Un cuerpo muy grande puede rechazarse antes de llegar a la API, con una página HTML de 413. No envíes archivos en línea. Sube el archivo con POST /assets y pasa la URL devuelta en la solicitud de generate.

Descargas de entradas

Un host que devuelve 404 o 410 es un 422 permanente. El cuerpo es JSON y Accept importa:
Un 410 del host usa la misma frase con 410. Otros rechazos permanentes usan Input file rejected: …. Un fallo de descarga que se puede reintentar es 502 o 504. Ramifica según el código de estado, no según el cuerpo, y reintenta. Un 502 que se repite constantemente para la misma URL probablemente significa que la URL está bloqueada o rota. Cambia la URL. Los fallos de conversión en la exportación 3D también son 502. Esa ruta no se probó en vivo, por lo que el cuerpo también puede llegar como texto plano de Cloudflare error code: 502. Ramifica según el código de estado y reintenta. Un 502 que se repite constantemente para la misma URL de modelo probablemente significa que la URL está bloqueada o rota.

429 de concurrencia

Cuando el job no puede pasar al backlog, una solicitud que supera el límite de concurrencia puede rechazarse con 429 y Content-Type: application/json:
limit es tu límite de concurrencia para este tipo de job. Se cuenta por usuario, no por workspace. Es aproximado: una ráfaga breve puede aceptarse por encima de él, así que no cuentes con que la solicitud limit + 1 sea la que falle. jobType es una categoría interna de job, no la ruta pública del modelo. No ramifiques según él. Krea 2 también puede devolver solo { "message": "CONCURRENCY_LIMIT_REACHED" }, sin limit ni jobType, cuando su cola compartida está llena. Ese no es tu límite. Espera y reintenta. El backlog solo está activo cuando el plan lo incluye (Pro y superiores), el modelo lo admite y la solicitud no es de Zero Data Retention. Actualmente, las solicitudes de Krea 2 no pasan al backlog en ningún plan, por lo que devuelven 429 al superar el límite. Cuando está activo, el job adicional se acepta con status: "backlogged" y comienza en cuanto queda un espacio libre. No hay un límite de backlog independiente. Consulta Límites de tasa. La API no envía Retry-After ni X-RateLimit-*. La respuesta sí incluye cf-ray. Ante un 429, reintenta con retroceso exponencial después de que terminen los jobs en curso (consulta GET /jobs/{id} o usa un webhook). Si una finalización posterior agota el saldo, los jobs que siguen en el backlog fallan con error.code "insufficient_balance". Es un job fallido, no un 402 HTTP. Esos jobs no envían webhook, así que consulta GET /jobs/{id} para los jobs en backlog.

API de operaciones de Agent

POST /agent/{operation} y GET /agent/session/{sessionId} devuelven { "error", "code"?, "allowedModels"? }. Solo error es obligatorio. allowedModels está en camelCase. Un turno que falla después de haber sido aceptado aparece como status: "failed" en la sesión, no como uno de estos errores HTTP. Consulta Agent. Un código de error de Agent no reconocido sigue siendo 422 con { "error", "code" }. El 404 de operación desconocida y un 500 no controlado usan { "message" } y siguen a Accept.

error.code de jobs fallidos

GET /jobs y GET /jobs/{id} incluyen error solo cuando status es "failed". No hay un result utilizable:
Ramifica según error.code. Nunca analices message.message puede omitirse. Los mensajes de provider_error e internal son texto libre, y un mensaje internal puede ser texto sin procesar del proveedor, como failed to download media from the provided URL. Trata cualquier code que no reconozcas como internal.
Las entregas de webhook de un job fallido usan el mismo objeto de job, incluido error. Una entrega de cancelación no tiene error. Un payload de más de 256 KiB no se envía, y no se realizan más entregas para ese job, así que consulta GET /jobs/{id} en su lugar. Verifica la firma antes de confiar en el cuerpo. Consulta Webhooks.

Depuración

No hay un encabezado de id de solicitud de Krea. Todas las respuestas sí incluyen el encabezado cf-ray de Cloudflare. No se envía ningún encabezado Retry-After ni X-RateLimit-*. Cuando escribas a support@krea.ai, incluye:
  • El job_id, cuando la llamada creó o hizo referencia a un job
  • La hora y el endpoint
  • Para un error en la solicitud, el valor de cf-ray
Access-Control-Allow-Origin es *. En generate, jobs, assets, styles y node apps, Access-Control-Expose-Headers no está definido, por lo que fetch en el navegador no puede leer cf-ray, Deprecation ni Sunset. Copia cf-ray desde el registro de red o desde un cliente del lado del servidor. En cualquier respuesta, revisa Deprecation y Sunset antes de que el modelo deje de aceptar llamadas. Consulta Deprecaciones.

Próximos pasos

Ciclo de vida de un job

Consulta el estado hasta que el job se complete, falle o se cancele

Webhooks

Verifica la firma en la entrega de un job fallido

Límites de tasa

Cuándo los jobs adicionales pasan al backlog y cuándo devuelven 429

Claves de API y facturación

Recarga el saldo de API después de un 402