HiAPI
  • Models
  • Pricing
Search

Search HiAPI models, tools, and resources.

LoginGet Started
  • Models
  • Pricing
HiAPI

One API, All AI Models

Generate images, video, and audio with leading models through one production-ready API.

Get a free API key

AI Image API

  • All image models
  • GPT Image 2
  • Nano Banana 2
  • Seedream 5.0 Pro
  • Qwen Image 2.0 Pro
  • FLUX 1.1 Pro

AI Video API

  • All video models
  • Seedance 2.5
  • FLUX.3 Video
  • Seedance 2.0
  • Veo 3.1
  • Kling 3.0

AI Audio API

  • All audio models
  • MiniMax Music 2.6
  • MiniMax Music 1.5
  • ElevenLabs v3
  • Text to music
  • Text to speech

Product

  • Model marketplace
  • Playground
  • Pricing
  • Image API Cost Calculator
  • Free GPT Image 2 Generator
  • Free Nano Banana Image Generator
  • Outfit Preview
  • Product Photo Lab

Developers

  • Documentation
  • API Reference
  • Agent Skills
  • LLM integration index
  • Blog

Company

  • About
  • Contact support
  • Terms of Service
  • Privacy Policy

© 2026 hiapi. All rights reserved.

Open source on GitHubPython SDK on PyPI
  • Prerequisites
  • Minimal working example (curl)
  • Python: create + poll + save to disk
  • Node.js: same flow with fetch
  • Parameter reference
  • Production-ready patterns
  • Use callbacks instead of polling
  • Make creates idempotent
  • Handle the auth error correctly
  • Download immediately, re-host yourself
  • Set sensible timeouts
  • FAQ
  • What's the difference between gpt-image-2 and gpt-image-2/text-to-image?
  • What does aspect_ratio: auto do?
  • Why does my request return HTTP 200 with permission_denied?
  • Can I generate multiple images in one request?
  • How do I cancel an in-flight task?
  • How do I switch to a different image model?
TutorialJun 25, 2026

How to use gpt-image-2/text-to-image via the hiapi API: parameters, code, and a working example

hiapiUpdated Jun 26, 2026image-generationtutorialgpt-image-2api-examples

Latest models

Explore models

Contents
  • Prerequisites
  • Minimal working example (curl)
  • Python: create + poll + save to disk
  • Node.js: same flow with fetch
  • Parameter reference
  • Production-ready patterns
  • Use callbacks instead of polling
  • Make creates idempotent
  • Handle the auth error correctly
  • Download immediately, re-host yourself
  • Set sensible timeouts
  • FAQ
  • What's the difference between gpt-image-2 and gpt-image-2/text-to-image?
  • What does aspect_ratio: auto do?
  • Why does my request return HTTP 200 with permission_denied?
  • Can I generate multiple images in one request?
  • How do I cancel an in-flight task?
  • How do I switch to a different image model?

Generate it with HiAPI

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

HiAPI Blog

Related articles

HiAPI

Generate it with HiAPI

This recipe shows the smallest amount of code you need to generate an image with gpt-image-2/text-to-image through the hiapi unified task API, then explains every parameter and the production-ready patterns (callbacks, idempotency, error handling) you should use once it works.

Prerequisites

You need an API key. Create one from the API Keys page in your hiapi dashboard — keys start with sk-. The model page at gpt-image-2/text-to-image lists current per-image pricing; the full breakdown is on the pricing page.

All calls in this guide hit the unified async task endpoint:

  • POST https://api.hiapi.ai/v1/tasks — create a generation task
  • GET https://api.hiapi.ai/v1/tasks/{taskId} — poll task status

The general reference for the platform lives in the hiapi API docs.

Minimal working example (curl)

A single generation is a two-step exchange: create the task, then wait for it to finish.

# 1. Create the task
curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2/text-to-image",
    "input": {
      "prompt": "a calico cat curled up on a sunlit windowsill, soft focus background",
      "aspect_ratio": "1:1",
      "resolution": "1K"
    }
  }'
# => {"code":200,"data":{"taskId":"tk-hiapi-01KVY...."},"message":"success"}

# 2. Poll until status == "success"
TASK_ID="tk-hiapi-01KVY...."
curl -s "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer sk-YOUR_KEY"
# => {"code":200,"data":{"status":"success","output":[{"url":"https://..."}], ...}}

The image URL is at data.output[0].url. Download it immediately — output[0].expireAt is short, so the URL is for fetching, not for permanently embedding.

Python: create + poll + save to disk

import os
import time
import urllib.request
import requests  # pip install requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_API_KEY"]  # sk-...

