black-forest-labs/flux-2-klein-4b/text-to-imageA partir de 2 créditos por imagem· Criar imagem

O FLUX.2 [klein] 4B é o modelo de imagem compacto da Black Forest Labs, com 4 bilhões de parâmetros, lançado em 15 de janeiro de 2026 sob a licença Apache 2.0. Geração e edição ficam num só modelo: nove proporções de até 2048 pixels no lado maior e edições a partir de até três imagens de referência. Foi feito para velocidade, sem revisão de prompts nem de resultados, embora um modelo pequeno costume vestir as pessoas com mais roupa do que você pediu.

Chame com o nome de modelo black-forest-labs/flux-2-klein-4b/text-to-image em POST /jobs/createTask, a partir de 2 créditos por imagem (US$ 0,02). Contas novas ganham 30 créditos grátis para você testar primeiro no Playground.

  • Criar imagem
  • Editar imagem
  • Até 2K
  • Até 3 imagens de referência
  • 9 proporções
Nome do modeloblack-forest-labs/flux-2-klein-4b/text-to-image
EndpointPOST https://api.popnow.ai/api/v1/jobs/createTask
# 1. Create the task. Keep the Idempotency-Key if you retry after a network error.
export IDEMPOTENCY_KEY="$(uuidgen)"
curl -X POST https://api.popnow.ai/api/v1/jobs/createTask \
  -H "Authorization: Bearer $POPNOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -d '{
  "model": "black-forest-labs/flux-2-klein-4b/text-to-image",
  "input": {
    "prompt": "A ceramic teapot on a linen cloth, soft window light, muted palette",
    "aspect_ratio": "1:1",
    "resolution": "1k"
  }
}'

# 2. Copy data.taskId from the response, then poll until state is succeeded, failed, canceled or expired.
TASK_ID="TASK_ID_FROM_RESPONSE"
curl "https://api.popnow.ai/api/v1/jobs/recordInfo?taskId=$TASK_ID" \
  -H "Authorization: Bearer $POPNOW_API_KEY"

O input é montado a partir do schema abaixo, então passa na validação como está. Troque o prompt e os links pelos seus.

Preço

OpçãoCréditos por imagem≈ USD
resolution 1K1,39US$ 0,014
resolution 2K1,49US$ 0,015

1 crédito = US$ 0,01 · Todas as opções e preços: GET /models/black-forest-labs/flux-2-klein-4b/text-to-image

Cada tarefa é arredondada para cima em créditos inteiros, então uma execução no nível mais baixo custa 2 créditos por imagem (US$ 0,02).

Limites

Resoluções
1K · 2K
Proporções
1:1 · 16:9 · 9:16 · 4:3 · 3:4 · 3:2 +3
Tamanho do prompt (caracteres)
5,000

Parâmetros

Estes campos vêm do mesmo schema que usamos para validar cada requisição. Campos que não estão na lista são rejeitados.

  • promptstringObrigatório

    Describe the subject, setting, light and style in plain sentences.

    Faixa
    1 – 5000 chars
  • aspect_ratiostringOpcional

    O formato do quadro: horizontal, quadrado ou vertical.

    Padrão
    "1:1"
    Valores aceitos
    "1:1""16:9""9:16""4:3""3:4""3:2""2:3""21:9""9:21"
  • resolutionstringOpcionalMuda o preço

    Tamanho de saída. Maior fica mais nítido e custa mais.

    Padrão
    "1k"
    Valores aceitos
    "1k""2k"
  • seedintegerOpcional

    Repetir o mesmo número dá um resultado reproduzível.

    Faixa
    0 – 2147483647
JSON Schema bruto
{
  "type": "object",
  "required": [
    "prompt"
  ],
  "properties": {
    "seed": {
      "type": "integer",
      "maximum": 2147483647,
      "minimum": 0,
      "description": "Random seed for controlled comparisons."
    },
    "prompt": {
      "type": "string",
      "maxLength": 5000,
      "minLength": 1,
      "description": "Describe the subject, setting, light and style in plain sentences."
    },
    "resolution": {
      "enum": [
        "1k",
        "2k"
      ],
      "type": "string",
      "default": "1k",
      "description": "Output size tier: 1k is about one megapixel, 2k is 2048 pixels on the long side."
    },
    "aspect_ratio": {
      "enum": [
        "1:1",
        "16:9",
        "9:16",
        "4:3",
        "3:4",
        "3:2",
        "2:3",
        "21:9",
        "9:21"
      ],
      "type": "string",
      "default": "1:1",
      "description": "Output aspect ratio."
    }
  },
  "additionalProperties": false
}

