Pular para o conteúdo principal
Uma chamada pode falhar em dois momentos. A requisição pode ser rejeitada imediatamente com um erro HTTP, ou pode ser aceita e depois terminar com status: "failed". Jobs que falham ou são cancelados não são cobrados. Você paga apenas pelos jobs concluídos. Em um node app, o job do próprio app nunca é cobrado. Cada nó de geração ou de LLM é cobrado quando o seu próprio job é concluído. Uma falha não cancela nós paralelos nem outras ramificações, então um nó concluído depois que o app já falhou também é cobrado, e essas cobranças não são reembolsadas. Um nó que falha, é cancelado ou nunca começa não é cobrado. Veja API Keys & Billing.

Erros no momento da requisição e jobs com falha

Erros no momento da requisição retornam um status 4xx ou 5xx. Nenhum job é criado. Leia o corpo conforme descrito abaixo. Jobs com falha retornam um status de sucesso no envio. Faça polling em GET /jobs/{id} ou aguarde um webhook. Quando o job termina, status é "failed" e a falha fica no objeto error de nível superior. Não leia result em um job com falha: ele é omitido (ou null). Ele só contém a saída quando status é "completed". Um job cancelled não tem nem result nem error. Use error.code para decidir o que fazer. message pode ser omitido e, para provider_error e internal, é um texto livre do provedor. Não faça parsing de message.

Corpos de resposta

Em generate, jobs, assets, styles e node apps, leia message ?? error quando o corpo for JSON. Um desses dois campos traz o resumo. Alguns corpos 5xx não são JSON, incluindo um 502 cujo corpo é o texto simples error code: 502. Faça o parsing de forma defensiva: se o corpo não for JSON, decida com base no status HTTP. A maioria das falhas usa { "message": "..." }, às vezes com campos extras (limit, jobType, modelAccessDenial). JSON inválido e alguns handlers abaixo usam { "error": "..." } em vez disso. Endpoints MCP como /mcp retornam erros JSON-RPC, { "jsonrpc", "id", "error": { "code", "message" } }, e não os corpos HTTP desta página.

Envie Accept: application/json