def create_task(prompt: str, aspect_ratio: str = "1:1", resolution: str = "1K") -> str:
    payload = {
        "model": "gpt-image-2/text-to-image",
        "input": {
            "prompt": prompt,
            "aspect_ratio": aspect_ratio,
            "resolution": resolution,
        },
    }
    r = requests.post(API_BASE, json=payload,
                      headers={"Authorization": f"Bearer {TOKEN}"},
                      timeout=60)
    r.raise_for_status()
    body = r.json()
    if body.get("error"):
        raise RuntimeError(f"create failed: {body['error']}")
    return body["data"]["taskId"]

def wait_task(task_id: str, timeout_s: int = 600, poll_s: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}",
                         headers={"Authorization": f"Bearer {TOKEN}"},
                         timeout=30)
        r.raise_for_status()
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            raise RuntimeError(f"task failed: {task.get('error')}")
        time.sleep(poll_s)
    raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")

if __name__ == "__main__":
    task_id = create_task(
        "a calico cat curled up on a sunlit windowsill, soft focus background",
        aspect_ratio="3:2",
        resolution="1K",
    )
    task = wait_task(task_id)
    url = task["output"][0]["url"]
    urllib.request.urlretrieve(url, "cat.png")
    print(f"saved cat.png from task {task_id}")

Node.js: same flow with fetch

// Node 18+ has global fetch
const API_BASE = "https://api.hiapi.ai/v1/tasks";
const TOKEN = process.env.HIAPI_API_KEY;

async function createTask(prompt, aspectRatio = "1:1", resolution = "1K") {
  const res = await fetch(API_BASE, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "gpt-image-2/text-to-image",
      input: { prompt, aspect_ratio: aspectRatio, resolution },
    }),
  });
  const body = await res.json();
  if (body.error) throw new Error(`create failed: ${body.error.code} ${body.error.message}`);
  return body.data.taskId;
}

async function waitTask(taskId, { timeoutMs = 600_000, pollMs = 5_000 } = {}) {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    const res = await fetch(`${API_BASE}/${taskId}`, {
      headers: { "Authorization": `Bearer ${TOKEN}` },
    });
    const task = (await res.json()).data || {};
    if (task.status === "success") return task;
    if (task.status === "fail") throw new Error(`task failed: ${JSON.stringify(task.error)}`);
    await new Promise(r => setTimeout(r, pollMs));
  }
  throw new Error(`task ${taskId} timed out`);
}

(async () => {
  const id = await createTask(
    "a calico cat curled up on a sunlit windowsill, soft focus background",
    "16:9",
    "1K",
  );
  const task = await waitTask(id);
  const url = task.output[0].url;
  const img = await fetch(url).then(r => r.arrayBuffer());
  const { writeFileSync } = await import("node:fs");
  writeFileSync("cat.png", Buffer.from(img));
  console.log(`saved cat.png from task ${id}`);
})();

Parameter reference

The request body always has two top-level fields: model (string, the bare model id gpt-image-2/text-to-image) and input (the per-model parameter object).

input fieldRequiredTypeNotes
promptYesstringThe text description of the image you want.
aspect_ratioYesstringOne of 1:1, 3:2, 2:3, 4:3, 3:4, 5:4, 4:5, 16:9, 9:16, 21:9, or auto.
resolutionNostring1K (default), 2K, or 4K. Pixel size scales with the chosen aspect ratio.
callbackNoobject{ "url": "https://yours.example/hook", "when": "final" } — see the next section.

A successful create returns {"code":200, "data":{"taskId":"tk-hiapi-..."}, "message":"success"}. A GET /v1/tasks/{taskId} returns data.status as one of handling, success, or fail; on success, data.output is an array whose first element has the url for the image and an expireAt timestamp.

Other hiapi image models (for example z-image, qwen-image) take slightly different input fields — aspect_ratio is the convention used by gpt-image-2/text-to-image. When you swap models, check the model page for the exact input schema.

Production-ready patterns

Use callbacks instead of polling

Polling every 5 seconds is fine for prototyping, but for production traffic you want hiapi to push the finished task to you so you can free the worker. Add a callback block to input:

{
  "model": "gpt-image-2/text-to-image",
  "input": {
    "prompt": "an astronaut sketching the moon",
    "aspect_ratio": "3:2",
    "resolution": "1K",
    "callback": {
      "url": "https://your-app.example.com/webhooks/hiapi",
      "when": "final"
    }
  }
}

when: "final" fires once when the task reaches a terminal state (success or fail). Your endpoint receives the same payload shape as GET /v1/tasks/{id}, so the handler can reuse the polling parser. Verify the taskId against the one you stored when you created the task so you know which request the callback belongs to.