Respostas, consultas e callbacks

Todos os modelos funcionam do mesmo jeito: crie uma tarefa e depois consulte ou espere o callback.

Veja o preço antes

cURL
curl -X POST https://api.popnow.ai/api/v1/jobs/quote \
  -H "Authorization: Bearer $POPNOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "black-forest-labs/flux-2-klein-4b/text-to-image",
  "input": {
    "prompt": "A ceramic teapot on a linen cloth, soft window light, muted palette",
    "aspect_ratio": "1:1",
    "resolution": "1k"
  }
}'

Mesmo corpo do createTask. Retorna a cobrança esperada e a máxima possível, sem rodar nada.

Aceita

HTTP
HTTP/1.1 202 Accepted

{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "task_01k3m8x9q2z4v7n5p6r8s0t1w3",
    "state": "queued"
  },
  "request_id": "req_example_create"
}

HTTP 202 quer dizer que a tarefa foi aceita e os créditos estão reservados, ainda não cobrados. A cobrança final nunca passa da reserva.

Consultar status

cURL
curl "https://api.popnow.ai/api/v1/jobs/recordInfo?taskId=$TASK_ID" \
  -H "Authorization: Bearer $POPNOW_API_KEY"

Consulte a cada poucos segundos, espaçando cada vez mais, e pare quando state for succeeded, failed, canceled ou expired.

Tarefa pronta

JSON
{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "task_01k3m8x9q2z4v7n5p6r8s0t1w3",
    "model": "black-forest-labs/flux-2-klein-4b/text-to-image",
    "state": "succeeded",
    "output": {
      "assets": [
        {
          "url": "https://cdn.popnow.ai/tasks/task_01k3m8x9q2z4v7n5p6r8s0t1w3/output.png?signature=FROM_RESPONSE",
          "expiresAt": "2026-10-17T12:20:00Z",
          "mime": "image/png",
          "width": 1024,
          "height": 1024
        }
      ]
    },
    "settled": true
  },
  "request_id": "req_example_record"
}

Baixe pela url antes de expiresAt. Precisa de um link novo depois? Peça com POST /common/download-url.

Verificar um callback

Node.js
import { createHash, createHmac, timingSafeEqual } from "node:crypto";
import express from "express";

const app = express();
// express.raw keeps the exact bytes that were signed; express.json would not match.
app.post("/hooks/popnow", express.raw({ type: "application/json" }), (req, res) => {
  const timestamp = req.header("X-Webhook-Timestamp");
  const signature = req.header("X-Webhook-Signature") ?? "";
  const body = JSON.parse(req.body.toString("utf8"));
  const taskId = body.data?.taskId ?? body.task_id;
  const digest = createHash("sha256").update(req.body).digest("hex");
  const expected = createHmac("sha256", process.env.POPNOW_WEBHOOK_SECRET)
    .update(`${taskId}.${timestamp}.${digest}`)
    .digest("base64");
  const ok = expected.length === signature.length && timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
  // Check the signature first, then reject anything older than five minutes.
  if (!ok || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return res.status(401).end();
  res.status(200).end(); // answer fast, then fetch the task and store its files
});

Com callBackUrl definida, enviamos a tarefa pronta para você. Confira a assinatura no corpo bruto antes de confiar nela.

Enviar um arquivo local

cURL
curl -X POST https://api.popnow.ai/api/v1/common/upload-url \
  -H "Authorization: Bearer $POPNOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contentType": "image/png", "bytes": 482113}'

# PUT the file bytes to data.uploadUrl with every header in data.headers, then commit it:
curl -X POST https://api.popnow.ai/api/v1/files/$FILE_ID/commit \
  -H "Authorization: Bearer $POPNOW_API_KEY"
# The commit returns a popnow://f/... reference. Put it in any image, video or
# audio field of the task input instead of a public https URL.

Links https públicos funcionam como estão. Arquivos locais passam antes por upload-url e commit.