Search

Search HiAPI models, tools, and resources.

Back to blog
Tutorial

How to Use flux-2-klein-4b/text-to-image via the hiapi API

hiapiapi-guideimage-generationflux

slug: flux-2-klein-4b-text-to-image-api-guide locale: en title: How to Use flux-2-klein-4b/text-to-image via the hiapi API category: tutorial summary:

  • Minimal curl and Python examples for flux-2-klein-4b/text-to-image over hiapi's unified /v1/tasks endpoint.
  • 'Full parameter table: prompt, aspect_ratio enum, and seed — the strict schema rejects unknown fields.'
  • 'Production notes: callback.url vs polling, the Idempotency-Key header, and the two error envelope shapes.' takeaways:
  • Create with POST /v1/tasks, then poll GET /v1/tasks/{taskId} or use callback.url for the result.
  • aspect_ratio accepts 11 named ratios; there's no size or n field for this model.
  • Same Idempotency-Key header returns the same taskId on retry — safe to reuse on timeouts.
  • 400 errors use error_code, 401 auth errors use a nested error.code — check HTTP status first. meta_title: flux-2-klein-4b Text-to-Image API Guide meta_description: 'Call flux-2-klein-4b/text-to-image with curl and Python: create a task, poll for the image, and handle callbacks, idempotency, and errors in production.' keywords:
  • flux-2-klein-4b text-to-image api
  • flux-2-klein-4b api example
  • hiapi image generation api
  • flux api curl python tags:
  • api-guide
  • image-generation
  • flux author_name: hiapi is_published: false cover_image: https://static.hiapi.ai/blog/_default/recipe-cover.jpg

How to Use flux-2-klein-4b/text-to-image via the hiapi API

What you'll build

A script that sends a prompt to flux-2-klein-4b/text-to-image, waits for the image, and downloads it — plus the production details (callbacks, idempotency, error shapes) you need before this runs unattended.

Prerequisite: grab an API key from the hiapi dashboard. Every request below authenticates with Authorization: Bearer sk-<your-api-key>.

The minimal working example

hiapi generation models run behind one unified async endpoint: POST /v1/tasks creates a job and hands back a taskId immediately; you then poll GET /v1/tasks/{taskId} until it reaches a terminal state.

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-2-klein-4b/text-to-image",
    "input": {
      "prompt": "a red fox walking through fresh snow, golden hour light",
      "aspect_ratio": "16:9"
    }
  }'

That returns:

{"code": 200, "data": {"taskId": "tk-hiapi-01K..."}, "message": "success"}

Poll the same task until data.status flips from handling to success (it briefly passes through archiving in between):

curl https://api.hiapi.ai/v1/tasks/tk-hiapi-01K... \
  -H "Authorization: Bearer sk-<your-api-key>"
{
  "code": 200,
  "data": {
    "status": "success",
    "output": [
      {"type": "image", "url": "https://temp.hiapi.ai/.../01K...-0.jpg", "expireAt": 1785939579}
    ]
  },
  "message": "success"
}

data.output[0].url is the finished image. It's a temporary link — in testing it expired about 7 days after generation — so download the bytes and store them yourself rather than linking to it directly.

Same flow in Python, with polling

import time
import requests

API_KEY = "sk-<your-api-key>"
BASE = "https://api.hiapi.ai/v1"
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

resp = requests.post(f"{BASE}/tasks", headers=headers, json={
    "model": "flux-2-klein-4b/text-to-image",
    "input": {
        "prompt": "a red fox walking through fresh snow, golden hour light",
        "aspect_ratio": "16:9",
    },
})
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]

while True:
    task = requests.get(f"{BASE}/tasks/{task_id}", headers=headers).json()["data"]
    if task["status"] == "success":
        image_url = task["output"][0]["url"]
        break
    if task["status"] == "failed":
        raise RuntimeError(f"generation failed: {task}")
    time.sleep(3)

image_bytes = requests.get(image_url).content
open("fox.jpg", "wb").write(image_bytes)

Parameters that matter

flux-2-klein-4b/text-to-image has a strict input schema — sending a field it doesn't recognize (size, n, negative_prompt, whatever another hiapi image model accepts) gets rejected outright, so don't copy params across models without checking the model page first.

FieldRequiredNotes
promptYesString describing the image.
aspect_ratioNoOne of 1:1, 16:9, 9:16, 3:2, 2:3, 4:3, 3:4, 5:4, 4:5, 21:9, 9:21. Defaults to 1:1 if omitted.
seedNoInteger. Reuse a seed to make results reproducible across calls.

Full parameter reference lives on the model page; current per-image pricing is on the pricing page — check there rather than hardcoding a number, since usage-based rates change.

Production write-up

Callbacks over polling. For anything beyond a quick script, skip the poll loop and add callback.url (plus "when": "final") to the task-creation body — hiapi POSTs the result to your endpoint once the task finishes, exactly the same payload shape you'd get from GET /v1/tasks/{taskId}. See Create Task for the callback field and signature-verification details.

{
  "model": "flux-2-klein-4b/text-to-image",
  "callback": {"url": "https://yourapp.com/hooks/hiapi", "when": "final"},
  "input": {"prompt": "a red fox walking through fresh snow, golden hour light"}
}

Idempotency. Set an Idempotency-Key header (up to 255 bytes) on your POST /v1/tasks call. Retrying the same request with the same key under the same account won't create a second task — you get the original taskId back. That's what makes it safe to retry a request that timed out on your side without double-billing.

Error handling. Two different failure shapes show up in practice, so check both:

  • A bad input (missing prompt, an out-of-range aspect_ratio, an unsupported field) returns HTTP 400 with {"error_code": "INVALID_REQUEST", "message": "..."}.
  • An invalid or unauthorized API key returns HTTP 401 with a different envelope: {"error": {"code": "permission_denied", "message": "...", "request_id": "..."}}.

Branch on the HTTP status first, then read whichever error field is present — don't assume one envelope shape for every failure.

FAQ

Does flux-2-klein-4b/text-to-image support image-to-image? Not directly — that's a separate model, flux-2-klein-4b/image-to-image, with its own input schema.

What's the difference between flux-2-klein-4b and flux-2-klein-9b? Both are text-to-image endpoints in the same FLUX.2 [klein] family; 9b is the larger of the two. Check the 9b model page for its current pricing and parameters before switching.

Can I request multiple images in one call? No — the schema doesn't accept an n or count field. Send one request per image you need.

How long is the returned image URL valid? The output[0].url is a temporary link with its own expireAt timestamp; treat it as short-lived (roughly a week in testing) and download the bytes right after the task succeeds instead of storing the URL.

Why am I getting a 401 permission_denied error? Your key is missing, invalid, or doesn't have access to this model. Confirm you're sending Authorization: Bearer sk-... with a key from your dashboard, not a placeholder.

Do I need to run my own server to use this API? Only if you want callbacks. Polling GET /v1/tasks/{taskId} from a script, cron job, or serverless function works fine for low-volume use; switch to callback.url once you're generating at scale.

Generate it with HiAPI

Choose a model, enter your prompt, and see the result.

HiAPI Blog

Related articles

HiAPI

Generate it with HiAPI

Start generating