Make creates idempotent

If your worker crashes after POST /v1/tasks but before storing the taskId, you can end up generating the same image twice. The cheap fix is to store (your_request_id → taskId) in your database the moment you receive the create response, in the same transaction that committed the request. If the worker retries, it finds the existing taskId and resumes polling instead of creating a new task.

Handle the auth error correctly

hiapi auth failures return HTTP 200 with the error payload embedded:

{"error":{"code":"permission_denied","message":"This API key cannot use the selected model. ...","type":"hiapi_error"}}

So a 200 status alone does not mean success. Always check body.error first; if it exists, look at error.code (permission_denied, invalid_request, etc.) and error.message. The request_id in the message is what you paste into a support ticket if you need help.

Download immediately, re-host yourself

data.output[0].url is a short-lived URL — the expireAt is in the response. Don't ship the hiapi URL into <img src> in your product; download the bytes as soon as the task succeeds, upload them to your own storage (S3, R2, Supabase Storage, etc.), and serve from there.

Set sensible timeouts

A reasonable default is a 60-second timeout on the POST (creating the task is fast — you're really just waiting for the API to acknowledge it) and a 10-minute total budget for the polling loop with a 5-second cadence. Tasks that take longer than 10 minutes almost always mean the task quietly went into fail, so timing out and surfacing the last task body in your logs is more useful than waiting indefinitely.

FAQ

What's the difference between gpt-image-2 and gpt-image-2/text-to-image?

gpt-image-2 is the model family; gpt-image-2/text-to-image is the specific endpoint you call to turn a text prompt into a new image. Other variants in the family expose different input schemas (for example, image edits accept reference images). When in doubt, use the bare model id you see on the model page.

What does aspect_ratio: auto do?

auto lets the model decide the aspect ratio from the prompt. Use it when you don't have a strong layout requirement; otherwise pin the ratio yourself so downstream cropping is predictable.

Why does my request return HTTP 200 with permission_denied?

Either the API key is wrong (typo, revoked, missing sk- prefix) or the key's plan doesn't include gpt-image-2/text-to-image. Open the API Keys dashboard, confirm the key string, and check your plan on the pricing page. Always check body.error.code — never trust the HTTP status alone.

Can I generate multiple images in one request?

gpt-image-2/text-to-image produces one image per task — data.output is an array, but for this model it always has length 1. To generate N variations, fire N tasks concurrently and use the callback pattern above so you don't keep N worker threads parked.

How do I cancel an in-flight task?

The unified task API does not currently expose a cancel endpoint. The simplest mitigation is to make your client-side worker drop the result if the user no longer wants it — you'll still be billed for the generation that already ran, so the right place to enforce cancellation is before the POST /v1/tasks call.

How do I switch to a different image model?

Change model to the new bare id (for example z-image/text-to-image) and adjust input to match that model's schema. Schemas are not identical across models — some accept size, some accept aspect_ratio, and a few do not accept resolution. The models catalog lists every available model with a per-model page that documents its input fields.

Latest models

View all models
  • GPT Image 2From $0.007/image
  • Nano Banana 2From $0.051/image
  • Seedream 5.0 ProFrom $0.050/image
  • Seedance 2.5From $0.121/s

Explore models

TextImageVideoAudio
Back to blog
GPT Image 2From $0.007/image
Nano Banana 2From $0.051/image
Seedream 5.0 ProFrom $0.050/image
Seedance 2.5From $0.121/s
View all models
TextChat and reasoning
ImageGenerate and edit
VideoText and image to video
AudioSpeech and music
Start generating
View model pricing
View all articles
How to Use the flux-3 API for Text-to-Video, Audio, and Continuation

How to Use the flux-3 API for Text-to-Video, Audio, and Continuation

minimax-music-3 API: curl & Python Guide

minimax-music-3 API: curl & Python Guide

How to use grok-imagine-image-2.0/image-to-image via the hiapi API: curl, Python, and a working request

How to use grok-imagine-image-2.0/image-to-image via the hiapi API: curl, Python, and a working request

How to Use grok-imagine-image-2.0/text-to-image via the hiapi API: curl, Python, and a Working Request

How to Use grok-imagine-image-2.0/text-to-image via the hiapi API: curl, Python, and a Working Request

How to Use the qwen-image-3.0 API: curl, Python, and a Working Request

How to Use the qwen-image-3.0 API: curl, Python, and a Working Request

How to Use qwen-image-3.0-pro via the hiapi API: curl, Python, and a Working Request

How to Use qwen-image-3.0-pro via the hiapi API: curl, Python, and a Working Request

Start generating