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 Omni

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
  • TL;DR
  • What you're building, and what you need
  • The request schema
  • Minimal working example: curl
  • Minimal working example: Python
  • Production notes
  • Related reading
  • FAQ
TutorialJul 11, 20268 min read

How to Use flux-2/image-to-image via the hiapi API: curl, Python, and a Working Request

Multi-Reference editing with the unified /v1/tasks interface — schema, code, and production notes

hiapiflux-2Image APIImage-to-ImageTutorial

Latest models

Explore models

Contents
  • TL;DR
  • What you're building, and what you need
  • The request schema
  • Minimal working example: curl
  • Minimal working example: Python
  • Production notes
  • 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

TL;DR

  • What this is: a working recipe for calling the flux-2/image-to-image API on hiapi — create a task, poll it, download the result.
  • Endpoint: POST https://api.hiapi.ai/v1/tasks with "model": "flux-2/image-to-image", then GET /v1/tasks/<taskId> until it reaches a terminal status.
  • Required input fields (all four): prompt, image_urls (1–8 public URLs — this is the Multi-Reference feature), aspect_ratio, and resolution (1K or 2K).
  • The schema is strict. Fields like strength or fidelity don't exist and are rejected with a 400. Fidelity is controlled by your reference images, your prompt, and resolution — not by a separate knob.

What you're building, and what you need

Goal: send one or more reference images plus a text prompt to flux-2, and get back an edited/restyled image you can download — from curl or Python, with no SDK.

Prerequisites:

  1. A hiapi API key — create one in the hiapi dashboard. Keys look like sk-... and go in the Authorization: Bearer header.
  2. At least one publicly reachable image URL to use as a reference. The API fetches image_urls server-side, so localhost links or private-bucket URLs won't work — use a public bucket, CDN, or presigned URL.
  3. curl, or Python 3.8+ with requests (pip install requests).

The request schema

flux-2/image-to-image runs on hiapi's unified task interface. The input object takes exactly these fields:

FieldTypeRequiredNotes
promptstringyesWhat to change or generate. Minimum 3 characters.
image_urlsstring[]yes1–8 public image URLs. More than one = Multi-Reference: flux-2 blends identity, product, or style cues across all of them.
aspect_ratiostringyesOne of 1:1, 4:3, 3:4, 16:9, 9:16, 3:2, 2:3, or auto (follow the reference image).
resolutionstringyes1K or 2K.

Anything else is rejected. For example, sending a strength or fidelity field returns:

{
  "code": 400,
  "error_code": "INVALID_REQUEST",
  "message": "invalid input: <root>: additional properties 'fidelity', 'strength' not allowed"
}

That's worth internalizing: flux-2's image-to-image mode has no denoise-strength dial. How faithful the output stays to your references ("high fidelity" editing vs. loose restyling) is driven by how you write the prompt — e.g. "keep the product, its label and proportions exactly as in the reference; only replace the background" — plus resolution: "2K" for detail-critical work.

Minimal working example: curl

Step 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": "flux-2/image-to-image",
    "input": {
      "prompt": "Place this product on a white marble countertop with soft morning light, keep the product itself unchanged",
      "image_urls": ["https://your-cdn.example.com/product.jpg"],
      "aspect_ratio": "1:1",
      "resolution": "2K"
    }
  }'

A successful create returns a task ID in data.taskId.

Step 2 — poll until it finishes:

curl -s https://api.hiapi.ai/v1/tasks/TASK_ID \
  -H "Authorization: Bearer sk-YOUR_KEY"

Keep polling every few seconds while data.status is non-terminal. On "status": "success", the image URL is at data.output[0].url.

Step 3 — download the result immediately:

curl -s -o result.jpg "OUTPUT_URL"

Output URLs carry an expireAt timestamp — they are temporary. Download the bytes (or copy them to your own storage) as soon as the task succeeds; don't hot-link the task output in production.

Minimal working example: Python

A complete script — create, poll, download — with nothing but requests:

import time
import requests

API_KEY = "sk-YOUR_KEY"
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

def create_task() -> str:
    resp = requests.post(BASE, headers=HEADERS, json={
        "model": "flux-2/image-to-image",
        "input": {
            "prompt": ("Combine the person from the first image with the jacket "
                       "from the second image, studio lighting, neutral backdrop"),
            "image_urls": [
                "https://your-cdn.example.com/person.jpg",
                "https://your-cdn.example.com/jacket.jpg",
            ],
            "aspect_ratio": "3:4",
            "resolution": "2K",
        },
    }, timeout=30)
    body = resp.json()
    task_id = (body.get("data") or {}).get("taskId")
    if not task_id:
        raise RuntimeError(f"create failed: {body}")
    return task_id

