---
name: 18models-api
description: Integrate the 18MODELS.AI generation API (34 image/video models — Wan, Qwen, HappyHorse, Seedance, Z-Image — behind one async endpoint). Use when the user mentions 18models, 18api, api.18models.ai, api.18api.ai, a model id such as wan2.7-t2v-uncensored / seedance-2.5-* / qwen-image3-*, or wants to generate images or videos through the 18MODELS API. Covers auth, request contract, polling, pricing, error handling and provider input policies.
---

# 18MODELS.AI generation API

Generated from the canonical API contract on 2026-08-19. Source of truth: https://18models.ai/docs (Markdown: https://18models.ai/llms-full.txt).
Do not invent parameters — every accepted field per model is listed in [references/models.md](references/models.md).

## Quick facts

- Base URL: `https://api.18models.ai`
- Auth: `Authorization: Bearer sk-…` (API Key from the customer's dashboard). Never hard-code a key; read it from an env var such as `M18_API_KEY`.
- One async endpoint for everything: `POST /ent/v2/generate` → `202 {task_id, status, reserved_cost, sku_key}`; poll `GET /ent/v2/tasks/{task_id}` until `status` is `success` or `failed`.
- Always send a stable `Idempotency-Key` header (retrying with the same key returns the same task instead of creating a duplicate).
- Prices: `GET /ent/v2/prices` (effective per-key catalog). Cost is reserved at submit and settled at completion; failed tasks are refunded automatically.
- Results are returned as HTTPS URLs on `https://cdn.18models.ai/...` in `result_urls` (and `result_url` for the first one).
- Media inputs (`images[]`, `videos[]`, `audios[]`, `files[]`) must be public HTTP(S) URLs — base64 is not accepted.
- `params.prompt_extend` and `params.watermark` default to `false` on every model that supports them; only send `true` if the user explicitly wants it.

## Request shape

```json
{
  "model": "wan2.7-i2v-firstframe-uncensored",
  "prompt": "A cinematic tracking shot at sunset",
  "negative_prompt": "",
  "images": ["https://cdn.example.com/first-frame.jpg"],
  "params": { "resolution": "1080p", "duration": 5 }
}
```

- `model` is required and must be one of the 34 canonical ids below.
- Model parameters live under `params` using their real names (`params.resolution`, `params.ratio`, `params.duration`, …).
- Send only fields the model accepts (see the per-model table). Unknown fields are rejected with `400 invalid_request / unknown_parameter`.

## Workflow (do this in order)

1. Pick the model by task type (text→image, image edit, text→video, first-frame→video, first+last frame, reference→video, video edit, video extend). Look up its table in references/models.md and build `params` from **that** table only.
2. Optionally call `GET /ent/v2/prices` to show the estimated cost before submitting.
3. `POST /ent/v2/generate` with `Idempotency-Key`. Expect `202`. A `400` with `{"error":"invalid_request","code":"…","field":"…"}` means the request body violates the contract — fix the named field, do not retry blindly.
4. Poll `GET /ent/v2/tasks/{task_id}` with backoff (start ~2s, cap ~5s; images take seconds, videos 1–5 minutes). Stop on `success` or `failed`.
5. On `success` use `result_urls`. On `failed` show `error` to the user; the reservation is already refunded.

## Model families (34 models)

- **Wan 2.7 / 3.0**: `wan2.7-i2v-continuation-uncensored`, `wan2.7-i2v-firstframe-uncensored`, `wan2.7-i2v-firstlast-uncensored`, `wan2.7-image-edit-uncensored`, `wan2.7-image-grid-i2i-uncensored`, `wan2.7-image-grid-t2i-uncensored`, `wan2.7-image-inpaint-uncensored`, `wan2.7-image-t2i-uncensored`, `wan2.7-r2v-multiple-uncensored`, `wan2.7-r2v-storyboard-uncensored`, `wan2.7-t2v-uncensored`, `wan2.7-videoedit-replace-uncensored`, `wan2.7-videoedit-style-uncensored`, `wan3.0-video-document-uncensored`, `wan3.0-video-firstframe-uncensored`, `wan3.0-video-firstlast-uncensored`, `wan3.0-video-reference-uncensored`, `wan3.0-video-t2v-uncensored`
- **Qwen-Image 3**: `qwen-image3-edit-uncensored`, `qwen-image3-t2i-uncensored`
- **HappyHorse**: `happyhorse-1.0-i2v-uncensored`, `happyhorse-1.0-r2v-uncensored`, `happyhorse-1.0-t2v-uncensored`, `happyhorse-1.1-i2v-uncensored`, `happyhorse-1.1-r2v-uncensored`, `happyhorse-1.1-t2v-uncensored`, `happyhorse-videoedit-uncensored`
- **Seedance 2.5**: `seedance-2.5-edit-uncensored`, `seedance-2.5-extend-uncensored`, `seedance-2.5-firstframe-uncensored`, `seedance-2.5-firstlast-uncensored`, `seedance-2.5-reference-uncensored`, `seedance-2.5-t2v-uncensored`
- **Z-Image**: `z-image-turbo-uncensored`

## Provider input policies (will fail the task at submit)

- `seedance-2.5-edit-uncensored` and `seedance-2.5-extend-uncensored`: input `videos[]` must not contain real people (BytePlus rejects it with `InputVideoSensitiveContentDetected`). AI-generated or person-free footage is fine.
- Full list: [references/policies.md](references/policies.md).

## Errors

- `400 invalid_request` — contract violation; `code` + `field` tell you exactly what to fix (`missing_required_field`, `invalid_enum_value`, `unknown_parameter`, `out_of_range`, …).
- `401` — missing/invalid API key. `402` — insufficient balance for the reservation. `429` — rate limited, back off.
- Task `status: failed` — provider-side failure; `error` is human-readable and already refunded.

## References

- [references/models.md](references/models.md) — every model, every accepted field, ranges and defaults (authoritative).
- [references/pricing.md](references/pricing.md) — public base list prices per SKU.
- [references/examples.md](references/examples.md) — copy-paste curl / Python / TypeScript clients with polling.
- [references/policies.md](references/policies.md) — provider input policies and gotchas.
