Search

Search HiAPI models, tools, and resources.

Back to blog
Tutorial

How to Use seedream-5.0-flash via the hiapi API: curl, Python, and a Working Request

hiapiseedreamimage-generationapi-tutorialpython

What you'll build

A working integration that calls the hiapi seedream-5.0-flash image model from curl and from Python: submit a text-to-image (or image-edit) request, poll for the result, and download the output URL. By the end you'll have a script you can drop into your own project.

Prerequisites

  • A hiapi account and API key. Grab one from the hiapi dashboard — keys look like sk-....
  • curl or Python 3.8+ (pip install requests).
  • No image-editing library required — seedream-5.0-flash accepts a plain prompt, or a prompt plus an input image URL for editing.

Full model reference: seedream-5.0-flash on hiapi and the API doc page.

Minimal runnable example

hiapi exposes every generation model through one unified endpoint: you create a task, then poll it (or get a callback) until it finishes.

curl

# 1. Create the task
curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedream-5.0-flash",
    "input": {
      "prompt": "a minimalist ceramic teapot on a wooden table, soft morning light, product photography",
      "size": "2K"
    }
  }'
# => {"code":0,"data":{"taskId":"task_xxx","status":"pending", ...}}

# 2. Poll until it finishes
curl -s https://api.hiapi.ai/v1/tasks/task_xxx \
  -H "Authorization: Bearer sk-<your-api-key>"
# => {"code":0,"data":{"taskId":"task_xxx","status":"success",
#      "output":[{"url":"https://...signed-url...","expireAt":"..."}]}}

Python

import time
import requests

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


def generate_image(prompt: str, size: str = "2K") -> str:
    create = requests.post(
        f"{BASE_URL}/tasks",
        headers=HEADERS,
        json={"model": "seedream-5.0-flash", "input": {"prompt": prompt, "size": size}},
        timeout=30,
    )
    create.raise_for_status()
    task_id = create.json()["data"]["taskId"]

    while True:
        poll = requests.get(f"{BASE_URL}/tasks/{task_id}", headers=HEADERS, timeout=30)
        poll.raise_for_status()
        data = poll.json()["data"]
        if data["status"] == "success":
            return data["output"][0]["url"]
        if data["status"] == "fail":
            raise RuntimeError(f"task failed: {data}")
        time.sleep(2)


if __name__ == "__main__":
    image_url = generate_image("a minimalist ceramic teapot on a wooden table, soft morning light")
    print(image_url)

Notes on the input object:

  • prompt (required, 1–5000 chars) — what to generate, or what to change if you also pass image.
  • image (optional, string or array of up to 10 URLs/base64 data:image/... URIs) — pass this to edit/reference an existing image instead of generating from scratch. Omit it for pure text-to-image.
  • size (optional, default "2K") — one of the presets 1K / 1.5K / 2K, or a custom WIDTHxHEIGHT string like "1536x1024" (921,600–4,624,220 total pixels, aspect ratio between 1:16 and 16:1).
  • output_format (optional) — "jpeg" or "png".
  • background (optional, default "opaque") — set "transparent" only when editing an image that has an alpha channel.

The response output[].url is a signed, expiring link (expireAt field) — download or re-host it promptly rather than storing the hot URL long-term.

Production patterns

Use a callback instead of polling

For server-to-server integrations, skip polling and let hiapi notify you when the task finishes. Add a top-level callback object alongside model/input (not nested inside input):

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedream-5.0-flash",
    "input": {"prompt": "a minimalist ceramic teapot on a wooden table"},
    "callback": {"url": "https://yourapp.example.com/hooks/hiapi", "when": "final"}
  }'

when: "final" is currently the only supported value — your endpoint receives exactly one POST when the task reaches a terminal state (success or fail). Dedupe on taskId in case of retried deliveries, and verify your endpoint is reachable over HTTPS before relying on it in production.

Poll vs. callback

  • Poll when you're prototyping, running a short-lived script, or don't have a public HTTPS endpoint yet. Simple, but adds latency and request volume for slow tasks.
  • Callback when you're running a service — no wasted polling requests, and you find out the instant the task completes. Requires a publicly reachable HTTPS URL.

Idempotency

Image generation itself isn't idempotent (the same prompt won't return the same image twice), so if your workflow needs "don't double-charge on retry" semantics, track taskId on your side and check task status before resubmitting an identical request after a timeout, rather than blindly retrying.

Error handling

  • 401 with permission_denied — your API key is missing, malformed, or revoked:

    {"error":{"code":"permission_denied","message":"This API key is invalid. Check that it is correct or use another API key and try again.","type":"hiapi_error"}}
    

    Double-check you're sending Authorization: Bearer sk-... (not just the raw key) and that the key hasn't been rotated.

  • 400 with INVALID_REQUEST — a field failed validation. The message tells you exactly which field and why, e.g. an out-of-range size. Fix the field and resubmit; don't retry as-is.

  • Task-level failure — the HTTP call can succeed (200) while the task still ends in status: "fail" once processing completes. Always check data.status on your poll/callback response, not just the HTTP status code of the create call.

FAQ

Is seedream-5.0-flash free to use? No — it's billed per image through your hiapi API key. See pricing for current rates; there's no production access without a valid key.

Does seedream-5.0-flash support image-to-image editing, not just text-to-image? Yes. Add an image field (a URL or base64 data:image/... string, or an array of up to 10) alongside your prompt and the model will edit/blend based on the reference image(s) instead of generating from scratch.

Why does my request return 200 but no image? A 200 from POST /v1/tasks only means the task was accepted — generation is asynchronous. Poll GET /v1/tasks/<id> (or wait for your callback) and check data.status; the image URL only appears once status is "success".

Can I request a custom resolution instead of 1K/1.5K/2K? Yes — pass size as "WIDTHxHEIGHT" (e.g. "1536x1024") instead of a preset. It must total between 921,600 and 4,624,220 pixels with an aspect ratio between 1:16 and 16:1, or the request returns a 400.

What happens to the output URL after a while? The returned output[].url is a signed URL with an expireAt timestamp — it is not permanent storage. Download the bytes or copy them to your own storage shortly after the task succeeds.

My callback never fires — what should I check first? Confirm your callback.url is a publicly reachable HTTPS endpoint (not localhost or an internal-only address), and that callback is a top-level field in your request body — not nested inside input.

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