def wait_task(task_id: str, timeout_s: int = 600, poll_s: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        task = requests.get(f"{BASE}/{task_id}", headers=HEADERS,
                            timeout=30).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_s)
    raise TimeoutError(f"task {task_id} still running after {timeout_s}s")

task_id = create_task()
print("task:", task_id)
task = wait_task(task_id)
url = task["output"][0]["url"]          # temporary URL — save it now
img = requests.get(url, timeout=120).content
with open("result.jpg", "wb") as f:
    f.write(img)
print("saved result.jpg,", len(img), "bytes")

Note the two-image image_urls — that's Multi-Reference in practice. Up to 8 references are accepted; the model composes across them (person + garment, product + background style, character + pose reference, and so on).

Production notes

Callbacks instead of polling. For anything beyond a script, register a callback when you create the task so hiapi pushes the terminal result to you:

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

With "when": "final" you get exactly one POST when the task reaches a terminal state. Rule of thumb: polling is fine for CLIs, batch jobs, and anything short-lived; callbacks are better for user-facing apps where a worker holding a poll loop per image doesn't scale. If you can't expose a public callback endpoint, poll — just back off to 5s+ intervals.

Make retries safe. Treat task creation as the side effect it is: store the returned taskId against your own job record before acting on the result, and on retry, re-check the stored task's status instead of blindly creating a new task (each successful create bills separately). If your job runner may fire twice, dedupe on your own job ID first.

Handle the errors you'll actually see:

  • 401 permission_denied — bad key, or the key lacks access to this model. The body looks like:

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

    Check the key in your dashboard; our invalid API key checklist covers the usual causes.

  • 400 INVALID_REQUEST — schema violation. The message names every offending field at once (missing required fields, bad enum values, unknown extras), so read it fully rather than fixing one field per retry.

  • Task status: "fail" — the task was accepted but generation failed; the error is inside data.error. Handle it in your poll/callback path, not at create time.

  • Expired output URL — if a download 4xx's minutes after success, you waited too long. Re-check expireAt and always download immediately.

Related reading

  • flux-2/image-to-image model page — parameters and current pricing
  • flux-2/text-to-image model page — same family, no reference images
  • flux-2 for e-commerce product images — an end-to-end recipe built on the text-to-image side
  • FLUX 1.1 Pro on hiapi — the previous-generation option compared
  • hiapi pricing — per-image cost across resolutions

FAQ

How many reference images can I pass to flux-2 image-to-image? Between 1 and 8, as public URLs in image_urls. Passing more than 8 fails validation (maxItems: got N, want 8).

Is there a strength or fidelity parameter? No. The input schema accepts only prompt, image_urls, aspect_ratio, and resolution; unknown fields are rejected with a 400. Control fidelity through prompt phrasing (state explicitly what must stay unchanged) and use 2K when detail matters.

What resolutions and aspect ratios are supported? resolution is 1K or 2K. aspect_ratio is one of 1:1, 4:3, 3:4, 16:9, 9:16, 3:2, 2:3, or auto — auto follows your reference image, which is usually what you want for edits.

Can I send base64 images instead of URLs? No — image_urls takes URLs, and they must be publicly reachable so the API can fetch them. Upload to a bucket or CDN first and pass the resulting URL (presigned URLs work).

How much does flux-2 image-to-image cost per image? Pricing varies by resolution — check the flux-2/image-to-image model page and the pricing page for current per-image rates.

How long do generated image URLs stay valid? Output URLs are temporary and include an expireAt field. Download the image bytes as soon as the task succeeds and store them yourself.

What's the difference between flux-2/image-to-image and flux-2/text-to-image? Same model family, different modes: text-to-image generates from a prompt alone, while image-to-image requires 1–8 reference images and edits or composes from them. Their input schemas differ, so the request bodies aren't interchangeable.

Latest models

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

Explore models

TextImageVideoAudio
Back to blog
GPT Image 2From $0.030/image
Nano Banana 2From $0.051/image
Seedream 5.0 ProFrom $0.050/image
Seedance 2.5From $0.231/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