# Legnext AI — Complete Documentation > Unofficial Midjourney REST API for image and video generation — production-ready, no Discord or Midjourney account required. Base URL: `https://api.legnext.ai/api` Auth: `x-api-key` on submit and account requests; `GET /v1/job/{job_id}` uses its UUID as a private capability token Get a key: https://legnext.ai/dashboard Current pricing: https://legnext.ai/#pricing This file consolidates the authoritative Legnext API reference for coding agents. It intentionally excludes onboarding, integrations, and changelog prose. Human guidance comes first; the backend-generated OpenAPI contract is included in full at the end. Each section is delimited by `---` and prefixed with its source URL. --- # First API request _Submit an image task, wait for completion, and save the output._ This example runs a complete text-to-image request with Node.js 20 or newer. It submits one task, polls that same `job_id`, and saves the completed image. ## 1. Set your API key Create a key in the [Legnext dashboard](https://legnext.ai/dashboard), then add it to your server-side environment: ```bash export LEGNEXT_API_KEY="your-api-key" ``` ## 2. Run the example Save the following as `legnext-example.mjs`: ```javascript import { writeFile } from "node:fs/promises"; import { setTimeout as delay } from "node:timers/promises"; const baseUrl = "https://api.legnext.ai/api"; const apiKey = process.env.LEGNEXT_API_KEY; if (!apiKey) throw new Error("Set LEGNEXT_API_KEY before running this example"); async function readResponse(response) { const body = await response.json(); if (!response.ok) { throw new Error(body.error?.message || body.message || `HTTP ${response.status}`); } return body; } const submitted = await readResponse( await fetch(`${baseUrl}/v1/diffusion`, { method: "POST", headers: { "content-type": "application/json", "x-api-key": apiKey, }, body: JSON.stringify({ text: "A cinematic mountain observatory at sunrise --v 8.2 --ar 16:9", }), }), ); console.log(`Submitted ${submitted.job_id}`); let task = submitted; for (let attempt = 0; attempt < 120; attempt += 1) { if (task.status === "completed" || task.status === "failed") break; await delay(5_000); task = await readResponse( await fetch(`${baseUrl}/v1/job/${submitted.job_id}`), ); console.log(task.status); } if (task.status === "failed") { throw new Error(task.error?.message || task.error?.raw_message || "Task failed"); } if (task.status !== "completed") { throw new Error("Client timeout: task is still running"); } const outputUrl = task.output?.image_url || task.output?.image_urls?.[0]; if (!outputUrl) throw new Error("Completed task did not contain an image URL"); const imageResponse = await fetch(outputUrl); if (!imageResponse.ok) throw new Error(`Image download failed: ${imageResponse.status}`); await writeFile("legnext-output.png", Buffer.from(await imageResponse.arrayBuffer())); console.log("Saved legnext-output.png"); ``` Run it: ```bash node legnext-example.mjs ``` The ten-minute wait in this example is a client-side limit, not a service guarantee. In production, persist the `job_id` before waiting so another process can resume the task. > **Note:** `GET /v1/job/{job_id}` does not use the API key. Treat the UUID as a private > capability token and keep it behind your server boundary. ## 3. Put it into production - Move the API call behind a server route or background worker. - Persist the first successful `job_id`; do not submit again just because polling or a webhook is delayed. - Treat `completed` and `failed` as terminal states. - Continue waiting through `pending`, `staged`, `processing`, and `retry`. - Copy result files to your own durable storage. - Display safe error messages to users and retain `job_id` for support. Read [Task lifecycle](https://docs.legnext.ai/getting-started/task-lifecycle) before adding retries or webhooks. See [Image Parameters](https://docs.legnext.ai/getting-started/image-parameters) for the model-specific flags accepted in `text`. --- # Prompting Basics _How to write effective Midjourney prompts through the Legnext API — wording, structure, and where parameters go._ Every image or video task starts with the `prompt` field in your request body. This page covers how to write that string well. The guidance comes from upstream Midjourney documentation; which flags and values your prompt may use is defined by the [image parameter matrix](https://docs.legnext.ai/getting-started/image-parameters), which is generated from the backend validation spec. When the two disagree, the matrix wins. ## Keep it short and specific Short, descriptive phrases consistently beat long instructions. Describe the snapshot you want, not the process of making it. > **Note:** Avoid: *Show me a picture of lots of blooming California poppies, make them > bright, vibrant orange, and draw them in an illustrated style with colored > pencils* > > Prefer: `Colored pencil illustration of bright orange California poppies` Three wording habits that measurably change results: - **Use precise synonyms.** "Big" is vague; "gigantic" or "enormous" gives the model a stronger signal. - **Use numbers, not plurals.** "Three cats" is controllable; "cats" is not. Collective nouns work too — "a flock of birds". - **Describe what you want, not what you don't.** Saying "no cake" in the text can still produce a cake. To exclude things, use the [`--no` parameter](https://docs.legnext.ai/getting-started/image-parameters) instead of negations in the text itself. ## The seven detail dimensions A one-word prompt works — the model fills every gap with its default style. That means more variety and less control. Anything you care about must be spelled out. When a result disappoints, check which of these dimensions you left unspecified: | Dimension | Question | Examples | |-----------|----------|----------| | Subject | Who or what? | person, animal, character, object, location | | Medium | In what form? | photo, oil painting, illustration, sculpture, pixel art | | Environment | Where? | indoors, underwater, in the city, on the moon | | Lighting | What kind? | soft, ambient, overcast, neon, studio lights | | Color | Which palette? | vibrant, muted, monochromatic, pastel, duotone | | Mood | What feeling? | playful, calm, gloomy, energetic | | Composition | How is it framed? | portrait, closeup, headshot, bird's-eye view | ```text Gigantic whale drifting over a desert city, gouache painting, golden-hour light, muted pastel palette, serene mood, wide aerial view --v 8.2 --ar 16:9 ``` ## Vocabulary that moves the needle Single adjectives in the right slot change the image dramatically. Useful starting points, grouped by what they control: - **Artistic medium** — `______ style cat`: block print, ballpoint pen sketch, cyanotype, graffiti, risograph, ukiyo-e, watercolor, pixel art, cross stitch, oil painting, cut paper. - **Time period** — `illustration of a ______ cat`: 1700s, 1920s, 1950s, 1980s each carry a distinct visual language. - **Emotion** — `______ cat`: shy, determined, joyful, sleepy. - **Color** — `______ colored cat`: sepia, pastel, duotone, iridescent, grayscale, neon, acid green. - **Environment** — `______ cat`: tundra, jungle, desert, salt flat, crystal forest, ocean. Treat these as probes: swap one word at a time and compare, rather than rewriting the whole prompt between runs. For reproducible comparisons, pin [`--seed`](https://docs.legnext.ai/getting-started/image-parameters). ## Anatomy of a full prompt A prompt string can carry three kinds of content: 1. **Text** — the description above. Required. 2. **Image references** — image URLs that steer content or style, attached via image prompts or reference parameters (`--sref`, `--oref`, `--cref`). Which of these a given model version accepts varies sharply — `--cref` is rejected across the whole v8 family, and `--oref` exists only on v8.0. Check the [parameter matrix](https://docs.legnext.ai/getting-started/image-parameters) before using them. 3. **Parameters** — flags appended at the end of the string, e.g. `--ar 16:9 --stylize 150`. They control rendering, not content. ```text https://cdn.example.com/forest-ref.png Misty pine forest at dawn --sref https://cdn.example.com/style.png --v 8.2 --ar 3:2 ``` > **Tip:** Pin a version explicitly. When `--v` is omitted the API renders as v7, and > parameter support differs across versions — a prompt tuned on the default may > fail or change meaning on v8.2. See [Models](https://docs.legnext.ai/getting-started/models) for > version selection. ## Next steps Once the basics feel predictable, move to [Advanced Prompting](https://docs.legnext.ai/getting-started/prompting-advanced): multi-prompts and weights, permutation prompts, negative prompting, and rendered text. --- # Advanced Prompting _Multi-prompts and weights, permutations, negative prompting, and rendered text — prompt-language features beyond the basics._ This page covers the prompt-language features that go beyond plain descriptive text. Read [Prompting Basics](https://docs.legnext.ai/getting-started/prompting-basics) first. > **Warning:** Multi-prompt and permutation syntax is documented upstream by Midjourney but is > **not** part of the backend validation spec behind the [image parameter > matrix](https://docs.legnext.ai/getting-started/image-parameters). Treat the behavior on this page as > upstream-documented and verify it against your target model version before > building on it. ## Multi-prompts > **Warning:** **Version-gated: V6 family only.** Midjourney's current compatibility chart > marks multi-prompting as unsupported on V7 and the V8 family — `::` weights on > `--v 7` or `--v 8.x` are ignored or rejected upstream. Pin `--v 6.1` (or > `--v 6`) when you use this syntax. A double colon `::` splits a prompt into parts the model considers separately before blending them. `space ship` gives you sci-fi spaceships; `space:: ship` treats "space" and "ship" as distinct ideas — the result might be a boat sailing through space. ```text space:: ship --v 6.1 ``` ### Prompt weights Add a number right after `::` to control how strongly a part pulls the result. `space::2 ship` makes space twice as influential as the ship. An omitted weight defaults to `1`; decimals (`::0.5`) are supported on the V6 family. ```text still life painting::2 fruit::1 --v 6.1 ``` ### Negative weights Weights can go negative to suppress a concept, with one hard rule: **the sum of all weights in the prompt must stay positive** or the prompt is rejected. ```text still life painting:: fruit::-0.5 # 1 + (-0.5) = 0.5 ✓ still life painting:: fruit::-2 # 1 + (-2) = -1 ✗ rejected ``` ## Permutation prompts Curly braces with comma-separated options expand one prompt into many: `a {red, green, yellow} bird` produces three prompts, one per color. Multiple brace sets multiply — `a {red, green} bird in the {jungle, desert}` produces four — and sets can be nested. Escape a literal comma with a backslash: `{red, pastel \, yellow}` expands to two options, the second being `pastel, yellow`. Permutations also work on parameters: `--v {8, 8.2}` fans out across versions. > **Note:** Permutation expansion happens when the prompt is submitted — upstream, the bot > confirms the count and runs each expansion as a separate job. Through the API, > the safe pattern is to expand client-side and submit one task per combination: > you control the exact task count, the per-task cost, and each task's lifecycle > independently. See [Task lifecycle](https://docs.legnext.ai/getting-started/task-lifecycle). ## Negative prompting with `--no` `--no` excludes elements without negation words leaking into the description. Append it at the end with a comma-separated list: ```text still life gouache painting --no fruit, apple, pear ``` Two subtleties from upstream behavior: - **`--no` is equivalent to a `-0.5` weight** on that element in a multi-prompt. It softens rather than surgically removes; for hard control, describe what you *do* want. - **Every word is read independently.** `--no modern clothing` is parsed as "no modern" and "no clothing" — which can misfire moderation and rarely does what you meant. Put the clothing you want in the prompt text instead. Support: `--no` works on v6 / v6.1 / v7 / v8 / v8.1 / v8.2 but is rejected on niji 6 — see the [parameter matrix](https://docs.legnext.ai/getting-started/image-parameters). ## Text inside images To render words in the image itself, wrap them in **double quotation marks** — single quotes and apostrophes do not work. Short Latin-alphabet phrases render most reliably, and naming the container helps: ```text a pastel watercolor landscape with "imagine" written in the clouds --v 8.2 a cartoon manual with the words "read the docs" on the cover --v 8.2 ``` ## A note on image references Reference parameters (`--sref`, `--oref`, `--cref`, `--iw`) are prompt-language features too, but their version support is narrow and changes fast — `--cref` is rejected across the entire v8 family, and `--oref` exists only on v8.0. Rather than duplicate a moving target here, use the [parameter matrix](https://docs.legnext.ai/getting-started/image-parameters) as the source of truth for which reference your target version accepts. --- # Authentication _Authenticate server-side requests with a Legnext API key._ Legnext uses an API key in the `x-api-key` request header. ```bash curl "https://api.legnext.ai/api/account/balance" \ -H "x-api-key: $LEGNEXT_API_KEY" ``` Create and manage keys in the [Legnext dashboard](https://legnext.ai/dashboard), then store the key in your application's server-side secret or environment configuration. > **Warning:** Never expose a Legnext API key in browser or mobile client code, public logs, > agent conversations, or committed `.env` files. Send requests through a trusted > server boundary. ## Request base URL Use this base URL for the API: ```text https://api.legnext.ai/api ``` Endpoint paths in the API Reference are appended to that base. For example, `POST /v1/diffusion` becomes: ```text https://api.legnext.ai/api/v1/diffusion ``` ## Get Task is the exception `GET /v1/job/{job_id}` does not require an API key. The UUID in that URL is a capability token: anyone who has it can read the public task result. Keep each `job_id` server-side. Do not expose it in browser URLs, client logs, analytics events, screenshots, or support messages sent through public channels. ## Authentication failures An absent, invalid, revoked, or wrong-environment key returns `401`. A disabled account returns `403`. Do not retry either response unchanged; correct the key or account state first. See [Errors & Handling](https://docs.legnext.ai/api-reference/errors) for the client action associated with each failure class. --- # Task lifecycle _Integrate Legnext's asynchronous submit, wait, and persist workflow safely._ Generation and follow-up endpoints are asynchronous. A successful submit returns a task and `job_id`; it does not mean the media is ready. The production flow is: ```text submit → persist job_id → poll or receive callback → reach a terminal state → save output ``` ## Status values | Status | Meaning | Client action | |---|---|---| | `pending` | Accepted and waiting in a queue | Persist `job_id`; continue waiting | | `staged` | Queued behind the account's concurrency limit | Continue waiting | | `processing` | Provider is generating the output | Continue waiting | | `retry` | Legnext is resubmitting after a transient provider error | Continue waiting; do not create a replacement task | | `completed` | Output is available | Save the output to durable storage | | `failed` | The task ended with an error | Inspect `error`; retry only when appropriate | `completed` and `failed` are terminal. Do not keep polling after either state. ## Polling Poll [`GET /v1/job/{job_id}`](https://docs.legnext.ai/api-reference/task-management/get-task). This request does not require an API key: the UUID is a private capability token. - Use a bounded wait and a non-zero interval; never tight-loop. - Persist `job_id` before starting the wait. - A client timeout does not cancel the server task. Resume polling the same `job_id` rather than submitting a replacement. - Move long waits to a background job instead of holding an interactive HTTP request open. - Keep the UUID out of browser URLs, analytics, and public logs. A client timeout does not change the server task. It may complete after your wait ends, so return a pending state to your application and let a worker resume the same `job_id`. ## Webhooks Generation endpoints accept an optional `callback` URL. Use it when your application already has a durable background or event-processing architecture. - Return a successful response quickly and process media asynchronously. - Expect duplicate, delayed, or missing delivery and deduplicate by `job_id`. - Treat the callback as a notification, then fetch the canonical task with Get Task before persisting the final state. - Keep polling as a recovery path for a callback that never reaches your system. Task callbacks do not currently provide a public signing secret. Keep the callback endpoint behind an unguessable path, accept only the expected method and content type, validate the payload shape, and rely on Get Task for the canonical result. Delivery timing and retries are not an exactly-once guarantee. Your handler must be safe to run more than once. ## Retries and duplicate jobs Legnext does not deduplicate submit requests by prompt. A repeated POST creates a new billable task. - Retry `429`, transient `5xx`, network failures, and timeouts with capped exponential backoff and jitter. - Do not retry `400`, `401`, `402`, or `403` unchanged. - If submit returned a `job_id`, poll that task instead of resubmitting. - Use an application-level operation ID to prevent two workers from submitting the same user request. If the submit connection fails before you receive a response, the outcome is ambiguous: the server may already have created a task. Legnext does not expose a client idempotency key, so your application must choose between risking a duplicate task and asking the user or worker to retry. See [Errors & Handling](https://docs.legnext.ai/api-reference/errors) for failure classes and client actions. ## Persist outputs Remote output URLs are delivery URLs, not permanent application storage. Copy completed media into storage you control before the retention window ends. See [Output Storage](https://docs.legnext.ai/getting-started/output-storage). --- # Errors & recovery _Decide whether to fix, wait, retry, or escalate a Legnext API failure._ Legnext failures occur either while a request is submitted or after an asynchronous task has been accepted. Handle those stages differently. ## Read the failure Task endpoints return the `TaskResponse` shape for both accepted and rejected requests. A failure includes: ```json { "job_id": "4de9c4db-31e1-43df-a2bd-d54285ce4f39", "status": "failed", "error": { "code": 400, "message": "Human-readable failure", "raw_message": "Optional provider detail", "detail": null } } ``` Use `error.code` and the HTTP status for broad control flow. Use `message` for diagnostics and derive a safe user-facing summary in your application. Keep `raw_message` in restricted server logs; it may contain untranslated or provider-specific details. > **Warning:** Do not build application logic around exact provider error sentences. Wording > can change without changing the failure class. ## Recovery matrix | Signal | Meaning | Client action | |---|---|---| | `400` | Invalid field, unsupported parameter, incompatible model/action, or moderated input | Fix the request or source image; do not retry unchanged | | `401` | Missing, invalid, or revoked API key | Correct or replace the key | | `402` | Insufficient quota | Ask the user to top up, then submit a new task | | `403` | Disabled/restricted account, moderation rejection, or daily error limit | Correct the cause or contact support; do not retry unchanged | | `404` from Get Task | Unknown or expired capability URL | Check the `job_id`; the task lookup window may have expired | | `429` | Concurrency or staged-queue limit reached | Wait for running tasks to finish, then retry with backoff | | transient `5xx` or network failure | Temporary Legnext or provider failure | Retry with capped exponential backoff and jitter | | persistent `5xx` across attempts or unrelated jobs | Service incident | Stop retrying and contact support with the `job_id` | | task `status: failed` | Background processing ended unsuccessfully | Classify `error`; resubmit only when the class is retryable | ## Submission and task failures ### The submit request was rejected When the HTTP response is not successful, the request did not enter the normal asynchronous lifecycle. Read the response body before deciding what to do. - For `400`–`403`, change the input, credentials, account state, or balance. - For `429`, wait for existing work to finish. - For a transient `5xx`, use a bounded retry policy. If a response already contains a `job_id`, persist it and query that task rather than creating a replacement. ### The accepted task later failed A submit can return successfully and the task can later reach `status: failed`. Read `error.message` and `error.raw_message`, then classify the failure: - moderation, invalid parameters, and unsupported follow-up actions require a changed request; - timeouts, provider rate limits, and generic execution failures may be retried as a new task; - repeated failures for the same valid request should be escalated. Failed tasks are terminal. Do not keep polling them. ## Retry without creating accidental jobs Legnext does not provide a submit idempotency key and does not deduplicate by prompt. Every repeated POST can create another billable task. 1. Persist the first returned `job_id`. 2. Poll that task through [Get Task](https://docs.legnext.ai/api-reference/task-management/get-task). 3. Deduplicate callbacks and completed-task processing by `job_id`. 4. Use your own operation ID or database constraint so two workers cannot submit the same user request. 5. Retry a submit only when no `job_id` was returned and accepting a possible duplicate is preferable to dropping the request. An internal task status of `retry` means Legnext is already resubmitting after a transient provider failure. Keep waiting; do not submit a second task. ## Common non-retryable corrections - Check the generated request schema for missing fields and enum values. - Use the [image parameter matrix](https://docs.legnext.ai/getting-started/image-parameters) for version-specific Midjourney flags. - Pin `--v 6.1` when using legacy Character Reference (`--cref`); the API default is V7. - Remove unsupported flags named by a `400` response. - For a rejected follow-up action, choose another source image or regenerate the base image. `available_actions` is advisory, not a guarantee. - For moderation failures, change the prompt or referenced image instead of repeatedly submitting the same content. ## When to contact support Email [support@legnext.ai](mailto:support@legnext.ai) after a bounded retry schedule when: - multiple unrelated valid tasks fail with `5xx`; - the same request fails repeatedly without an actionable validation message; - credits appear inconsistent after the task reaches a terminal state; or - a task remains non-terminal beyond your operational timeout. Include the `job_id`, endpoint, UTC timestamp, HTTP status, and sanitized error object. Never send the API key. --- # Output Storage _Persist generated files before delivery URLs and follow-up actions expire._ ## Output retention Result files are served from temporary CDN URLs that stay valid for 7 days after a task completes. Treat every returned URL as a temporary delivery URL, not as your application's permanent asset. After a task reaches `completed`: 1. Download the required file from `output.image_url` or `output.image_urls`. 2. Store it in storage controlled by your application. 3. Save your durable URL alongside the Legnext `job_id`. 4. Serve the durable copy to users instead of depending on the original URL. Do not schedule the download for the end of the 7-day window. Networks, providers, and storage migrations can make a delivery URL unavailable earlier. A production integration should persist the output as part of completed-task processing. ## Task and follow-up window Task lookup and operations that depend on an existing Midjourney result are available for three days after the source task is created. Complete variations, upscales, and other follow-up operations inside that window. Use `available_actions` to choose a likely valid action, but still handle a `400` rejection. For some edit-derived images the field can advertise an action that the provider cannot perform. > **Note:** Output retention, task lookup, and follow-up operation validity are separate. > Storing an image yourself does not extend the period in which Legnext can query > or perform an action on the original task. See [Task lifecycle](https://docs.legnext.ai/getting-started/task-lifecycle) for polling, webhook, and retry guidance. --- # Models _Supported Midjourney model versions and the compatibility choices that affect an API integration._ Legnext supports `v6`, `v6.1`, `niji 6`, `v7`, `v8`, `v8.1`, and `v8.2`. When `--v` is omitted, the API renders with **v7**. Pin the version explicitly when repeatability or parameter compatibility matters. ## Choose a model | Model | Choose it for | Important compatibility notes | |---|---|---| | `--v 8.2` | Current V8 aesthetics and native 2K with `--hd` | Rejects `--turbo`, `--q`, `--oref`, `--cref`, and `--sd` | | `--v 8.1` | V8 image prompting and native 2K with `--hd` | Same parameter surface as V8.2 | | `--v 8` | — | **Retired upstream on July 24, 2026.** The API still accepts it for backward compatibility, but upstream rendering is undefined — migrate to `--v 8.1` or `--v 8.2`. No inpaint, outpaint, or pan actions | | `--v 7` | Default behavior and Omni Reference with `--oref` | Supports V7 actions and Draft Mode | | `--v 6.1` / `--v 6` | Legacy prompts and Character Reference with `--cref` | Keep only for compatibility with existing workflows | | `--niji 6` | Anime and East Asian illustration styles | Uses the Niji model family | > **Note:** The V8 family does not support Turbo mode. Use `--fast`. The API returns HTTP > 400 when a version-specific parameter is rejected. ## Exact compatibility Use the generated [image parameter matrix](https://docs.legnext.ai/getting-started/image-parameters) for accepted flags, ranges, and cost multipliers. Agents can validate against the machine-readable [`mj-image-params.v1.json`](https://docs.legnext.ai/schemas/mj-image-params.v1.json). The `available_actions` field is a useful guide for follow-up operations, but it is not an authorization guarantee. Some edit-derived images can still reject an advertised action. Handle that `400` response without retrying the same source image. --- # Image Parameters _Generated compatibility matrix for Midjourney image parameters by model version._ The table below is generated from the backend validation specification. Do not infer support from examples or upstream Midjourney documentation. > **Tip:** New to writing prompts? Start with [Prompting > Basics](https://docs.legnext.ai/getting-started/prompting-basics) — this page is the flag-by-flag > compatibility reference, not a writing guide. > **Note:** For video-only controls such as Motion, Loop, End frame, and Batch size, use the > [video parameter guide](https://docs.legnext.ai/getting-started/video-parameters). Their rows in this > matrix describe backend pass-through, not the final video prompt syntax. ## Image generation parameters {/* BEGIN GENERATED:image-parameters-table — source: legnext-ai/Legnext-backend spec/mj-image-params.yaml via cmd/genmjparams. Do not edit between the markers; edit the YAML and CI will sync this table. */} | Parameter | Format | Values / Range | v8 | v8.1 | v8.2 | Default* | Description | |---|---|---|---|---|---|---|---| | Aspect Ratio | `--aspect`, `--ar` | Up to 14:1 (4:1 for v8.1 / v8.2 HD) | ✓ | ✓ | ✓ | ✓ | Images are initially square; use this to change the shape. Integer ratios only — use 139:100 instead of 1.39:1. | | Batch Size (legacy) | `--bs` | [1, 2, 4] (video endpoints only) | ✓ | ✓ | ✓ | ✓ | Legacy batch-size flag. Not supported for image generation — video endpoints only; accepted by the API but unverified. | | Chaos | `--chaos`, `--c` | 0-100 (default: 0) | ✓ | ✓ | ✓ | ✓ | Adds variety to image results; higher values create more unusual images. | | Character Reference | `--cref`, `--cw` | Image URL (--cref); weight 0-100 (--cw) | ✗ | ✗ | ✗ | ✓ | Keeps the same character across images. Only v6 / v6.1 / niji 6 — replaced by Omni Reference (--oref) from v7 onward; the whole v8 family rejects it. A no-version prompt using --cref renders as v7 and fails upstream with Invalid prompt format. | | Draft Mode | `--draft` | No value | ✗ | ✓ | ✓ | ✓ | Rapid low-resolution exploration. v7: 4 images at half price. v8.1 / v8.2: a 24-image batch billed at the standard rate (no discount); only the first 4 images are actionable. Not available on v8.0 — rejected up front. | | End (legacy) | `--end` | — | ✓ | ✓ | ✓ | ✓ | Legacy video flag, accepted by the API; semantics unverified. | | Experimental | `--exp` | No value | ✓ | ✓ | ✓ | ✓ | Experimental aesthetic control (legacy flag, accepted by the API; semantics unverified). | | Fast Mode | `--fast` | No value | ✓ | ✓ | ✓ | ✓ | Default GPU speed mode (standard processing speed, typically under 1 minute). | | HD Mode | `--hd` | No value | ✓ 1.5× cost | ✓ 1.5× cost | ✓ 1.5× cost | ○ | v8.0 / v8.1 / v8.2: renders native 2K (2048x2048) at 1.5x the standard cost (120 credits vs 80 for SD). Pre-V8: no effect — renders SD 1024 and is billed 1x. | | Image Weight | `--iw` | 0-3 (default: 1) | ✓ | ✓ | ✓ | ✓ | Controls the influence of image prompts; higher values make image prompts more influential. Probed passing on v8.2. | | Loop (legacy) | `--loop` | — | ✓ | ✓ | ✓ | ✓ | Legacy video flag, accepted by the API; semantics unverified. | | Motion | `--motion` | 1-4 (default: 2) | ✓ | ✓ | ✓ | ✓ | Controls video motion intensity (video tasks only); higher = more motion. Legacy flag, value handling unverified. | | Negative Prompt | `--no` | Text description | ✓ | ✓ | ✓ | ✓ | Tells the model what not to include in the image. Supported on v6 / v6.1 / v7 / v8 / v8.1 / v8.2 (not niji 6). | | Niji | `--niji` | 5, 6 (current: 6) | ✓ | ✓ | ✓ | ✓ | Focused anime and East Asian aesthetic model (e.g. --niji 6). | | Omni Reference | `--oref`, `--ow` | Image URL (--oref); weight (--ow) | ✗ | ✗ | ✗ | ✓ 2× cost | References a person or object from another image. Supported on v7 only — removed across the v8 family, so use --v 7 for omni reference. Billed at 2x the standard rate (160 credits vs 80). | | Personalization Profile | `--profile`, `--p` | Profile code | ✓ | ✓ | ✓ | ✓ | Personalization profile selector (--p / --profile). | | Quality | `--quality`, `--q` | 0.25, 0.5, 1, 2, 4 (default: 1) | ✓ | ✗ | ✗ | ✓ | Controls image detail and processing time. Removed from v8.1 onward — rejected on v8.1 and v8.2. | | Raw Mode | `--raw` | No value | ✓ | ✓ | ✓ | ✓ | Vestigial alias carried over from the legacy flag set — the real surface is --style raw. | | Seed | `--seed` | 0-4294967295 | ✓ | ✓ | ✓ | ✓ | For testing and experimentation: same seed + same prompt = consistent results. | | Seed Diffusion | `--sd` | No value | ✗ | ✗ | ✗ | ✓ | From v8 on, SD is controlled via the Midjourney web settings panel and is not exposed via the API — rejected on v8, v8.1 and v8.2. | | Stop | `--stop` | 10-100 (default: 100) | ✓ | ✓ | ✓ | ✓ | Finish images partway through the process for a softer, more unique look. | | Style | `--style` | Style name (e.g. raw) | ✓ | ✓ | ✓ | ✓ | Style selector. --style raw reduces the default aesthetic styling; probed passing on v8.2. | | Style Reference | `--sref` | Image URL | ✓ | ✓ | ✓ | ✓ | Matches the look and feel of another image. Probed passing on v8.2. | | Style Weight | `--sw` | Number | ✓ | ✓ | ✓ | ✓ | Style weight; companion parameter of --sref. | | Stylize | `--stylize`, `--s` | 0-1000 (default: 100) | ✓ | ✓ | ✓ | ✓ | Controls artistic style: lower = more prompt-focused, higher = more artistic. | | Tile | `--tile` | No value | ✓ | ✓ | ✓ | ✓ | Creates seamless tiled images for patterns and textures. Probed passing on v8.2. | | Turbo Mode | `--turbo` | No value | ✗ | ✗ | ✗ | ✓ | High-performance GPU pool, up to 4x faster, double cost (v5+ only). The entire v8 family rejects --turbo, so it is rejected up front on v8 / v8.1 / v8.2 — use --fast instead. | | Version | `--version`, `--v` | 1-8.2 (API default: 7; latest: 8.2) | ✓ | ✓ | ✓ | ✓ | Switches between model versions. When --v is omitted the API renders as v7 — version is the user's choice, never injected. | | Weird | `--weird`, `--w` | 0-3000 (default: 0) | ✓ | ✓ | ✓ | ✓ | Makes images strange and unconventional. | ✓ supported · ✗ rejected (the API returns 400) · ○ accepted but has no effect on this version (not billed) **Default** applies when `--v` is omitted (the API renders as v7), to pre-V8 versions (v6.x), and to future majors not yet probed. Unrecognized v8 minors (e.g. `--v 8.3` before it is probed) inherit the newest v8 row. The machine-readable version of this table — per-flag value types, cost multipliers, and validation rules — is published at [mj-image-params.v1.json](https://docs.legnext.ai/schemas/mj-image-params.v1.json). {/* END GENERATED:image-parameters-table */} ## Usage Append parameters to the prompt string: ```text Cinematic coastal road at sunrise --v 8.2 --ar 16:9 --stylize 150 ``` Use [Models](https://docs.legnext.ai/getting-started/models) for version selection and the [image generation endpoint](https://docs.legnext.ai/api-reference/image-generation/diffusion) for the request schema. --- # Video Parameters _Prompt parameters accepted by the video generation endpoints._ Append video controls to the prompt text sent to a video endpoint. | Parameter | Values | Behavior | |---|---|---| | Motion | `--motion low`, `--motion high` | Low is the default; high allows larger movement | | Raw | `--raw` | Reduces automatic enhancements | | End frame | `--end ` | Uses the image URL as the final frame | | Loop | `--loop` | Requests matching first and last frames | | Batch size | `--bs 1`, `--bs 2`, `--bs 4` | Controls the number of videos returned | ```text Cinematic clouds moving over a mountain --motion high --loop --bs 2 ``` These are provider-facing prompt controls. The generated OpenAPI schema remains the authority for the JSON request body. The legacy video rows in the image parameter matrix describe backend pass-through only; use this page for their actual prompt syntax. See [video diffusion](https://docs.legnext.ai/api-reference/video-generation/video-diffusion), [extend video](https://docs.legnext.ai/api-reference/video-generation/extend-video), and [video upscale](https://docs.legnext.ai/api-reference/video-generation/video-upscale) for request and response schemas. --- # Text to Image _Create a Midjourney image-generation task from a prompt._ **Endpoint:** `POST /v1/diffusion` Use this as the starting point for a text-to-image workflow. Put model and rendering controls in `text`, for example: ```text Cinematic coastal road at sunrise --v 8.2 --ar 16:9 ``` The response is an asynchronous task. Persist its `job_id`, then follow the [task lifecycle](https://docs.legnext.ai/getting-started/task-lifecycle) until `completed` or `failed`. For accepted flags and version compatibility, use the generated [image parameter matrix](https://docs.legnext.ai/getting-started/image-parameters). --- # Variation _Create subtle or strong variations of one image in a completed grid._ **Endpoint:** `POST /v1/variation` Variation is a follow-up operation. Pass the parent `jobId` and the zero-based `imageNo` of the image to vary. The response is a new asynchronous task. Use the parent's `available_actions` as guidance, but handle a `400` rejection: the field is not a guarantee that every provider can perform the action on that source image. --- # Upscale _Upscale one image from a completed Midjourney grid._ **Endpoint:** `POST /v1/upscale` Upscale is a follow-up operation. Pass the parent `jobId`, the zero-based `imageNo`, and a supported upscale `type`. The response is a new asynchronous task. Use the action metadata returned by the parent task to choose a supported operation. This endpoint is the Midjourney grid upscale action; it is unrelated to the suspended Enhancement API. --- # Reroll _Generate a new result from a completed parent task._ **Endpoint:** `POST /v1/reroll` Reroll is a follow-up operation. Pass the parent task's `job_id`; the new request creates a separate billable task with its own lifecycle. Submit follow-up operations within the parent task's [three-day task window](https://docs.legnext.ai/getting-started/output-storage#task-and-follow-up-window). Do not reroll merely because polling or a callback is delayed. --- # Blend _Combine two to five source images into a new Midjourney image._ **Endpoint:** `POST /v1/blend` Use Blend when the source material is a set of public image URLs rather than a previous Legnext task. Supply two to five images. `aspect_ratio` is optional and defaults to `1:1`. The result follows the normal asynchronous [task lifecycle](https://docs.legnext.ai/getting-started/task-lifecycle). Download the completed output to storage you control. --- # Describe _Create prompt suggestions from a public image URL._ **Endpoint:** `POST /v1/describe` Describe returns text suggestions rather than generated media. It is still an asynchronous task: persist `job_id` and wait for a terminal state before reading the text output. The source image must be reachable by Legnext without browser cookies or private network access. --- # Shorten _Turn a long prompt into shorter Midjourney prompt suggestions._ **Endpoint:** `POST /v1/shorten` Shorten returns text suggestions rather than generated media. It is asynchronous, so persist `job_id` and wait for `completed` before reading the output. Treat the returned prompts as suggestions. If you later submit one to Text to Image, apply model parameters using the [image parameter matrix](https://docs.legnext.ai/getting-started/image-parameters). --- # Pan _Extend a completed image in one direction._ **Endpoint:** `POST /v1/pan` Pan is a follow-up operation. Pass the parent `jobId`, zero-based `imageNo`, and direction defined by the generated request schema. Not every model or source image supports Pan. Check the parent task's `available_actions`, then handle a `400` rejection as a capability mismatch rather than a transient failure. --- # Outpaint _Expand the canvas around a completed image._ **Endpoint:** `POST /v1/outpaint` Outpaint is a follow-up operation on one image from a completed parent task. Pass the parent `jobId`, zero-based `imageNo`, and the requested expansion. Support depends on the model and source image. A capability rejection requires a different or regenerated base image; do not retry the same request unchanged. --- # Inpaint _Regenerate selected regions of a completed image._ **Endpoint:** `POST /v1/inpaint` Inpaint is a follow-up operation. Pass the completed parent task and the region data defined by the generated request schema. The source image and its model must support editing. If the API rejects the action, regenerate a compatible base image instead of looping on the same parent. --- # Remix _Create a new variation while changing the prompt._ **Endpoint:** `POST /v1/remix` Remix is a follow-up operation on one image in a completed parent grid. Pass the parent `jobId`, zero-based `imageNo`, mode, and replacement prompt. Model and provider capabilities depend on the parent image. Treat `available_actions` as guidance and handle unsupported-action responses without retrying the same source unchanged. --- # Edit _Edit a public image with a prompt and region geometry._ **Endpoint:** `POST /v1/edit` Edit is a follow-up operation on one image from a completed parent task. Pass the parent `jobId`, zero-based `imageNo`, canvas, image position, and replacement prompt described by the generated request schema. A mask is optional. The response is an asynchronous task. Validate geometry in your application before submitting and persist the returned `job_id`. --- # Upload paint _Edit an uploaded image with canvas, mask, and prompt data._ **Endpoint:** `POST /v1/upload-paint` Upload Paint accepts a public source image plus explicit canvas, placement, mask, and prompt data. Use it when your application already owns the image rather than starting from a Legnext task. Validate the geometry and polygon coordinates before submitting. The response is a new asynchronous task. --- # Retexture _Apply a new material or visual treatment to a public image._ **Endpoint:** `POST /v1/retexture` Retexture accepts a public image URL and a prompt describing the desired treatment. The source must be downloadable by Legnext without cookies or private network access. The response is asynchronous. Save the new output as a separate asset rather than replacing the source before the task completes. --- # Remove Background _Remove the background from a public image._ **Endpoint:** `POST /v1/remove-background` Pass a public image URL that Legnext can download without authentication. The response is an asynchronous task, not the processed file itself. After completion, copy the returned asset to [durable storage](https://docs.legnext.ai/getting-started/output-storage). --- # Midjourney Enhance _Apply the Midjourney Enhance follow-up action to a completed image._ **Endpoint:** `POST /v1/enhance` Enhance is a Midjourney follow-up action on one image from a completed parent task. It is not the suspended Topaz-based Enhancement API. Pass the parent `jobId` and zero-based `imageNo`. Support depends on the parent image; handle an unsupported-action `400` without retrying the same source. --- # Video Diffusion _Create a Midjourney video task from a prompt or existing image._ **Endpoint:** `POST /v1/video-diffusion` Choose one input path: - pass a completed parent `jobId` and optionally select `imageNo`; or - put a public image URL and motion prompt in `prompt`. `imageNo` defaults to `0`. The response is an asynchronous task. Use the [video parameter guide](https://docs.legnext.ai/getting-started/video-parameters) for prompt controls, then follow the standard [task lifecycle](https://docs.legnext.ai/getting-started/task-lifecycle). --- # Extend Video _Extend one video from a completed video task._ **Endpoint:** `POST /v1/extend-video` Pass the completed parent `jobId`, zero-based `videoNo`, and a prompt that guides the continuation. Each request creates a separate asynchronous task. Complete the extension within the parent's [three-day task window](https://docs.legnext.ai/getting-started/output-storage#task-and-follow-up-window) and persist the resulting video to your own storage. --- # Video Upscale _Upscale one video from a completed video task._ **Endpoint:** `POST /v1/video-upscale` Pass the completed parent `jobId` and zero-based `videoNo`. The endpoint creates a new asynchronous task; it does not return the upscaled file immediately. After completion, copy the video to [durable storage](https://docs.legnext.ai/getting-started/output-storage). --- # Get Task _Retrieve the current state and result of an asynchronous task._ **Endpoint:** `GET /v1/job/{job_id}` Use the exact `job_id` returned at submission. This endpoint does not require an API key: the UUID in the URL is a capability token that grants access to the task result. > **Warning:** Keep the capability URL server-side. Do not put it in browser URLs, analytics, > public logs, or screenshots. Continue waiting through `pending`, `staged`, `processing`, and `retry`. Stop at `completed` or `failed`. A `404` means the identifier is unknown or the three-day task lookup window has expired. --- # Get Account Balance _Read the current account balance and available usage units._ **Endpoint:** `GET /account/balance` Use this endpoint for account-level monitoring and before asking a user to recover from `402 insufficient quota`. Do not predict whether a particular request will succeed by subtracting hard-coded prices in the client. Task cost depends on current model and parameters; use the task response's usage metadata and current balance instead. --- # OpenAPI contract _Backend-generated paths, authentication, fields, enums, and responses._ ```yaml # Code generated by cmd/genopenapi; DO NOT EDIT. # # Source of truth: the Legnext backend itself — routes registered in # internal/task_manager_server/handler plus the operation catalog in # internal/openapi/catalog.go (request/response structs are reflected from # internal/model). Regenerate with: # # go generate ./internal/openapi/ # # Consumers: docs.legnext.ai (synced via .github/workflows/docs-sync.yml), # API playgrounds, SDK generators, coding agents. openapi: 3.1.0 info: title: Legnext AI API description: |- The Legnext API generates and edits images and videos with Midjourney. ## Authentication Send your API key in the `x-api-key` header on every request (the `Authorization: Bearer ` form is also accepted). Create and manage keys in the Legnext dashboard. The one exception is `GET /v1/job/{job_id}`, which is unauthenticated. Its UUID is a capability token: keep it private and do not expose it in client-side logs or analytics. ## Asynchronous tasks Every generation endpoint creates an asynchronous task and returns the full `TaskResponse` object immediately (status `pending`, or `staged` when the account is at its concurrency limit). The task reaches a terminal status — `completed` or `failed` — within seconds to minutes. Poll `GET /v1/job/{job_id}` or pass a `callback` URL at creation to be notified (the completed TaskResponse is POSTed to it). ## Errors Task endpoints (everything under `/v1`) report errors in the same `TaskResponse` shape as success: `status` is `failed` and the `error` object carries `code` (the HTTP status) and `message`. Account, usage, and webhook endpoints report errors as `{code, message}` where `code` mirrors the HTTP status. ## Limits and maintenance `402` means insufficient quota, `429` means the account's concurrency or staged-queue limit is reached (retry once running tasks finish), and `503` means the service (or one provider-backed feature) is under maintenance. version: 1.0.0 contact: email: support@legnext.ai license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html jsonSchemaDialect: https://json-schema.org/draft/2020-12/schema servers: - url: https://api.legnext.ai/api description: Production tags: - name: Image Generation description: Create and derive Midjourney images. - name: Video Generation description: Create and extend Midjourney videos. - name: Image Enhancement description: AI image enhancement and upscaling (Topaz). - name: Task Management description: Track and query asynchronous tasks. - name: Account description: Account profile, balance, and quota. paths: /account/active_tasks: get: tags: - Account summary: Get Active Tasks description: Retrieve the account's currently active (staged / pending / processing) tasks, grouped by model with per-state counts. operationId: getActiveTasks responses: "200": description: Active tasks grouped by model. content: application/json: schema: type: object properties: code: type: integer description: Business status code; mirrors the HTTP status (200 on success). data: $ref: '#/components/schemas/ActiveTasks' message: type: string description: '"success" on success; human-readable error message otherwise.' required: - code - message - data "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: type: object properties: message: type: string description: Human-readable error message. required: - message "403": description: Forbidden — account is disabled. content: application/json: schema: type: object properties: message: type: string description: Human-readable error message. required: - message "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: type: object properties: code: type: integer description: Business status code; mirrors the HTTP status (200 on success). detail: description: Optional machine-readable error detail (only present on some failures). message: type: string description: '"success" on success; human-readable error message otherwise.' required: - code - message /account/balance: get: tags: - Account summary: Get Account Balance description: 'Retrieve the authenticated account''s balance summary: USD-equivalent balance, available credits and points, and the low-balance alert state. Conversion: 1 USD = 1000 points = 1000 credits.' operationId: getAccountBalance responses: "200": description: Balance summary. content: application/json: schema: type: object properties: code: type: integer description: Business status code; mirrors the HTTP status (200 on success). data: $ref: '#/components/schemas/Balance' message: type: string description: '"success" on success; human-readable error message otherwise.' required: - code - message - data "400": description: Bad Request — invalid parameters. content: application/json: schema: type: object properties: code: type: integer description: Business status code; mirrors the HTTP status (200 on success). detail: description: Optional machine-readable error detail (only present on some failures). message: type: string description: '"success" on success; human-readable error message otherwise.' required: - code - message "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: type: object properties: message: type: string description: Human-readable error message. required: - message "403": description: Forbidden — account is disabled. content: application/json: schema: type: object properties: message: type: string description: Human-readable error message. required: - message /account/info: get: tags: - Account summary: Get Account Information description: Retrieve the authenticated account's profile, plan, wallet, and credit-pack breakdown. `api_keys` is always null in this response (the key list is withheld on user-facing endpoints). operationId: getAccountInfo responses: "200": description: Account information. content: application/json: schema: type: object properties: code: type: integer description: Business status code; mirrors the HTTP status (200 on success). data: $ref: '#/components/schemas/AccountInfo' message: type: string description: '"success" on success; human-readable error message otherwise.' required: - code - message - data "400": description: Bad Request — invalid parameters. content: application/json: schema: type: object properties: code: type: integer description: Business status code; mirrors the HTTP status (200 on success). detail: description: Optional machine-readable error detail (only present on some failures). message: type: string description: '"success" on success; human-readable error message otherwise.' required: - code - message "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: type: object properties: message: type: string description: Human-readable error message. required: - message "403": description: Forbidden — account is disabled. content: application/json: schema: type: object properties: message: type: string description: Human-readable error message. required: - message /v1/blend: post: tags: - Image Generation summary: Blend Images description: Combine 2-5 images into a single composition. operationId: blendImages requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BlendRequest' responses: "200": description: Blend task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/describe: post: tags: - Image Generation summary: Describe Image description: Generate text prompts that describe an existing image. operationId: describeImage requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DescribeRequest' responses: "200": description: Describe task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/diffusion: post: tags: - Image Generation summary: Text to Image description: Generate high-quality images from a text prompt using Midjourney. Append Midjourney parameters as `--flags` inside `text` (e.g. `"A cute kitten --ar 16:9 --stylize 100"`). Which flags each model version accepts — and what each costs — is defined in the machine-readable schema at https://docs.legnext.ai/schemas/mj-image-params.v1.json. operationId: generateImage requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DiffusionRequest' responses: "200": description: Task accepted. The full task object is returned with status `pending` (or `staged` when the account is at its concurrency limit). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/edit: post: tags: - Image Generation summary: Edit Image description: |- Reposition and repaint an image on a custom canvas with optional masks. Restricted to whitelisted accounts (403 otherwise). The base image must itself have been generated on the official provider. operationId: editImage requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/EditRequest' responses: "200": description: Edit task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/enhance: post: tags: - Image Generation summary: Enhance description: |- Upscale one image from a draft-mode grid to full quality. The parent task must have been created with `--draft` (only the first 4 images of a 24-image v8.1 draft grid are actionable). Restricted to whitelisted accounts (403 otherwise). The base image must itself have been generated on the official provider. operationId: enhanceImage requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/EnhanceRequest' responses: "200": description: Enhance task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/enhance-upscale: post: tags: - Image Enhancement summary: Enhance and Upscale Image description: |- Upscale images to ultra-high resolutions (up to 12K) using Topaz Labs AI with content-aware enhancement. **Currently suspended**: the endpoint returns 503 while the Topaz provider is unavailable. operationId: enhanceUpscaleImage requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/EnhanceUpscaleRequest' responses: "200": description: Enhancement task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "503": description: Service Unavailable — the enhance/upscale provider is temporarily suspended. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/extend-video: post: tags: - Video Generation summary: Extend Video description: Extend a completed video with additional motion. operationId: extendVideo requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExtendVideoRequest' responses: "200": description: Extend-video task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/inpaint: post: tags: - Image Generation summary: Inpaint description: |- Selectively regenerate masked regions of an image using a new prompt. Restricted to whitelisted accounts (403 otherwise). The base image must itself have been generated on the official provider. operationId: inpaint requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InpaintRequest' responses: "200": description: Inpaint task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/job/{job_id}: get: tags: - Task Management summary: Get Task Status description: 'Retrieve the current state and result of a task. Terminal statuses are `completed` and `failed`; while running, status is `pending`, `staged`, `processing`, or `retry`. The UUID in this URL acts as a capability token: keep it private and do not expose it in client-side logs or analytics.' operationId: getTaskStatus parameters: - name: job_id in: path description: The `job_id` returned at task creation. required: true schema: type: string format: uuid responses: "200": description: The task object. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "404": description: Task not found (unknown or expired task_id). content: application/json: schema: type: object properties: code: type: integer description: Business status code; mirrors the HTTP status (200 on success). detail: description: Optional machine-readable error detail (only present on some failures). message: type: string description: '"success" on success; human-readable error message otherwise.' required: - code - message "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: type: object properties: code: type: integer description: Business status code; mirrors the HTTP status (200 on success). detail: description: Optional machine-readable error detail (only present on some failures). message: type: string description: '"success" on success; human-readable error message otherwise.' required: - code - message security: [] /v1/outpaint: post: tags: - Image Generation summary: Outpaint description: Expand an image beyond its borders in all directions (zoom out). operationId: outpaint requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/OutpaintRequest' responses: "200": description: Outpaint task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/pan: post: tags: - Image Generation summary: Pan Extend description: Extend an image in a single direction. operationId: panExtend requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PanRequest' responses: "200": description: Pan task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/remix: post: tags: - Image Generation summary: Remix description: |- Reinterpret one image from a grid with a new prompt and controllable strength. Restricted to whitelisted accounts (403 otherwise). The base image must itself have been generated on the official provider. operationId: remixImage requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RemixRequest' responses: "200": description: Remix task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/remove-background: post: tags: - Image Generation summary: Remove Background description: |- Remove the background of an image, producing a clean cutout. Restricted to whitelisted accounts (403 otherwise). The base image must itself have been generated on the official provider. operationId: removeBackground requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RemoveBackgroundRequest' responses: "200": description: Remove-background task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/reroll: post: tags: - Image Generation summary: Reroll Task description: Re-run a completed generation with the same prompt to produce a fresh grid. operationId: rerollTask requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RerollRequest' responses: "200": description: Reroll task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/retexture: post: tags: - Image Generation summary: Retexture description: |- Transform the materials and textures of an image while preserving its structure. Restricted to whitelisted accounts (403 otherwise). The base image must itself have been generated on the official provider. operationId: retexture requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RetextureRequest' responses: "200": description: Retexture task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/shorten: post: tags: - Image Generation summary: Shorten Prompt description: Analyze a prompt and distill it to its most influential tokens. operationId: shortenPrompt requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ShortenRequest' responses: "200": description: Shorten task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/upload-paint: post: tags: - Image Generation summary: Advanced Edit with Canvas description: |- Edit an arbitrary uploaded image on a custom canvas with masks. Restricted to whitelisted accounts (403 otherwise). The base image must itself have been generated on the official provider. operationId: uploadPaint requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UploadPaintRequest' responses: "200": description: Upload-paint task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/upscale: post: tags: - Image Generation summary: Upscale Image description: Upscale one image from a completed generation grid to full resolution. operationId: upscaleImage requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpscaleRequest' responses: "200": description: Upscale task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/variation: post: tags: - Image Generation summary: Create Image Variation description: Generate variations of one image from a completed grid with controllable intensity. operationId: createVariation requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VariationRequest' responses: "200": description: Variation task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/video-diffusion: post: tags: - Video Generation summary: Video Diffusion description: Generate a video from a text prompt (t2v) or from an image of a previous generation grid (i2v). For t2v, `prompt` must contain an init-image URL followed by the motion description. operationId: generateVideo requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VideoDiffusionRequest' responses: "200": description: Video task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' /v1/video-upscale: post: tags: - Video Generation summary: Video Upscale description: Upscale one video from a completed video grid to higher resolution. operationId: upscaleVideo requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VideoUpscaleRequest' responses: "200": description: Video-upscale task accepted. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "400": description: Bad Request — invalid request body or parameter values (see `error.message`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "401": description: Unauthorized — missing, invalid, or revoked API key. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "402": description: Payment Required — insufficient quota to freeze for this task (`insufficient quota`). content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "403": description: Forbidden — account disabled, feature restricted to whitelisted accounts, or daily error limit reached. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "429": description: Too Many Requests — concurrency or staged-queue limit exceeded; retry after running tasks finish. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' "500": description: Internal Server Error — unexpected server-side failure. content: application/json: schema: $ref: '#/components/schemas/TaskResponse' components: schemas: APIKey: type: object properties: account_id: type: integer created_at: type: string format: date-time deleted_at: type: string format: date-time description: Deletion timestamp; null when the record is active. id: type: integer name: type: string revoked: type: boolean updated_at: type: string format: date-time value: type: string required: - id - created_at - updated_at - deleted_at - name - revoked - account_id - value AccountInfo: type: object properties: account_group: type: string account_tags: type: array items: $ref: '#/components/schemas/AccountTag' api_keys: type: array items: $ref: '#/components/schemas/APIKey' created_at: type: string format: date-time credit_pack_info: $ref: '#/components/schemas/CreditPackInfo' deleted_at: type: string format: date-time description: Deletion timestamp; null when the record is active. equivalent_in_usd: type: number fallback_mj_provider: type: string id: type: integer is_enable: type: boolean max_concurrent_task_count: type: integer name: type: string notification_hook_url: type: string plan: type: string preferred_mj_provider: type: string type: type: string updated_at: type: string format: date-time wallet: $ref: '#/components/schemas/Wallet' required: - id - created_at - updated_at - deleted_at - name - is_enable - account_group - plan - type - api_keys - max_concurrent_task_count - wallet - account_tags - notification_hook_url - preferred_mj_provider - fallback_mj_provider - equivalent_in_usd - credit_pack_info AccountTag: type: object properties: account_id: type: integer created_at: type: string format: date-time deleted_at: type: string format: date-time description: Deletion timestamp; null when the record is active. id: type: integer tag: type: string updated_at: type: string format: date-time required: - id - created_at - updated_at - deleted_at - account_id - tag ActiveTask: type: object properties: account_id: type: integer created_at: type: string format: date-time id: type: integer is_temporary: type: boolean model: type: string description: Model family that executed the task. enum: - midjourney service_mode: type: string description: Service mode the task runs under. Only `public` is currently supported. enum: - public status: type: string description: Active-task state. `abnormal` tasks are never exposed to users. enum: - staged - pending - processing task_id: type: string format: uuid task_type: type: string updated_at: type: string format: date-time usage: type: integer usage_type: type: string description: Billing unit used for the task. enum: - credit - point required: - id - created_at - updated_at - task_id - account_id - model - task_type - status - service_mode - usage_type - is_temporary - usage ActiveTasks: type: object properties: midjourney: $ref: '#/components/schemas/ActiveTasksByModel' required: - midjourney ActiveTasksByModel: type: object properties: active_tasks: type: array items: $ref: '#/components/schemas/ActiveTask' pending_count: type: integer processing_count: type: integer staged_count: type: integer required: - staged_count - pending_count - processing_count - active_tasks Balance: type: object properties: account_id: type: integer alert_threshold: type: number available_credits: type: integer available_points: type: integer balance_usd: type: number low_balance_alert: type: boolean updated_at: type: string format: date-time required: - account_id - balance_usd - available_credits - available_points - alert_threshold - low_balance_alert - updated_at BlendRequest: type: object properties: aspect_ratio: type: string description: Output aspect ratio. enum: - "1:1" - "2:3" - "3:2" default: "1:1" callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imgUrls: type: array description: URLs of the images to blend. items: type: string minItems: 2 maxItems: 5 required: - imgUrls CreditPack: type: object properties: account_id: type: integer active: type: boolean capacity: type: integer created_at: type: string format: date-time deleted_at: type: string format: date-time description: Deletion timestamp; null when the record is active. description: type: string effective_at: type: string format: date-time expired_at: type: string format: date-time external_reference: type: string frozen: type: integer id: type: integer updated_at: type: string format: date-time used: type: integer wallet_id: type: integer required: - id - created_at - updated_at - deleted_at - wallet_id - account_id - active - capacity - frozen - used - effective_at - expired_at - description CreditPackInfo: type: object properties: available_credits: type: integer credit_packs: type: array items: $ref: '#/components/schemas/CreditPack' credit_packs_count: type: integer expired_credits: type: integer frozen_credits: type: integer inactive_credits: type: integer total_credits: type: integer used_credits: type: integer required: - credit_packs_count - total_credits - frozen_credits - used_credits - expired_credits - inactive_credits - available_credits - credit_packs DescribeRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imgUrl: type: string format: uri description: URL of the image to describe. required: - imgUrl DiffusionRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. text: type: string description: Text prompt for image generation. minLength: 1 maxLength: 8192 required: - text EditRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. canvas: $ref: '#/components/schemas/OfficialCanvas' description: Target canvas dimensions. imageNo: type: integer description: Index of the image in the parent task's grid (0-3, left-to-right, top-to-bottom). minimum: 0 maximum: 3 imgPos: $ref: '#/components/schemas/OfficialImagePosition' description: Position and size of the source image on the canvas. jobId: type: string format: uuid description: ID of the original task (the `job_id` returned when it was created). mask: $ref: '#/components/schemas/OfficialMask' description: Optional mask (url max 1024 chars, or areas with width/height 500-4096). remixPrompt: type: string description: Prompt guiding the edit (1-8192 characters). Midjourney --flags are accepted. minLength: 1 maxLength: 8192 required: - jobId - imageNo - canvas - imgPos - remixPrompt EnhanceRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imageNo: type: integer description: Index of the image in the parent task's grid (0-3, left-to-right, top-to-bottom). minimum: 0 maximum: 3 jobId: type: string format: uuid description: ID of the parent draft task. required: - jobId - imageNo EnhanceUpscaleRequest: type: object properties: aspect_ratio: type: string description: Output aspect ratio. enum: - keep - "1:1" - "16:9" - "9:16" - "4:5" - "5:4" - "3:2" - "2:3" - "4:3" - "3:4" default: keep content_type: type: string description: Content type hint for the enhancer. enum: - photo - illustration - text - low_res - standard default: standard crop_mode: type: string description: How to fit the target aspect ratio. enum: - letterbox - crop default: letterbox face_enhancement_level: type: string description: Face enhancement preset. enum: - "off" - none - subtle - moderate - strong default: moderate image_url: type: string description: Direct URL of the image to enhance (must start with http:// or https://). Either `image_url` or `jobId`+`imageNo` is required. maxLength: 2048 pattern: ^https?:// imageNo: type: integer description: Index of the image in the parent task's grid (0-3, left-to-right, top-to-bottom). Required when using `jobId`. minimum: 0 maximum: 3 jobId: type: string format: uuid description: ID of a previous Midjourney task whose grid image should be enhanced. notify_progress: type: boolean output_format: type: string description: Output image format. enum: - jpeg - jpg - png - tiff - tif default: jpeg target_resolution: type: string description: Target resolution preset. enum: - HD - FHD - 2K - 4K - 6K - 8K - 12K default: 2K webhook_endpoint: type: string webhook_schema: type: string webhook_secret: type: string anyOf: - required: - image_url - required: - jobId - imageNo ExtendVideoRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. jobId: type: string format: uuid description: ID of the parent video task. prompt: type: string description: Prompt guiding the extension. minLength: 1 maxLength: 8192 videoNo: type: integer description: Index of the video in the parent grid (0-3). minimum: 0 maximum: 3 required: - jobId - videoNo - prompt ImageOutput: type: object properties: available_actions: type: object image_url: type: string image_urls: type: array items: type: string seed: type: string required: - image_url - image_urls - seed InpaintRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imageNo: type: integer description: Index of the image in the parent task's grid (0-3, left-to-right, top-to-bottom). minimum: 0 maximum: 3 jobId: type: string format: uuid description: ID of the original task (the `job_id` returned when it was created). mask: $ref: '#/components/schemas/OfficialMask' description: Mask selecting the regions to regenerate. Either `url` (mask image, max 1024 chars) or `areas` (rectangles, width/height 500-4096) must be provided. remixPrompt: type: string description: Prompt guiding the edit (1-8192 characters). Midjourney --flags are accepted. minLength: 1 maxLength: 8192 required: - jobId - imageNo - mask - remixPrompt OfficialArea: type: object properties: height: type: integer points: type: array items: type: integer width: type: integer required: - width - height - points OfficialCanvas: type: object properties: height: type: integer width: type: integer required: - width - height OfficialImagePosition: type: object properties: height: type: integer width: type: integer x: type: integer "y": type: integer required: - width - height - x - "y" OfficialMask: type: object properties: areas: type: array items: $ref: '#/components/schemas/OfficialArea' url: type: string required: - url - areas OutpaintRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imageNo: type: integer description: Index of the image in the parent task's grid (0-3, left-to-right, top-to-bottom). minimum: 0 maximum: 3 jobId: type: string format: uuid description: ID of the original task (the `job_id` returned when it was created). remixPrompt: type: string description: Optional prompt guiding the expansion (1-8192 characters when provided). minLength: 1 maxLength: 8192 scale: type: number description: Zoom-out factor. minimum: 1.1 maximum: 2 required: - jobId - imageNo - scale PanRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. direction: type: integer description: 'Extension direction: 0 = down, 1 = right, 2 = up, 3 = left.' enum: - 0 - 1 - 2 - 3 imageNo: type: integer description: Index of the image in the parent task's grid (0-3, left-to-right, top-to-bottom). minimum: 0 maximum: 3 jobId: type: string format: uuid description: ID of the original task (the `job_id` returned when it was created). remixPrompt: type: string description: Optional prompt guiding the extension. maxLength: 8192 scale: type: number description: Extension factor. minimum: 1.1 maximum: 3 required: - jobId - imageNo - direction - scale RemixRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imageNo: type: integer description: Index of the image in the parent task's grid (0-3, left-to-right, top-to-bottom). minimum: 0 maximum: 3 jobId: type: string format: uuid description: ID of the original task (the `job_id` returned when it was created). mode: type: integer description: 'Remix strength: 0 = strong, 1 = subtle.' enum: - 0 - 1 default: 0 remixPrompt: type: string description: Prompt guiding the edit (1-8192 characters). Midjourney --flags are accepted. minLength: 1 maxLength: 8192 required: - jobId - imageNo - remixPrompt RemoveBackgroundRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imgUrl: type: string format: uri description: URL of the source image. maxLength: 1024 required: - imgUrl RerollRequest: type: object properties: jobId: type: string format: uuid description: ID of the original task (the `job_id` returned when it was created). required: - jobId RetextureRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imgUrl: type: string format: uri description: URL of the source image. maxLength: 1024 remixPrompt: type: string description: Prompt guiding the edit (1-8192 characters). Midjourney --flags are accepted. minLength: 1 maxLength: 8192 required: - imgUrl - remixPrompt ShortenRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. prompt: type: string description: Prompt to analyze. minLength: 1 maxLength: 8192 required: - prompt TaskConfig: type: object properties: service_mode: type: string description: Service mode the task runs under. Only `public` is currently supported. enum: - public webhook_config: $ref: '#/components/schemas/TaskWebhookConfig' required: - service_mode - webhook_config TaskError: type: object properties: code: type: integer detail: {} message: type: string raw_message: type: string required: - code - raw_message - message - detail TaskMeta: type: object properties: created_at: type: string format: date-time ended_at: type: string format: date-time started_at: type: string format: date-time usage: $ref: '#/components/schemas/TaskUsage' required: - created_at - started_at - ended_at - usage TaskResponse: type: object properties: config: $ref: '#/components/schemas/TaskConfig' detail: type: "null" description: Reserved for future use; currently null in public API responses. error: $ref: '#/components/schemas/TaskError' input: type: object description: Echo of the task's input parameters (shape depends on `task_type`; mirrors the create-request body of the operation that created the task). Null in error responses. job_id: type: string format: uuid description: Task UUID. Pass it to GET /v1/job/{job_id} to poll, or reference it as `jobId` in follow-up operations. logs: type: array description: Operational log lines of the task (progress events, retries). items: type: string meta: description: Timestamps and billing usage of the task (null in error responses). oneOf: - $ref: '#/components/schemas/TaskMeta' - type: "null" model: type: string description: Model family that executed the task. enum: - midjourney output: description: Task result, present once status is `completed` (null before that). Image/video tasks return URLs; describe/shorten tasks return text prompts. oneOf: - $ref: '#/components/schemas/ImageOutput' - $ref: '#/components/schemas/VideoOutput' - $ref: '#/components/schemas/TextOutput' - type: "null" status: type: string description: 'Lifecycle state. Terminal states: `completed`, `failed`. `staged` means the task is queued behind the account''s concurrency limit; `retry` means it is being resubmitted after a transient provider error.' enum: - pending - staged - processing - retry - completed - failed task_type: type: string description: Type of the task — the operation that created it. enum: - diffusion - upscale - reroll - variation - inpaint - outpaint - pan - edit - remix - enhance - upload_paint - retexture - remove_background - shorten - describe - blend - video_diffusion - extend_video - video_upscale - enhance_upscale required: - job_id - model - task_type - status - config - input - output - meta - detail - logs - error TaskUsage: type: object properties: consume: type: integer frozen: type: integer type: type: string description: Billing unit used for the task. enum: - credit - point required: - type - frozen - consume TaskWebhookConfig: type: object properties: endpoint: type: string secret: type: string required: - endpoint - secret TextOutput: type: object properties: description: type: string finalPrompt: type: string promptEn: type: string prompts: type: array items: type: string required: - promptEn - description - finalPrompt - prompts UploadPaintRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. canvas: $ref: '#/components/schemas/OfficialCanvas' description: Target canvas dimensions. imgPos: $ref: '#/components/schemas/OfficialImagePosition' description: Position and size of the source image on the canvas. imgUrl: type: string format: uri description: URL of the source image. maxLength: 1024 mask: $ref: '#/components/schemas/OfficialMask' description: Mask selecting the regions to regenerate (url max 1024 chars, or areas with width/height 500-4096). remixPrompt: type: string description: Prompt guiding the edit (1-8192 characters). Midjourney --flags are accepted. minLength: 1 maxLength: 8192 required: - imgUrl - canvas - imgPos - mask - remixPrompt UpscaleRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imageNo: type: integer description: Index of the image in the parent task's grid (0-3, left-to-right, top-to-bottom). minimum: 0 maximum: 3 jobId: type: string format: uuid description: ID of the original task (the `job_id` returned when it was created). type: type: integer description: 'Upscale mode: 0 = subtle, 1 = creative (v6/v6.1/niji6/v7). Values 2 (v5 2x) and 3 (v5 4x) are deprecated.' enum: - 0 - 1 - 2 - 3 required: - jobId - imageNo - type VariationRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imageNo: type: integer description: Index of the image in the parent task's grid (0-3, left-to-right, top-to-bottom). minimum: 0 maximum: 3 jobId: type: string format: uuid description: ID of the original task (the `job_id` returned when it was created). remixPrompt: type: string description: Optional prompt guiding the variation (1-8192 characters when provided). minLength: 1 maxLength: 8192 type: type: integer description: 'Variation intensity: 0 = subtle, 1 = strong.' enum: - 0 - 1 required: - jobId - imageNo - type VideoDiffusionRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. imageNo: type: integer description: Index of the image in the parent task's grid (0-3, left-to-right, top-to-bottom). Defaults to 0 for i2v. minimum: 0 maximum: 3 jobId: type: string format: uuid description: Parent image task ID (required for i2v). prompt: type: string description: Motion prompt (required for t2v; must contain an init-image URL). minLength: 1 maxLength: 8192 pattern: https?:// videoType: type: integer description: 'Resolution: 0 = 480p, 1 = 720p.' enum: - 0 - 1 default: 0 anyOf: - required: - jobId - required: - prompt VideoOutput: type: object properties: available_actions: type: object seed: type: string video_urls: type: array items: type: string required: - video_urls - seed VideoUpscaleRequest: type: object properties: callback: type: string format: uri description: Optional webhook URL. When set, the completed TaskResponse is POSTed to this URL; when empty, poll GET /v1/job/{job_id}. jobId: type: string format: uuid description: ID of the parent video task. videoNo: type: integer description: Index of the video in the parent grid (0-3). minimum: 0 maximum: 3 required: - jobId - videoNo Wallet: type: object properties: account_id: type: integer auto_recharge_enabled: type: boolean auto_recharge_target_credit: type: integer auto_recharge_threshold_credit: type: integer created_at: type: string format: date-time credit_packs: type: array items: $ref: '#/components/schemas/CreditPack' deleted_at: type: string format: date-time description: Deletion timestamp; null when the record is active. id: type: integer last_auto_recharge_triggered_at: type: integer last_low_balance_alert_sent_at: type: integer low_balance_alert_enabled: type: boolean low_balance_alert_threshold: type: number point_frozen: type: integer point_remain: type: integer point_used: type: integer updated_at: type: string format: date-time required: - id - created_at - updated_at - deleted_at - account_id - credit_packs - point_remain - point_frozen - point_used - auto_recharge_enabled - auto_recharge_threshold_credit - auto_recharge_target_credit - last_auto_recharge_triggered_at - low_balance_alert_enabled - low_balance_alert_threshold - last_low_balance_alert_sent_at securitySchemes: ApiKeyAuth: type: apiKey in: header name: x-api-key description: 'API key from the Legnext dashboard. `Authorization: Bearer ` is accepted as an alternative.' security: - ApiKeyAuth: [] ``` ---