Introduction
/v1/tasks is the single entry point for all async generation models — image, video, and audio. Whatever the model, you submit, poll, and receive terminal callbacks through the same set of endpoints: submitting returns a taskId, then you poll the task detail or wait for a callback to get the final output.
API overview
Section titled “API overview”All requests use the same Base URL:
https://api.hiapi.ai| Method | Path | Purpose |
|---|---|---|
POST | /v1/tasks | Create a task, returns taskId |
GET | /v1/tasks | List tasks (paginated, newest first) |
GET | /v1/tasks/:id | Get task detail: status, output, or failure reason |
Authentication
Section titled “Authentication”Every request carries the account API key in the Authorization header:
Authorization Bearer YOUR_API_KEY required Account API key. Required on every request.
Content-Type application/json required The request body is JSON.
A task must belong to the API key’s account; cross-account queries return 404.
Model and parameters
Section titled “Model and parameters”Set the HiAPI model name via model, and put business parameters in the input object. The fields of input are defined per model — see the relevant model page.
Callbacks
Section titled “Callbacks”Async tasks support two ways to get results:
- Polling — after creating a task, request
GET /v1/tasks/:idat intervals untilstatusis terminal. - Callback (Webhook) — provide
callback.urlwhen creating the task, and HiAPIPOSTs to that URL when the task reaches a terminal state (successorfail).
The callback request:
- Method
POST, Content-Typeapplication/json - Body is identical to the
datafield ofGET /v1/tasks/:id(the task detail object) callback.whencurrently supports onlyfinal(bothsuccessandfailfire a callback)
Signature (optional, recommended)
Section titled “Signature (optional, recommended)”Set a “Webhook signing key” on the account settings page in the HiAPI console (shared secret, 16–256 chars; empty means no signing).
- Not set: callback requests carry no signature header.
- Set: each callback carries
X-HiAPI-Timestamp: Unix seconds (string)X-HiAPI-Signature:hex( HMAC_SHA256(secret, timestamp + "." + body) )
Receiver verification (Python pseudocode):
import hmac, hashlib
ts = request.headers["X-HiAPI-Timestamp"]sig = request.headers["X-HiAPI-Signature"]body = request.raw_body # raw bytes, not JSON-parsed
expected = hmac.new( secret.encode(), (ts + "." + body).encode(), hashlib.sha256,).hexdigest()
assert hmac.compare_digest(expected, sig), "bad signature"# Recommended: reject requests where abs(now - int(ts)) > 5 minutes (replay protection)Retries and idempotency
Section titled “Retries and idempotency”| Item | Behavior |
|---|---|
| Enqueue | Once, when the task reaches success or fail |
| Success | Receiver returns HTTP 2xx |
| Retry | Non-2xx / timeout / network error retries at immediately → +1 min → +5 min → +20 min, up to 4 attempts |
| Terminal | After 4 failed attempts no more retries; does not affect the task’s own state |
Terminal callbacks are delivered “at least once”, not “exactly once”. Deduplicate by taskId on your side.
Status codes
Section titled “Status codes”Task status enum
Section titled “Task status enum”| status | Meaning | Returns output? |
|---|---|---|
queued | Enqueued, not started | No |
handling | Processing | No |
archiving | Done, output being prepared | No |
success | Terminal: complete, output available | Yes |
fail | Terminal: failed | No, returns error |
The only terminal states are success / fail; they never convert to each other, and a taskId’s result is fixed once terminal.
HTTP status codes
Section titled “HTTP status codes”| Status | Meaning |
|---|---|
200 | Success (task detail returns 200 even when status=fail; the failure is in the body’s error) |
400 | Invalid request — see error_code below |
404 | Task does not exist or does not belong to the current account |
503 | Platform temporarily unavailable; retry later with exponential backoff |
Business error codes
Section titled “Business error codes”The synchronous failure response of POST /v1/tasks (error_code) and a terminal task’s error.code share this enum:
| code | Meaning | What to do |
|---|---|---|
INVALID_REQUEST | Invalid body (missing field / wrong type / bad callback.url / model rejects the input) | Fix the request; do not retry the same request |
MODEL_UNAVAILABLE | Model unavailable (disabled, no permission, temporarily unavailable) | Retry shortly, or switch models |
TASK_FAILED | Task failed | Retry once; contact support if persistent |
TASK_TIMEOUT | Task timed out | Retryable |
STORAGE_UNAVAILABLE | Output storage error | Retryable; contact support if persistent |
Failure responses look like:
{ "code": 400, "message": "invalid request", "data": null, "error_code": "INVALID_REQUEST"}State machine
Section titled “State machine” POST /v1/tasks ──► queued ──► handling ──► archiving ──► success (terminal) (200 / taskId) │ │ ▼ ▼ fail fail (terminal)
success / fail triggers the callback (if callback.url was set)