HiAPI
  • Models
  • Pricing
Search

Search HiAPI models, tools, and resources.

  • 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
  • What you need
  • The request schema
  • Minimal working example (curl)
  • Python: create, poll, download
  • Production notes
  • Callbacks instead of polling
  • Idempotency
  • Error handling
  • Choosing the quality tier (and what about "consistency"?)
  • Related reading
  • FAQ
TutorialJul 11, 2026

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

hiapigrok-imagineimage-to-imagetutorialapi

Latest models

Explore models

Contents
  • What you need
  • The request schema
  • Minimal working example (curl)
  • Python: create, poll, download
  • Production notes
  • Callbacks instead of polling
  • Idempotency
  • Error handling
  • Choosing the quality tier (and what about "consistency"?)
  • Related reading
  • FAQ

Generate it with HiAPI

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

HiAPI Blog

Related articles

HiAPI

Generate it with HiAPI

This guide shows you how to transform an existing image with grok-imagine-quality/image-to-image — the higher-fidelity tier of the Grok Imagine family — through the hiapi unified tasks API. You'll submit a source image plus a text prompt, poll for the result, and download the generated image. Every request and response shape below was verified against the live API.

What you need

  • A hiapi API key — create one in your dashboard.
  • One to three publicly reachable image URLs to use as the source. The platform fetches and normalizes your input media server-side, so local file paths and base64 payloads won't work — host the image somewhere the API can reach it first.

That's it. No SDK required; the tasks API is plain HTTPS + JSON.

The request schema

grok-imagine-quality/image-to-image runs on the async tasks endpoint: you POST /v1/tasks to create a job, then poll GET /v1/tasks/<taskId> (or register a callback) until it finishes.

The input schema is strict — unknown fields are rejected with a 400:

FieldTypeRequiredNotes
promptstring✅What to do with the source image
image_urlsstring[]✅1–3 public URLs of source/reference images
aspect_ratiostring–One of auto, 2:1, 20:9, 19.5:9, 16:9, 4:3, 3:2, 1:1, 2:3, 3:4, 9:16, 9:19.5, 9:20, 1:2
resolutionstring–1k or 2k — lowercase (1K returns a 400)
output_formatstring–jpeg, png, or webp

Note what's not there: no size, no n, no seed, no strength or consistency knob. How closely the output tracks your source is controlled by your prompt and by which reference images you pass — see the FAQ below.

Minimal working example (curl)

Create the task:

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine-quality/image-to-image",
    "input": {
      "prompt": "Turn this product photo into a clean studio shot on a light gray background with soft shadows",
      "image_urls": ["https://your-cdn.example.com/source.jpg"],
      "aspect_ratio": "1:1",
      "resolution": "2k",
      "output_format": "png"
    }
  }'

A successful create returns a task id:

{
  "code": 200,
  "data": {
    "taskId": "task_xxxxxxxxxxxx"
  }
}

Poll until the task reaches a terminal state:

curl https://api.hiapi.ai/v1/tasks/task_xxxxxxxxxxxx \
  -H "Authorization: Bearer sk-<your-key>"

While running, data.status is in progress; on completion it becomes success and the image lands in data.output:

{
  "code": 200,
  "data": {
    "taskId": "task_xxxxxxxxxxxx",
    "status": "success",
    "output": [
      {
        "url": "https://.../result.png?...&expireAt=...",
        "expireAt": 1760000000
      }
    ]
  }
}

⚠️ The output URL is temporary (note expireAt). Download the bytes and store them on your own storage as soon as the task succeeds — don't hotlink the result URL.

If the task fails, data.status is fail and data.error carries code and message.

Python: create, poll, download

A complete script using only requests:

import time
import requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
API_KEY = "sk-<your-key>"

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

def create_task(prompt: str, image_urls: list[str]) -> str:
    payload = {
        "model": "grok-imagine-quality/image-to-image",
        "input": {
            "prompt": prompt,
            "image_urls": image_urls,   # 1-3 public URLs
            "aspect_ratio": "1:1",
            "resolution": "2k",         # lowercase: "1k" or "2k"
            "output_format": "png",
        },
    }
    r = requests.post(API_BASE, headers=HEADERS, json=payload, timeout=60)
    data = r.json()
    task_id = (data.get("data") or {}).get("taskId")
    if not task_id:
        raise RuntimeError(f"create failed: {data}")
    return task_id