Sem Accept: application/json, alguns erros voltam como uma página HTML e um parser de JSON vai falhar.
Erros { "message" }, incluindo 401 e 404, são JSON quando Accept é application/json ou */*. Quando Accept está ausente, ou é text/html, esses status retornam uma página HTML (Content-Type: text/html) e um parser de JSON vai falhar. Isso importa para clientes que não enviam o cabeçalho Accept. O urllib do Python é um deles. O curl envia Accept: */* por padrão, e o fetch do Node também, então ambos recebem JSON, a menos que você sobrescreva Accept. POST /generate/..., GET /jobs/{id}, GET /styles e GET /assets sem autenticação retornam 401 {"message":"Unauthorized"} para */* e application/json, e uma página HTML quando Accept está ausente ou é text/html. Um GET /jobs/{id} autenticado para um id desconhecido faz o mesmo com o status: 404 JSON {"message":"Job not found or unauthorized"} quando Accept pede JSON, e 404 text/html quando Accept está ausente. JSON inválido (400) e validação (422) usam { "error" } e continuam em JSON mesmo quando Accept está ausente. O mesmo vale para o 422 de campo removido, o 410 de modelo descontinuado, o 402 de Zero Data Retention, as respostas { "error" } de node apps e os erros mapeados da API de operações do Agent. Os 402 e 429 na admissão de um job POST /generate/... também são JSON, inclusive para um Accept de navegador. 413 e 500 usam { "message" } e seguem o Accept, assim como 401 e 404.

Validação (422)

details lista todos os problemas. field é o caminho unido por . ("image_style_references.0.url"). Erros no nível do objeto usam uma string vazia, como na chave desconhecida acima. Várias chaves desconhecidas produzem Unrecognized keys: ... e o mesmo field vazio. expected só é adicionado quando code é "invalid_type". Um cabeçalho X-Webhook-URL inválido usa esse mesmo 422. GET /jobs com parâmetros de consulta inválidos também retorna esse 422. Não é um 400. Uma verificação de entrada de Zero Data Retention que falha dentro da ferramenta retorna 422 com a explicação em message (o formato { "message" }, então o Accept importa). Veja Zero Data Retention.

Campos removidos e obsoletos (422)

O campo removido batchSize / batch_size usa um 422 diferente. Não há array details:
batch_size é removido da mesma forma. field é o nome que você enviou. Um alias de campo obsoleto usa reason "deprecated_field" ou "conflicting_fields", além de replacement, sunset_date e migration_url quando se aplicam. Decida com base em error e reason. A frase a ser mostrada para uma pessoa é message.

Modelos descontinuados (410)

Um modelo que passou da data de descontinuação retorna 410 com Deprecation: true e um cabeçalho Sunset (uma data RFC 1123):
error é o valor estável "model_unavailable". replacement e migration_url são omitidos quando não há substituto recomendado. Repetir com o mesmo modelo continuará retornando 410. Mude para replacement quando ele estiver definido e veja Descontinuações. Um modelo obsoleto, mas ainda ativo, envia Deprecation e Sunset em todas as respostas, incluindo erros. Usar um alias de campo obsoleto faz o mesmo, inclusive no seu próprio 422. Quando existe um guia de migração, um cabeçalho Link: <migration_url>; rel="deprecation" também é enviado.

Códigos de status

400

JSON inválido em generate é sempre JSON, sem precisar do cabeçalho Accept:
O execute de node app usa { "error" } para uma URL de entrada que não consegue usar: Invalid URL for input "<key>" ou Failed to download URL for <key>: …. A mensagem de download também cobre falhas temporárias, então, ao contrário de generate (veja Downloads de entrada), uma falha de download em node app é sempre 400. Tente novamente uma vez se a URL for válida. JSON inválido em POST /node-apps/{id}/execute não é o 400 de generate acima. Ele vira um 500 { "message": "Internal Error" }, sem texto de exceção, e segue o Accept. Outras respostas 400 em assets e node apps são { "message": "..." } com uma explicação curta, por exemplo No file provided em um upload pré-assinado ou Invalid pagination parameters nas versões de node app. Um upload de asset com falha repassa o status do serviço de upload (400, 401, 404 ou 500) e pode colocar o texto da resposta em message. Esse texto às vezes é uma string JSON. Parâmetros de consulta inválidos em GET /jobs são 422, não 400.

401

Generate, jobs, assets, styles e node apps:
Uploads pré-assinados retornam { "message": "Presigned upload URL expired" } ou { "message": "Invalid presigned upload URL" }.

Pagamento necessário (402)

Para um cliente cobrado via API (uma chave de API, ou MCP usando uma chave de API) cujo saldo de API não cobre o job:
Adicione saldo em krea.ai/app/api/ ↗. Jobs em andamento são concluídos. Veja API Keys & Billing. Outros valores de message para 402 na API pública: Uma chamada de generate com Zero Data Retention em um workspace que não tem o recurso ativado retorna este corpo, sempre em JSON:
A API de operações do Agent usa seus próprios corpos 402. Eles consomem o saldo de computação do workspace, não o saldo de API.

403

404

Todo 404 é { "message" }, por exemplo um id de job desconhecido:
A ausência do cabeçalho Accept faz com que esses erros sejam HTML, exceto o Endpoint not found para um modelo que sua chave ou seu plano não pode usar, que é sempre JSON. Um GET /jobs/{id} autenticado para um id desconhecido sem Accept é 404 text/html. Uma operação do Agent desconhecida também é 404 { "message": "Endpoint not found" }, não o formato { "error", "code" } do Agent.

405

O corpo é texto simples sem cabeçalho Content-Type, não JSON, inclusive quando Accept é application/json. O texto é o método seguido de method not allowed, por exemplo GET method not allowed. Um cabeçalho Allow lista os métodos que o caminho aceita.

Payload grande demais (413)

Um corpo de requisição grande demais é rejeitado com 413. Vindo da própria API, o corpo segue o Accept:
Um corpo muito grande pode ser rejeitado antes de chegar à API, com uma página 413 em HTML. Não envie arquivos inline. Faça o upload do arquivo com POST /assets e passe a URL retornada na requisição de generate.

Downloads de entrada

Um host que retorna 404 ou 410 gera um 422 permanente. O corpo é JSON, e o Accept importa:
Um 410 do host usa a mesma frase com 410. Outras rejeições permanentes usam Input file rejected: …. Uma falha de download que pode ser repetida é 502 ou 504. Decida com base no código de status, não no corpo, e tente novamente. Um 502 que se repete para a mesma URL provavelmente significa que a URL está bloqueada ou quebrada. Troque a URL. Falhas de conversão na exportação 3D também são 502. Esse caminho não foi testado em produção, então o corpo também pode chegar como texto simples do Cloudflare error code: 502. Decida com base no código de status e tente novamente. Um 502 que se repete para a mesma URL de modelo provavelmente significa que a URL está bloqueada ou quebrada.

429 de concorrência

Quando o job não pode entrar em backlog, uma requisição acima do limite de concorrência pode ser rejeitada com 429 e Content-Type: application/json:
limit é o seu limite de concorrência para esse tipo de job. Ele é contado por usuário, não por workspace. É aproximado: uma rajada curta pode ser aceita acima dele, então não conte que a requisição limit + 1 será a que falha. jobType é uma categoria interna de job, não o caminho público do modelo. Não tome decisões com base nele. O Krea 2 também pode retornar apenas { "message": "CONCURRENCY_LIMIT_REACHED" }, sem limit nem jobType, quando sua fila compartilhada está cheia. Esse não é o seu limite. Aguarde e tente novamente. O backlog só fica ativo quando o plano o inclui (Pro e superiores), o modelo oferece suporte e a requisição não é de Zero Data Retention. No momento, requisições do Krea 2 não entram em backlog em nenhum plano, então retornam 429 acima do limite. Quando ele está ativo, o job extra é aceito com status: "backlogged" e começa assim que houver uma vaga livre. Não há um limite separado para o backlog. Veja Limites de Taxa. A API não envia Retry-After nem X-RateLimit-*. A resposta inclui cf-ray. Ao receber 429, tente novamente com backoff exponencial depois que os jobs em andamento terminarem (faça polling em GET /jobs/{id} ou use um webhook). Se uma conclusão posterior esgotar o saldo, os jobs que ainda estão no backlog falham com error.code "insufficient_balance". Isso é um job com falha, não um HTTP 402. Esses jobs não enviam webhook, então faça polling em GET /jobs/{id} para jobs em backlog.

API de operações do Agent

POST /agent/{operation} e GET /agent/session/{sessionId} retornam { "error", "code"?, "allowedModels"? }. Apenas error é obrigatório. allowedModels está em camelCase. Um turno que falha depois de ter sido aceito aparece como status: "failed" na sessão, não como um desses erros HTTP. Veja Agent API. Um código de erro do Agent não reconhecido continua sendo 422 com { "error", "code" }. O 404 de operação desconhecida e um 500 não tratado usam { "message" } e seguem o Accept.

error.code de jobs com falha

GET /jobs e GET /jobs/{id} definem error apenas quando status é "failed". Não há result utilizável:
Decida com base em error.code. Nunca faça parsing de message.message pode ser omitido. As mensagens de provider_error e internal são texto livre, e uma mensagem internal pode ser o texto bruto do provedor, como failed to download media from the provided URL. Trate qualquer code que você não reconheça como internal.
As entregas de webhook de um job com falha usam o mesmo objeto de job, incluindo error. Uma entrega de cancelamento não tem error. Um payload maior que 256 KiB não é enviado, e nenhuma outra entrega é feita para esse job, então faça polling em GET /jobs/{id}. Verifique a assinatura antes de confiar no corpo. Veja Webhooks.

Depuração

Não existe um cabeçalho de id de requisição da Krea. Toda resposta inclui o cabeçalho cf-ray do Cloudflare. Nenhum cabeçalho Retry-After ou X-RateLimit-* é enviado. Ao escrever para support@krea.ai, inclua:
  • O job_id, quando a chamada criou ou referenciou um job
  • O horário e o endpoint
  • Para um erro no momento da requisição, o valor de cf-ray
Access-Control-Allow-Origin é *. Em generate, jobs, assets, styles e node apps, Access-Control-Expose-Headers não é definido, então o fetch do navegador não consegue ler cf-ray, Deprecation nem Sunset. Copie o cf-ray do log de rede ou de um cliente no servidor. Em qualquer resposta, verifique Deprecation e Sunset antes que o modelo pare de aceitar chamadas. Veja Descontinuações.

Próximos passos

Ciclo de vida do job

Faça polling do status até o job ser concluído, falhar ou ser cancelado

Webhooks

Verifique a assinatura em uma entrega de job com falha

Limites de taxa

Quando jobs extras entram em backlog e quando retornam 429

API Keys & Billing

Adicione saldo de API depois de um 402