PiAPI
PiAPI is a unified async-task gateway for many third-party generative models.
Every media request goes through one envelope:
POST /api/v1/task
{
"model": "<vendor-or-family>",
"task_type": "<task>",
"input": { ... },
"config": { "service_mode": "public", "webhook_config": { ... } }
}
Polling and result fetching are uniform via GET /api/v1/task/{task_id}. The
LLM API at POST /v1/chat/completions is the only synchronous surface and is
OpenAI-compatible (including streaming).
When to use
- Generate images (Midjourney, Flux, Gemini Nano Banana).
- Generate video (Kling, Luma, Hailuo, Veo 3, Seedance, Hunyuan).
- Generate music (Suno, Udio via
music-u, MMAudio for sfx).
- TTS / voice (F5-TTS).
- 3D assets (Trellis).
- Faceswap (
Qubico/image-toolkit, Qubico/video-toolkit).
- LLM chat completions (any model exposed under PiAPI's OpenAI proxy).
- Webhook handlers that consume PiAPI callbacks.
When NOT to use
- The user wants direct vendor access (use the vendor's own API/SDK).
- The user wants WaveSpeedAI, Replicate, or fal.ai — different platforms.
- The user only needs ChatGPT/Claude prompt completion with no media generation
and you already have a direct API for that LLM.
Prereqs
export PIAPI_API_KEY="pk-..." # required, sent as x-api-key header
export PIAPI_WEBHOOK_SECRET="..." # only when verifying inbound webhooks
The shim piapi-cli runs the bundled Python in its own venv at
~/.local/share/piapi-skill/venv. Do not pip-install piapi — there is no
official SDK; the CLI uses pure requests.
Quick reference
Image — Midjourney imagine
piapi-cli imagine \
"ultrarealistic mediterranean coast, sunset" \
--aspect-ratio 16:9 --process-mode fast --wait
Image — Flux text-to-image
piapi-cli flux \
--prompt "neon-lit cyberpunk alley, rain reflections" \
--model Qubico/flux1-schnell --width 1024 --height 1024 --wait
Video — Kling image-to-video
piapi-cli kling \
--image-url https://example.com/in.jpg \
--prompt "camera dolly forward, soft cinematic" \
--duration 5 --aspect-ratio 16:9 --wait
Music — Suno
piapi-cli suno \
--prompt "warm lo-fi hip hop, vinyl crackle, mellow" \
--custom-mode false --make-instrumental false --wait
Faceswap — single image
piapi-cli faceswap \
--target-url https://example.com/target.jpg \
--swap-url https://example.com/face.jpg \
--wait
Generic submit / wait / cancel
piapi-cli submit --model midjourney --task-type imagine \
--input '{"prompt":"a samurai cat","aspect_ratio":"3:2","process_mode":"fast"}' \
--webhook-url https://yourapp/api/piapi --webhook-secret "$PIAPI_WEBHOOK_SECRET"
piapi-cli result <task_id>
piapi-cli wait <task_id> --timeout 1800 --poll-interval 2
piapi-cli cancel <task_id> # only valid while status is pending
One-shot run (submit + wait)
piapi-cli run --model Qubico/flux1-schnell --task-type txt2img \
--input '{"prompt":"misty forest","width":1024,"height":1024}'
LLM chat completion
piapi-cli llm --model gpt-4o-mini \
--message 'system:You are concise.' \
--message 'user:Summarize Stoicism in one sentence.'
piapi-cli llm --model claude-3-5-sonnet --stream --message 'user:Hi'
Verify a webhook
piapi-cli verify-webhook \
--header-secret "$X_WEBHOOK_SECRET_FROM_REQUEST" \
--expected "$PIAPI_WEBHOOK_SECRET"
REST primitives
| Method |
Path |
Purpose |
POST |
/api/v1/task |
Submit any media job. Returns task_id. |
GET |
/api/v1/task/{task_id} |
Poll status + fetch output URLs. |
DELETE |
/api/v1/task/{task_id} |
Cancel — only if status is pending. |
POST |
/v1/chat/completions |
OpenAI-compatible LLM (sync, supports SSE). |
Auth header (lowercase canonical):
x-api-key: <PIAPI_API_KEY>
Status enum drift (important)
Different model families return different status casing. The CLI normalizes
every status to lowercase before comparing:
- Capitalized family (Midjourney, Kling, Faceswap):
Pending | Processing | Staged | Completed | Failed
- Lowercase family (Flux, Veo 3, Gemini, Suno):
pending | starting | processing | success | failed | retry
Treat as terminal-success: completed | complete | success | succeeded.
Treat as terminal-failure: failed | failure | error | canceled | cancelled | rejected. Anything else = still running, keep polling.
Service modes
public — Pay-Per-Use (PPU). Default. Concurrency capped per pricing tier.
private — Host-Your-Account (HYA). Required for Midjourney private mode
(Discord token + channel ID + guild ID). Higher upfront commit, no
per-image PPU charge after the seat fee.
Set via --public / --private on submit and run, or include
{"config":{"service_mode":"private"}} in raw payloads.
Frequently-used model · task_type
| Family |
model |
task_type |
| Midjourney |
midjourney |
imagine, upscale, variation, inpaint, describe, blend |
| Flux |
Qubico/flux1-schnell, Qubico/flux1-dev, Qubico/flux1-dev-advanced |
txt2img, img2img, inpaint, controlnet-lora, redux-variation |
| Kling |
kling |
text2video, image2video, extend, lipsync, effects |
| Luma |
luma |
text2video, image2video, extend |
| Hailuo |
hailuo |
text2video, image2video, subject2video |
| Veo 3 |
veo3 |
txt2vid, img2vid |
| Suno |
music-u |
generate_music, generate_music_custom, extend, concat, add_lyrics |
| MMAudio |
Qubico/mmaudio |
video2audio |
| Hunyuan |
Qubico/hunyuan |
txt2video-lora, img2video-lora |
| Faceswap |
Qubico/image-toolkit, Qubico/video-toolkit |
face-swap, multi-face-swap |
| Trellis |
Qubico/trellis |
image-to-3d |
| F5-TTS |
Qubico/f5-tts |
txt2speech |
| Gemini Image |
gemini |
nano-banana-text-to-image, nano-banana-edit |
| Seedance |
seedance |
text-to-video, image-to-video |
Latency knobs
- Midjourney:
process_mode = fast | turbo | relax. fast is the default
rate; turbo costs more but is roughly half the wait; relax is cheapest
but can sit minutes in queue.
- Flux:
flux1-schnell ≈ 4 steps, fastest; flux1-dev ≈ 28 steps, higher
quality.
- Kling:
mode = std | pro and duration = 5 | 10 seconds.
- Suno:
custom_mode = true lets you pin lyrics + style; otherwise PiAPI
fills both.
Error surface
400 — bad input shape. Check model + task_type combo first; many
failures are wrong task_type for the family.
401 — missing or invalid x-api-key.
402 — out of credits or no active plan.
429 — concurrency cap or RPM cap exceeded for the tier.
500 / 502 — upstream model error. Retry with backoff; PiAPI returns
retry status for transient cases.
Tier rate limits (snapshot, verify in pricing page)
| Tier |
Concurrency |
Notes |
| Free |
1 |
Limited credits, no Hunyuan. |
| Creator |
5 |
Most families. |
| Pro |
30 |
All families, higher RPM. |
| Enterprise |
90+ |
Custom; Hunyuan has no per-tier cap. |
References
1---2name: piapi-23description: Use this skill when the user asks for image, video, music, 3D, audio, or LLM generation backed by the PiAPI inference platform (https://piapi.ai). Covers Midjourney, Suno, Kling, Luma, Hailuo, Flux, Hunyuan, Faceswap, Trellis, MMAudio, F5-TTS, Veo 3, Gemini 2.5 Flash Image, and Seedance via a single unified `POST /api/v1/task` envelope. The CLI also wraps the OpenAI- compatible `POST /v1/chat/completions` LLM surface.4---56# PiAPI78PiAPI is a unified async-task gateway for many third-party generative models.9Every media request goes through one envelope:1011```12POST /api/v1/task13{14 "model": "<vendor-or-family>",15 "task_type": "<task>",16 "input": { ... },17 "config": { "service_mode": "public", "webhook_config": { ... } }18}19```2021Polling and result fetching are uniform via `GET /api/v1/task/{task_id}`. The22LLM API at `POST /v1/chat/completions` is the only synchronous surface and is23OpenAI-compatible (including streaming).2425## When to use2627- Generate images (Midjourney, Flux, Gemini Nano Banana).28- Generate video (Kling, Luma, Hailuo, Veo 3, Seedance, Hunyuan).29- Generate music (Suno, Udio via `music-u`, MMAudio for sfx).30- TTS / voice (F5-TTS).31- 3D assets (Trellis).32- Faceswap (`Qubico/image-toolkit`, `Qubico/video-toolkit`).33- LLM chat completions (any model exposed under PiAPI's OpenAI proxy).34- Webhook handlers that consume PiAPI callbacks.3536## When NOT to use3738- The user wants direct vendor access (use the vendor's own API/SDK).39- The user wants WaveSpeedAI, Replicate, or fal.ai — different platforms.40- The user only needs ChatGPT/Claude prompt completion with no media generation41 and you already have a direct API for that LLM.4243## Prereqs4445```bash46export PIAPI_API_KEY="pk-..." # required, sent as x-api-key header47export PIAPI_WEBHOOK_SECRET="..." # only when verifying inbound webhooks48```4950The shim `piapi-cli` runs the bundled Python in its own venv at51`~/.local/share/piapi-skill/venv`. Do not pip-install `piapi` — there is no52official SDK; the CLI uses pure `requests`.5354## Quick reference5556### Image — Midjourney imagine5758```bash59piapi-cli imagine \60 "ultrarealistic mediterranean coast, sunset" \61 --aspect-ratio 16:9 --process-mode fast --wait62```6364### Image — Flux text-to-image6566```bash67piapi-cli flux \68 --prompt "neon-lit cyberpunk alley, rain reflections" \69 --model Qubico/flux1-schnell --width 1024 --height 1024 --wait70```7172### Video — Kling image-to-video7374```bash75piapi-cli kling \76 --image-url https://example.com/in.jpg \77 --prompt "camera dolly forward, soft cinematic" \78 --duration 5 --aspect-ratio 16:9 --wait79```8081### Music — Suno8283```bash84piapi-cli suno \85 --prompt "warm lo-fi hip hop, vinyl crackle, mellow" \86 --custom-mode false --make-instrumental false --wait87```8889### Faceswap — single image9091```bash92piapi-cli faceswap \93 --target-url https://example.com/target.jpg \94 --swap-url https://example.com/face.jpg \95 --wait96```9798### Generic submit / wait / cancel99100```bash101piapi-cli submit --model midjourney --task-type imagine \102 --input '{"prompt":"a samurai cat","aspect_ratio":"3:2","process_mode":"fast"}' \103 --webhook-url https://yourapp/api/piapi --webhook-secret "$PIAPI_WEBHOOK_SECRET"104105piapi-cli result <task_id>106piapi-cli wait <task_id> --timeout 1800 --poll-interval 2107piapi-cli cancel <task_id> # only valid while status is pending108```109110### One-shot run (submit + wait)111112```bash113piapi-cli run --model Qubico/flux1-schnell --task-type txt2img \114 --input '{"prompt":"misty forest","width":1024,"height":1024}'115```116117### LLM chat completion118119```bash120piapi-cli llm --model gpt-4o-mini \121 --message 'system:You are concise.' \122 --message 'user:Summarize Stoicism in one sentence.'123124piapi-cli llm --model claude-3-5-sonnet --stream --message 'user:Hi'125```126127### Verify a webhook128129```bash130piapi-cli verify-webhook \131 --header-secret "$X_WEBHOOK_SECRET_FROM_REQUEST" \132 --expected "$PIAPI_WEBHOOK_SECRET"133```134135## REST primitives136137| Method | Path | Purpose |138|---|---|---|139| `POST` | `/api/v1/task` | Submit any media job. Returns `task_id`. |140| `GET` | `/api/v1/task/{task_id}` | Poll status + fetch output URLs. |141| `DELETE` | `/api/v1/task/{task_id}` | Cancel — only if status is `pending`. |142| `POST` | `/v1/chat/completions` | OpenAI-compatible LLM (sync, supports SSE). |143144Auth header (lowercase canonical):145146```147x-api-key: <PIAPI_API_KEY>148```149150## Status enum drift (important)151152Different model families return different status casing. The CLI normalizes153every status to lowercase before comparing:154155- Capitalized family (Midjourney, Kling, Faceswap):156 `Pending | Processing | Staged | Completed | Failed`157- Lowercase family (Flux, Veo 3, Gemini, Suno):158 `pending | starting | processing | success | failed | retry`159160Treat as terminal-success: `completed | complete | success | succeeded`.161Treat as terminal-failure: `failed | failure | error | canceled | cancelled |162rejected`. Anything else = still running, keep polling.163164## Service modes165166- `public` — Pay-Per-Use (PPU). Default. Concurrency capped per pricing tier.167- `private` — Host-Your-Account (HYA). Required for Midjourney private mode168 (Discord token + channel ID + guild ID). Higher upfront commit, no169 per-image PPU charge after the seat fee.170171Set via `--public` / `--private` on `submit` and `run`, or include172`{"config":{"service_mode":"private"}}` in raw payloads.173174## Frequently-used model · task_type175176| Family | model | task_type |177|---|---|---|178| Midjourney | `midjourney` | `imagine`, `upscale`, `variation`, `inpaint`, `describe`, `blend` |179| Flux | `Qubico/flux1-schnell`, `Qubico/flux1-dev`, `Qubico/flux1-dev-advanced` | `txt2img`, `img2img`, `inpaint`, `controlnet-lora`, `redux-variation` |180| Kling | `kling` | `text2video`, `image2video`, `extend`, `lipsync`, `effects` |181| Luma | `luma` | `text2video`, `image2video`, `extend` |182| Hailuo | `hailuo` | `text2video`, `image2video`, `subject2video` |183| Veo 3 | `veo3` | `txt2vid`, `img2vid` |184| Suno | `music-u` | `generate_music`, `generate_music_custom`, `extend`, `concat`, `add_lyrics` |185| MMAudio | `Qubico/mmaudio` | `video2audio` |186| Hunyuan | `Qubico/hunyuan` | `txt2video-lora`, `img2video-lora` |187| Faceswap | `Qubico/image-toolkit`, `Qubico/video-toolkit` | `face-swap`, `multi-face-swap` |188| Trellis | `Qubico/trellis` | `image-to-3d` |189| F5-TTS | `Qubico/f5-tts` | `txt2speech` |190| Gemini Image | `gemini` | `nano-banana-text-to-image`, `nano-banana-edit` |191| Seedance | `seedance` | `text-to-video`, `image-to-video` |192193## Latency knobs194195- Midjourney: `process_mode = fast | turbo | relax`. `fast` is the default196 rate; `turbo` costs more but is roughly half the wait; `relax` is cheapest197 but can sit minutes in queue.198- Flux: `flux1-schnell` ≈ 4 steps, fastest; `flux1-dev` ≈ 28 steps, higher199 quality.200- Kling: `mode = std | pro` and `duration = 5 | 10` seconds.201- Suno: `custom_mode = true` lets you pin lyrics + style; otherwise PiAPI202 fills both.203204## Error surface205206- `400` — bad input shape. Check `model` + `task_type` combo first; many207 failures are wrong `task_type` for the family.208- `401` — missing or invalid `x-api-key`.209- `402` — out of credits or no active plan.210- `429` — concurrency cap or RPM cap exceeded for the tier.211- `500` / `502` — upstream model error. Retry with backoff; PiAPI returns212 `retry` status for transient cases.213214## Tier rate limits (snapshot, verify in pricing page)215216| Tier | Concurrency | Notes |217|---|---|---|218| Free | 1 | Limited credits, no Hunyuan. |219| Creator | 5 | Most families. |220| Pro | 30 | All families, higher RPM. |221| Enterprise | 90+ | Custom; Hunyuan has no per-tier cap. |222223## References224225- Overview & quickstart: https://piapi.ai/docs/overview226- Per-model docs: https://piapi.ai/docs/{midjourney,kling,suno,flux,faceswap,...}227- LLM API: https://piapi.ai/docs/llm-api228- MCP server: https://piapi.ai/docs/mcp-server229- Pricing: https://piapi.ai/pricing