HiAPI
Blog

Tutorial

How to Use imagen-4.0-fast via the HiAPI API: curl and Python Guide

A practical integration guide for developers: request setup, parameter handling, and reliability patterns for the fast image model

Nov 3, 2026 11 min read
暖沙色背景上,赭红与棕褐的横向阶梯色带自左向右层层下行,构成教程文章的封面图。

What imagen-4.0-fast Is Optimized For

imagen-4.0-fast is the latency-oriented tier of the imagen-4.0 family: it targets fast turnaround on image generation requests while keeping the same request-and-response shape you would use for the rest of the family. In practice, that makes it the tier you reach for when an image needs to appear inside a user-facing interaction — a draft thumbnail, a preview the user will refine, an asset for a live layout — rather than in an offline batch where wall-clock time is irrelevant.

A useful way to think about model selection is to separate the interaction budget from the quality ceiling. Fast tiers win when the interaction budget is tight and a good-enough image unblocks the next step. Higher-quality tiers win when the image itself is the deliverable. Because imagen-4.0-fast lives behind the same HiAPI interface as other image models, switching tiers later is a configuration change, not a rewrite — so you can start on the fast tier, measure whether output quality meets your product bar, and only then consider moving specific use cases up the tier ladder.

The other thing the fast tier is optimized for is predictability under load. Short generations mean connections are held for less time, which makes concurrency budgets behave more linearly: doubling workers roughly doubles throughput until you hit account-level rate limits rather than timing out mid-generation. That property is what the later sections on timeouts and concurrency build on.

If your use case involves multi-step user flows, batching, or anything where a request might be retried, the fast tier is the safer default — you can afford one extra attempt and still land inside a human's patience window.

Prerequisites and API Setup

Before the first call, gather four things.

1. A HiAPI account and API key

All image generation goes through the HiAPI unified API. Create an API key in your HiAPI dashboard and store it as an environment variable rather than in source code:

export HIAPI_API_KEY="your_key_here"

Never commit the key. If your code runs in CI or a container, inject the variable through your secret manager at runtime.

2. A base URL and model identifier

Keep two constants in one config module so every request in your codebase points at the same place:

HIAPI_BASE_URL = "https://api.hiapi.ai"
HIAPI_IMAGE_MODEL = "imagen-4.0-fast"

The model identifier is what selects imagen-4.0-fast inside a request payload. Treat it as data, not as a hardcoded string scattered across files.

3. An HTTP client you trust

For Python, httpx or requests both work; httpx gives you cleaner timeout objects. For shell work, curl is enough and is the fastest way to isolate whether a problem is in your code or in the request itself.

4. A minimal test harness

Decide up front where generated output will land — writing to a file on disk for a smoke test is fine, but production code should stream or store deliberately rather than leave large payloads in memory.

Two configuration habits pay off early. First, centralize authentication in one helper that attaches the Authorization header, so rotating a key touches one place. Second, keep a DEBUG flag that lets you print request IDs and timing without changing payloads. When something fails at 2am, those two habits are the difference between a five-minute fix and an hour of guessing.

A Working Request with curl

Here is a complete, runnable curl call. It generates a single image from a text prompt:

curl -sS -X POST "$HIAPI_BASE_URL/v1/images/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "imagen-4.0-fast",
    "prompt": "a quiet harbor at dawn, soft mist over wooden docks, photographic",
    "n": 1,
    "size": "1024x1024"
  }'

Walking through the fields:

  • -sS silences the progress meter but still shows errors. For debugging, add -i to see response headers, which usually carry a request ID you can quote when asking for help.
  • -X POST with the Content-Type: application/json header is what makes the payload a structured request rather than an opaque body.
  • Authorization: Bearer $HIAPI_API_KEY is the only authentication mechanism. The key is read from the environment so it never appears in your shell history in plaintext if you set it in your session.
  • model selects imagen-4.0-fast within the HiAPI image endpoint. Omit it and you may get a different default model — always be explicit.
  • prompt is the only required content field. Keep it descriptive but not encyclopedic; long prompts cost tokens and rarely improve fast-tier output past a point.
  • n controls how many images the request returns. Start at 1 while integrating.
  • size is the output resolution request. Section five covers how to choose it.

Run it once and inspect the response body before writing any Python. If curl succeeds, every later failure is in your client code. If curl fails, the problem is the key, the payload, or the account — and you have already eliminated half the search space.

The Same Request in Python

Here is the minimal Python client, translated field-for-field from the curl call, with error handling wrapped around the HTTP layer:

import os
import httpx

HIAPI_BASE_URL = "https://api.hiapi.ai"
HIAPI_IMAGE_MODEL = "imagen-4.0-fast"

def generate_image(prompt: str, size: str = "1024x1024") -> dict:
    api_key = os.environ["HIAPI_API_KEY"]  # fail fast if unset
    payload = {
        "model": HIAPI_IMAGE_MODEL,
        "prompt": prompt,
        "n": 1,
        "size": size,
    }
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    }
    with httpx.Client(timeout=httpx.Timeout(60.0, connect=10.0)) as client:
        response = client.post(
            f"{HIAPI_BASE_URL}/v1/images/generations",
            json=payload,
            headers=headers,
        )
    if response.status_code == 401:
        raise RuntimeError("HiAPI rejected the API key")
    if response.status_code == 429:
        raise RuntimeError("Rate limited; back off and retry")
    response.raise_for_status()
    return response.json()

if __name__ == "__main__":
    result = generate_image("a quiet harbor at dawn, soft mist over wooden docks, photographic")
    print(result)