def wait_task(task_id: str, timeout_s: int = 600, poll_interval: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(poll_interval)
    raise TimeoutError(f"task {task_id} still running after {timeout_s}s")

if __name__ == "__main__":
    task_id = create_task(
        prompt="Turn this product photo into a clean studio shot on a light gray background",
        image_urls=["https://your-cdn.example.com/source.jpg"],
    )
    print("task:", task_id)

    task = wait_task(task_id)
    url = task["output"][0]["url"]

    # The output URL expires -- download immediately and persist yourself
    img = requests.get(url, timeout=120).content
    with open("result.png", "wb") as f:
        f.write(img)
    print(f"saved result.png ({len(img)} bytes)")

Production notes

Callbacks instead of polling

For anything beyond a one-off script, register a callback and skip the poll loop. Add a top-level callback object (sibling of model and input):

{
  "model": "grok-imagine-quality/image-to-image",
  "input": { "...": "..." },
  "callback": {
    "url": "https://your-app.example.com/hooks/hiapi",
    "when": "final"
  }
}

when only supports "final" — you get exactly one POST when the task reaches a terminal state (success or fail). Rules of thumb:

  • Polling is fine for CLIs, notebooks, and batch jobs where the process stays alive anyway. Poll every 3–5 seconds; don't hammer sub-second intervals.
  • Callbacks are better for web backends: no held connections, no worker occupied for the duration of generation. Verify the payload by re-fetching GET /v1/tasks/<taskId> server-side rather than trusting the webhook body blindly.

Idempotency

Task creation is not idempotent by itself — if your process crashes after POST /v1/tasks but before persisting the taskId, retrying creates (and bills) a second task. Persist the taskId to your own store before you start waiting, keyed by your internal job id, and on restart resume by polling the stored taskId instead of re-creating.

Error handling

The errors you'll actually hit:

  • 401 permission_denied — the API key is invalid or doesn't have access to this model. The body includes a request_id you can send to support:

    {
      "error": {
        "code": "permission_denied",
        "message": "This API key cannot use the selected model. ...",
        "request_id": "2026...",
        "type": "hiapi_error"
      }
    }
    
  • 400 INVALID_REQUEST — schema violations, with a precise message. Real examples from this model:

    • prompt: missing required field "prompt" — you forgot a required field.
    • image_urls: maxItems: got 12, want 3 — too many reference images (max 3).
    • resolution: value must be one of '1k', '2k' — you sent 1K/4K.
    • additional properties 'seed' not allowed — you passed a field this model doesn't accept.
  • Terminal fail status — the task was accepted but generation failed (e.g. the source URL wasn't fetchable). Check data.error.message, fix the input, and create a new task.

Retry 5xx and network errors with backoff; don't retry 400s — they'll fail identically until you fix the payload.

Choosing the quality tier (and what about "consistency"?)

The Grok Imagine family on hiapi ships as separate model ids per tier and modality. For image-to-image you can pick:

  • grok-imagine-quality/image-to-image — the higher-fidelity tier covered here; slower, better detail retention.
  • grok-imagine/image-to-image — the standard tier; same request schema, faster and cheaper per image.

The tier is the model id — there is no quality parameter inside input (sending one returns 400 additional properties 'quality' not allowed). Per-image pricing for both tiers is on the pricing page.

Related reading

  • grok-imagine-quality/image-to-image model page — playground and pricing
  • How to use grok-imagine/text-to-image — generate the source image from scratch first
  • How to use grok-imagine/image-to-video — animate your result
  • hiapi docs — auth, tasks API, and the rest of the platform

FAQ

Is there a consistency or strength parameter? No. The input schema accepts only prompt, image_urls, aspect_ratio, resolution, and output_format; anything else is rejected with a 400. To control how closely the output follows the source, be explicit in the prompt about what must be preserved ("keep the product and label identical, change only the background") and pass up to 3 reference images via image_urls.

Can I upload a local file or send base64? Not directly — image_urls takes URLs, and the platform fetches them server-side. Upload the file to any publicly reachable storage (S3, R2, a CDN) and pass that URL.

How many source images can I pass? Between 1 and 3. An empty array fails with minItems: got 0, want 1; more than 3 fails with maxItems.

What resolutions and aspect ratios are supported? resolution is 1k or 2k (lowercase only). aspect_ratio supports 14 values from 2:1 to 1:2, including auto, 16:9, 1:1, 9:16, and phone-friendly 9:19.5/9:20.

How long do output URLs stay valid? Each output carries an expireAt timestamp. Treat results as ephemeral: download the bytes as soon as the task succeeds and store them yourself.

How do I generate multiple variations? There's no n parameter — create one task per variation. Tasks run independently, so you can submit several in parallel.

What does a 401 permission_denied mean if my key is correct? The key exists but can't use this model (plan or permission scope). Check the key's model permissions in your dashboard, or contact support with the request_id from the error body.

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