krea-2-medium-turbo is Krea's fast, low-cost text-to-image tier on hiapi. You send one prompt, pick an aspect ratio, and get a single rendered image back through the asynchronous task API. This guide gives you a copy-paste curl and Python request against /v1/tasks, the exact input schema, and the timing and error behaviour I measured on 2026-10-21 — including one result that contradicts the documentation.
What you need first
A hiapi API key (sk-...). Create one in the API Keys dashboard. Every request authenticates with Authorization: Bearer sk-<your-key>. That's the only prerequisite — the model runs server-side, so there's nothing to install except an HTTP client.
The input schema
krea-2-medium-turbo takes five fields. Only prompt and model are required:
| Field | Required | Type | Default | Notes |
|---|---|---|---|---|
model | yes | string | — | Must be exactly krea-2-medium-turbo. |
prompt | yes | string | — | 1–5000 characters. |
aspect_ratio | no | enum | 1:1 | One of 1:1, 4:3, 3:2, 16:9, 2.35:1, 4:5, 2:3, 9:16. |
creativity | no | enum | low | raw (most literal) → low → medium → high (most creative). |
seed | no | integer | — | Optional. Read the seed caveat below before you rely on it. |
The input object is strict (additionalProperties: false): any field that isn't in this table is rejected before generation starts. There is no n / num_images, no resolution or size, and no negative-prompt field. One request returns exactly one image, and the output dimensions are driven entirely by aspect_ratio. If you've used other image APIs on hiapi that accept resolution (Seedream, Qwen-Image) or size, drop those here — they'll 400.
Minimal working request (curl)
Creating a task returns immediately with a taskId; the image renders in the background.
curl -s -X POST "https://api.hiapi.ai/v1/tasks" \
-H "Authorization: Bearer sk-<your-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "krea-2-medium-turbo",
"input": {
"prompt": "A lighthouse on a rocky coast at golden hour, cinematic wide shot",
"aspect_ratio": "2.35:1",
"creativity": "medium",
"seed": 42
}
}'
Response:
{ "code": 200, "data": { "taskId": "tk-hiapi-01M5E4J4FQVJNSDKQ29BRSMD0A" }, "message": "success" }
Then poll the task by id until it reaches a terminal status:
curl -s "https://api.hiapi.ai/v1/tasks/tk-hiapi-01M5E4J4FQVJNSDKQ29BRSMD0A" \
-H "Authorization: Bearer sk-<your-key>"
A finished task looks like this (fields trimmed for clarity):
{
"code": 200,
"data": {
"taskId": "tk-hiapi-01M5E4J4FQVJNSDKQ29BRSMD0A",
"model": "krea-2-medium-turbo",
"status": "success",
"storage": "temp",
"created": 1792549655,
"completed": 1792549681,
"output": [
{
"type": "image",
"url": "https://temp.hiapi.ai/xxxxxxxx/01M5E4J4FQVJNSDKQ29BRSMD0A-0.png",
"artifactId": "280334",
"expireAt": 1793154481
}
]
},
"message": "success"
}
The image is at data.output[0].url.
The same flow in Python
import time
import requests
API = "https://api.hiapi.ai/v1/tasks"
HEADERS = {
"Authorization": "Bearer sk-<your-key>",
"Content-Type": "application/json",
}
def generate(prompt, aspect_ratio="1:1", creativity="low", seed=None):
body = {
"model": "krea-2-medium-turbo",
"input": {"prompt": prompt, "aspect_ratio": aspect_ratio, "creativity": creativity},
}
if seed is not None:
body["input"]["seed"] = seed
created = requests.post(API, headers=HEADERS, json=body, timeout=30)
created.raise_for_status()
task_id = created.json()["data"]["taskId"]
# Poll until the task reaches a terminal state.
while True:
data = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=30).json()["data"]
status = data["status"]
if status == "success":
return data["output"][0]["url"]
if status == "fail": # note: still HTTP 200, see below
raise RuntimeError(f"generation failed: {data}")
time.sleep(3)
url = generate(
"A lighthouse on a rocky coast at golden hour, cinematic wide shot",
aspect_ratio="2.35:1",
creativity="medium",
)
print(url)
Production notes
- Poll or use a callback. The loop above polls every 3 s, which is fine for low volume. For production, attach a
callback.urlwithwhen: "final"on the create request and let hiapi POST you the finished task instead of polling — see the task API docs for the callback contract. - A failed generation still returns HTTP 200. The HTTP status on the poll endpoint reports whether the request succeeded, not whether the image succeeded. A failed render comes back as
200withdata.status: "fail". Branch ondata.status, not on the HTTP code, or you'll treat failures as successes. - Output URLs are temporary. Results are stored under
"storage": "temp"ontemp.hiapi.aiwith anexpireAttimestamp roughly seven days out (604,800 s in my runs). Download the bytes and re-host them (your own bucket/CDN) as soon as the task finishes — don't hotlink thetemp.hiapi.aiURL from production pages. - Pricing is a single flat rate per image, independent of aspect ratio or creativity level — there are no resolution tiers to reason about. Check the current figure on the pricing page rather than hard-coding it.
What I actually tested (2026-10-21)
Everything below is from live calls, not the docs:
- Timing and resolution. A
2.35:1request completed in ~26 s (created→completeddeltas), and the returned PNG was 1568 × 672 px — so2.35:1really is the cinematic widescreen crop, not a squared-off approximation. The task passes through intermediate statuseshandling→archiving→successwhile it renders and moves the file to temp storage. - Enum validation is enforced server-side. Sending
"aspect_ratio": "21:9"(a plausible but unsupported value) returns400immediately:invalid input: aspect_ratio: value must be one of '1:1', '4:3', '3:2', '16:9', '2.35:1', '4:5', '2:3', '9:16'. The error names the field and lists the legal values, which makes it easy to handle programmatically. - Unknown fields 400, they don't get ignored.
"resolution": "2K"returnsinvalid input: <root>: additional properties 'resolution' not allowed;"n": 2returns the same error forn. This is theadditionalProperties: falserule in action — copy a request body from a different model and the stray fields will block the whole call. seeddid not reproduce an identical image in my test. I sent the same prompt,seed: 42,aspect_ratio: 2.35:1, andcreativity: mediumtwice back-to-back. Both returned valid 1568 × 672 images, but they were visibly different scenes (a white tower in one, a red-and-white striped tower in the other) with different file sizes (1.30 MB vs 1.51 MB) and different hashes. The field is accepted and documented as reproducible, but treat exact pixel reproduction as best-effort rather than guaranteed — if you need a specific frame, save the output you got, don't re-request it from the seed.
Related pages
- krea-2-medium-turbo model page — live playground and full parameter reference.
- krea-2-medium-turbo API docs — endpoint and callback details.
- Krea 3 text-to-image — the newer, quality-oriented Krea tier (with
berry/jammodes); use it when you want more polish andkrea-2-medium-turbowhen you want speed and low cost. - AI image generation APIs on hiapi — other text-to-image models behind the same task interface.
FAQ
Which aspect ratios can I request? Eight: 1:1 (default), 4:3, 3:2, 16:9, 2.35:1, 4:5, 2:3, and 9:16. Any other value returns a 400.
Can I generate more than one image per call? No. There's no n field, and the schema rejects unknown properties, so each request yields exactly one image. Loop the request (optionally with different seeds) for a batch.
What does creativity do? It controls how literally the model follows your prompt: raw is the most faithful to the wording, high takes the most interpretive liberty, with low (default) and medium in between.
Does krea-2-medium-turbo support image-to-image or editing? No — it's text-to-image only. There are no image_urls / input-image fields in the schema. Use a dedicated edit/i2i model on hiapi if you need to transform an existing picture.
How long are output URLs valid? They're served from temporary storage and expire (about seven days out in my tests). Download and re-host the image right after the task finishes.