A few deliberate choices in that snippet:

  • os.environ["HIAPI_API_KEY"] raises KeyError immediately if the variable is missing, which is better than sending an unauthenticated request and misreading the 401 as a key problem.
  • Explicit timeouts — a connect timeout and a read timeout separately. The read timeout is the one that matters for image generation, because the server holds the connection while the image is produced.
  • Status-specific branches before raise_for_status(). A 401 and a 429 need completely different responses from your code; collapsing them into one exception makes retries accident-prone.
  • A Client context manager so connections are closed deterministically. In a long-lived service, create one client at startup and reuse it instead — connection reuse matters for throughput.

The response body carries the generated image reference plus metadata. Log the full body on the first few calls during integration so you know exactly what field names your code depends on.

Parameters and Resolution Choices

Parameter handling for imagen-4.0-fast rewards a boring, explicit style. Keep the payload as a dict built by one function, and validate before sending rather than after a failure.

Prompt

The prompt is the highest-leverage parameter and the easiest to over-engineer. Describe subject, setting, and style in that order. Avoid stacking contradictory style words; the fast tier will resolve them into an average, not a compromise you control. If you generate the same prompt repeatedly, cache the result server-side rather than re-requesting.

n

Requesting multiple images in one call is convenient for user-facing pickers, but it multiplies the work done in a single request and therefore the time the connection is held. During integration keep n at 1; add it only after you have measured end-to-end latency with it enabled.

size

The resolution parameter is where costs and latency quietly accumulate. Larger output means more generation work and larger response bodies. Pick the smallest resolution that satisfies the display context — a thumbnail slot does not need a hero image's dimensions. Decouple the generation size from the display size and let your own image pipeline upscale or downscale afterward; that keeps requests predictable and makes it easy to tune quality against latency later without changing prompt logic.

Determinism and reproducibility

Record every parameter you send alongside the output, keyed by a request ID. When someone asks why an image looks different from last week, a stored payload answers the question in seconds. If you build payloads by merging user input over defaults, validate the merged result as a whole — partial overrides are the usual source of malformed requests.

A practical rule: the payload should be small, fully explicit, and reproducible from logs. Anything you cannot reconstruct from your logs is a parameter you will eventually regret adding.

Handling Timeouts and Concurrency

Because imagen-4.0-fast keeps generation time short, most reliability problems are client-side: timeouts set too low, retries that fire when they shouldn't, or too much parallelism against an account-level limit.

Timeouts

Set two numbers, not one. A short connect timeout catches network and DNS problems quickly; a longer read timeout accommodates generation plus transfer. Choose the read timeout from observed p95 latency in your environment with headroom, not from a guess. Retrying a request that timed out while the server was still working wastes capacity — so if you do retry, treat it as a new attempt with its own budget rather than assuming the first one was free.

Retries

Retry only what is safe to retry: connection errors and 5xx responses. Never retry a 4xx — a malformed payload will fail identically every time. Use exponential backoff with jitter, and cap the total number of attempts. A useful structure is three attempts with delays of roughly 1s, 2s, and 4s plus randomization, which spreads load when many clients fail simultaneously.

Concurrency

For batch work, use a bounded worker pool rather than unbounded asyncio.gather. Each in-flight request holds a connection and consumes your account's rate budget. Start with a small pool — a handful of concurrent requests — measure throughput, and increase until latency stops improving or you begin seeing 429s. The fast tier's short generations make their own case here: because each request finishes quickly, a modest pool sustains high throughput without long-lived open connections.

Backpressure

When you receive a 429, the correct response is to slow down, not to retry immediately. Add a short delay informed by the backoff pattern above, and consider temporarily reducing pool size. Log the concurrency level at the time of the 429 — that number is your practical ceiling.

Debugging Common Request Failures

Work through failures in the order that eliminates the most uncertainty per step: reproduce with curl first, then move into your client.

401 Unauthorized

The key is missing, malformed, or not sent as a Bearer token. Check the Authorization header directly, confirm the environment variable is populated in the exact process making the call (containers and CI runners differ from your shell), and verify there are no stray quotes or trailing whitespace around the value. If curl works with a literal key but your app fails, the problem is definitely environment loading.

400 Bad Request

A malformed payload or an invalid parameter value. Reproduce with the exact JSON your client sent — log the serialized payload, not your in-memory dict — and compare it against the working curl example. Frequent causes: Content-Type missing, model misspelled, a numeric field sent as a string, and leftover fields from an earlier API shape.

422 / validation errors

Fields are present but outside permitted bounds — typically n or size set to a value the model does not accept. Reduce the payload to the minimum required fields, confirm it succeeds, then add parameters back one at a time.

429 Rate limited or quota exhausted

You are sending more requests, or more concurrent requests, than your account allows. Confirm with your concurrency logs, reduce pool size, and confirm the backoff pattern is actually being applied. If it persists at low volume, check whether other processes share the same key.

5xx and timeouts

Server-side or network. Retry with backoff once or twice; if the failure is repeatable for a specific payload, capture the request ID from response headers and the exact payload — that is what makes escalation productive.

A general habit

Keep a --verbose curl reproduction for every production failure. Getting from an application error to a single copy-pasteable curl command shrinks the debugging surface to the request itself. From there, imagen-4.0-fast through the HiAPI API behaves predictably.

Related articles

View all articles →

Start building with persistent AI artifacts

Get your API key and call image, video and audio models through one task-based API.

Read the API docs