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 <key>` 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
        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
        - 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 <key>` is
        accepted as an alternative.
security:
  - ApiKeyAuth: []
