openapi: 3.0.3
info:
  title: Image Generation API
  x-cld-module-context: cloud
  x-cld-module-name: media-generation
  description: |
    Use the Image Generation API to generate images from text prompts and reference images, using various AI models.

    The API supports Basic Authentication using your Cloudinary API Key and API Secret, which can be found on the [API Keys page](https://console.cloudinary.com/app/settings/api-keys) of your Cloudinary Console.

    **Key Features:**
    * **Unified API**: A single interface for generating images across multiple best-in-class AI models.
    * **Text-to-image**: Generate images from a text prompt.
    * **Image-to-image**: Generate images guided by one or more reference images and a text prompt.
    * **Cloudinary Integration**: Generated images are automatically available for delivery, transformation, and optimization through Cloudinary's platform.
    * **Future-proof**: Adopt new state-of-the-art models as they become available, without rebuilding your integration.
    
    **Model Families (`model.family` / `model.tier`):**
    * **flux**: Photorealistic images (FLUX.2 Klein 9B / FLUX.2 Pro).
    * **recraft**: Vector and illustration (Recraft V3 / Recraft V4).
    * **gpt-image**: Campaign and marketing images (GPT Image 1 Mini / GPT Image 2).
    * **nano-banana**: General purpose generation (Nano Banana 1 / Nano Banana 2).
    * **ideogram**: Realism, text rendering, and artistic generation (Ideogram V4).

    These families are the selection matrix, not the full roster: each family offers a
    `standard` and a `premium` tier. Many models are available only by `model.id` and
    belong to no family — see the `model.id` enum for the complete list.

    The Image Generation API requires the [Cloudinary Image Generation add-on](https://console.cloudinary.com/app/marketplace/details/image_generation).
    
    [Learn more](https://cloudinary.com/documentation/image_generation_addon)

  version: 1.4.0 # x-release-please-version
  license:
    name: UNLICENSED
    url: https://cloudinary.com/tos
  contact:
    name: Cloudinary Support
    url: https://support.cloudinary.com/hc/en-us/requests/new
servers:
  - url: https://api.cloudinary.com/v2
tags:
  - name: Generation
    description: Generate images from text prompts using AI models.
  - name: Tasks
    description: Query the status of async generation tasks.
security:
  - basicAuth: []
  - OAuth2:
    - media_generation
paths:
  /generate/{cloud_name}/text_to_image:
    parameters:
      - $ref: "#/components/parameters/cloudName"
    post:
      x-speakeasy-mcp:
        name: generate-image
        scopes:
          - builder
        title: Generate an Image
      tags:
        - Generation
      summary: Generate an image
      description: |
        Generate an image from a text prompt using AI models.
        
        The model is selected via the optional `model` object:
        1. If `model.id` is provided, use that exact model.
        2. Else if `model.family` (+ optional `model.tier`) is provided, resolve via the model registry; a missing tier defaults to `standard`.
        3. Else if `model.mode` is `auto`, the service picks the model for the request (optionally steered by `model.preference`).
        4. Otherwise, use the global default (nano-banana / premium, i.e. `nano-banana-2`).
      operationId: generate_image
      requestBody:
        required: true
        description: A JSON object containing the generation request parameters.
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GenerateImageRequest"
            examples:
              BasicExample:
                $ref: "#/components/examples/GenerateImageBasicExample"
              DeclarativeSizeExample:
                $ref: "#/components/examples/GenerateImageDeclarativeSizeExample"
              DimensionsSizeExample:
                $ref: "#/components/examples/GenerateImageDimensionsSizeExample"
              AsyncExample:
                $ref: "#/components/examples/GenerateImageAsyncExample"
              AutoModelExample:
                $ref: "#/components/examples/GenerateImageAutoModelExample"
      responses:
        '200':
          description: Image generated successfully (synchronous).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GenerateImageResult"
              examples:
                Success:
                  $ref: "#/components/examples/GenerateImageSuccessExample"
                SuccessManagedAsset:
                  $ref: "#/components/examples/GenerateImageManagedAssetSuccessExample"
        '202':
          $ref: "#/components/responses/GenerationAcceptedResponse"
        '400':
          $ref: "#/components/responses/BadRequestResponse"
        '401':
          $ref: "#/components/responses/UnauthorizedResponse"
        '422':
          $ref: "#/components/responses/UnprocessableEntityResponse"
        '429':
          $ref: "#/components/responses/RateLimitedResponse"
        '500':
          $ref: "#/components/responses/InternalServerErrorResponse"
        '502':
          $ref: "#/components/responses/ModelUnavailableResponse"
  /generate/{cloud_name}/image_to_image:
    parameters:
      - $ref: "#/components/parameters/cloudName"
    post:
      x-speakeasy-mcp:
        name: generate-image-from-images
        scopes:
          - builder
        title: Generate an Image from Reference Images
      tags:
        - Generation
      summary: Generate an image from reference images
      description: |
        Generate an image guided by one or more **reference images** — restyle,
        on-brand variants, character consistency, virtual try-on, edit/extend —
        steered by `prompt`.

        Only edit-capable models are selectable here. The model is selected via
        the optional `model` object, exactly like `text_to_image`, but IDs are
        restricted to edit models:
        1. If `model.id` is provided, use that exact edit model.
        2. Else if `model.family` (+ optional `model.tier`) is provided, resolve
           to that family's edit model (e.g. `nano-banana` / `premium` →
           `nano-banana-2-edit`).
        3. Else if `model.mode` is `auto`, the service picks an edit model for
           the request (optionally steered by `model.preference`).
        4. Otherwise, use the default edit model (`nano-banana-2-edit`).

        Each reference image is either a stored managed asset (by `asset_id`,
        read-permission checked) or an external HTTPS `url`.
      operationId: generate_image_from_images
      requestBody:
        required: true
        description: A JSON object containing the image-to-image generation request parameters.
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ImageToImageRequest"
            examples:
              BasicExample:
                $ref: "#/components/examples/ImageToImageBasicExample"
              FamilyModelExample:
                $ref: "#/components/examples/ImageToImageFamilyModelExample"
              ExplicitModelExample:
                $ref: "#/components/examples/ImageToImageExplicitModelExample"
              AutoModelExample:
                $ref: "#/components/examples/ImageToImageAutoModelExample"
      responses:
        '200':
          description: Image generated successfully (synchronous).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GenerateImageResult"
        '202':
          $ref: "#/components/responses/GenerationAcceptedResponse"
        '400':
          $ref: "#/components/responses/BadRequestResponse"
        '401':
          $ref: "#/components/responses/UnauthorizedResponse"
        '403':
          $ref: "#/components/responses/ForbiddenResponse"
        '404':
          $ref: "#/components/responses/NotFoundResponse"
        '422':
          $ref: "#/components/responses/UnprocessableEntityResponse"
        '429':
          $ref: "#/components/responses/RateLimitedResponse"
        '500':
          $ref: "#/components/responses/InternalServerErrorResponse"
        '502':
          $ref: "#/components/responses/ModelUnavailableResponse"
  /generate/{cloud_name}/tasks/{task_id}:
    parameters:
      - $ref: "#/components/parameters/cloudName"
      - in: path
        name: task_id
        description: The ID of the generation task.
        required: true
        schema:
          type: string
          pattern: '^[a-f0-9]{1,256}$'
        example: 053f4bde4b933c8ecef23724ecde63b667c1ea21816d56c161c7ec1df6297da4b43109625650e9edf0f42152cc4cc32c8ad57824ac75ba8e05020f827c415559ac1248076a2d72c0a73af0479cca77eb
    get:
      x-speakeasy-mcp:
        name: get-generation-task
        scopes:
          - builder
        title: Get a Generation Task
        readOnlyHint: true
        idempotentHint: true
      tags:
        - Tasks
      summary: Get a generation task
      description: Get the status of a generation task.
      operationId: get_generation_task_status
      responses:
        '200':
          description: Generation task status.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskResponse'
              examples:
                Completed:
                  $ref: "#/components/examples/GenerateTaskCompletedExample"
        '400':
          $ref: "#/components/responses/BadRequestResponse"
        '401':
          $ref: "#/components/responses/UnauthorizedResponse"
        '404':
          $ref: "#/components/responses/NotFoundResponse"
        '429':
          $ref: "#/components/responses/RateLimitedResponse"
        '500':
          $ref: "#/components/responses/InternalServerErrorResponse"
components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: Basic authentication using Cloudinary API Key and API Secret.
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://oauth.cloudinary.com/oauth2/auth
          tokenUrl: https://oauth.cloudinary.com/oauth2/token
          scopes:
            media_generation: Generate media
  parameters:
    cloudName:
      in: path
      name: cloud_name
      description: The cloud name of your Cloudinary product environment.
      example: your-cloud-name
      schema:
        type: string
      required: true
  responses:
    GenerationAcceptedResponse:
      description: Generation accepted.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TaskResponse"
    BadRequestResponse:
      description: Bad request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    UnauthorizedResponse:
      description: Unauthorized.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFoundResponse:
      description: Not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimitedResponse:
      description: Rate limited.
      content:
        application/json:
          schema:
            type: object
            title: "RateLimitedResponse"
            required:
              - error
              - request_id
            properties:
              error:
                $ref: '#/components/schemas/Error'
              limits:
                $ref: '#/components/schemas/Limits'
              notices:
                $ref: '#/components/schemas/Notices'
              request_id:
                type: string
                description: Unique identifier for this request, for correlation and support.
                example: 17c3b70c5096df0e77e838323abb7029
          examples:
            RateLimited:
              $ref: "#/components/examples/RateLimitedExample"
    InternalServerErrorResponse:
      description: Internal server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ModelUnavailableResponse:
      description: Model unavailable.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ForbiddenResponse:
      description: Forbidden.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    UnprocessableEntityResponse:
      description: Unprocessable entity.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  schemas:
    GenerateImageRequest:
      type: object
      description: |
        Parameters for an image-generation request. Only `prompt` is required;
        all other fields fall back to documented defaults.
      required:
        - prompt
      properties:
        prompt:
          type: string
          minLength: 1
          maxLength: 16384
          description: The text description of the image to generate.
          example: A photorealistic sunset over a mountain lake
        model:
          $ref: "#/components/schemas/ModelSelection"
        image_size:
          $ref: "#/components/schemas/ImageSize"
        format:
          $ref: "#/components/schemas/ImageFormat"
        target:
          $ref: "#/components/schemas/Target"
        seed:
          $ref: "#/components/schemas/Seed"
        async:
          $ref: "#/components/schemas/Async"
        notification_url:
          $ref: "#/components/schemas/NotificationUrl"
    ImageFormat:
      type: string
      enum:
        - jpeg
        - png
        - webp
      description: |
        Desired output image format. Optional; defaults to `png` when omitted.
        Mapped to the closest format the chosen model supports — `webp` falls
        back to `png` on models that don't support it (e.g. FLUX.2 Pro), and the
        request is ignored entirely by models that don't expose a format option
        (e.g. Recraft).
      example: png
    Seed:
      type: integer
      nullable: true
      minimum: 0
      description: |
        Seed for reproducible generation. Supported by the `flux`, `nano-banana`
        and `ideogram` models and by `qwen-image-3`; silently ignored by the
        models that don't support it, which report `seed` as null in the
        response.
      example: 42
    Async:
      type: boolean
      default: false
      description: |
        Whether to perform the generation asynchronously. When true, the API
        returns immediately with a 202 and completes in the background. Once
        complete, a webhook notification is sent to the specified URL and/or to
        the URLs defined in the product environment's settings.
    NotificationUrl:
      type: string
      format: uri
      description: The webhook URL to notify when the generation is complete. Only relevant when `async` is set to true.
      example: https://path.to/webhook
    ImageToImageRequest:
      type: object
      description: |
        Parameters for an image-to-image (reference-guided) request. Both
        `prompt` (the edit instruction) and `reference_images` are required; all
        other fields fall back to the same defaults as `text_to_image`.
      required:
        - prompt
        - reference_images
      properties:
        prompt:
          type: string
          minLength: 1
          maxLength: 16384
          description: The text instruction describing the desired edit / output.
          example: Place the product from [1] on a marble kitchen counter, soft morning light
        reference_images:
          type: array
          minItems: 1
          maxItems: 4
          description: |
            Reference images that steer the generation, in order (1-indexed; the
            prompt may address them positionally as `[1]`, `[2]`, …). Each entry
            is either a managed asset (by `asset_id`) or an external `url`. The
            platform accepts up to 4; a specific model may accept fewer — the
            `recraft-v3-edit` and `mai-image` edit models accept 1, and the
            `grok-imagine` and `qwen-image` edit models accept 3. Exceeding the
            selected model's capacity returns 400.
          items:
            $ref: "#/components/schemas/ReferenceImage"
        model:
          $ref: "#/components/schemas/ModelSelection"
        image_size:
          $ref: "#/components/schemas/ImageSize"
        format:
          $ref: "#/components/schemas/ImageFormat"
        target:
          $ref: "#/components/schemas/Target"
        seed:
          $ref: "#/components/schemas/Seed"
        async:
          $ref: "#/components/schemas/Async"
        notification_url:
          $ref: "#/components/schemas/NotificationUrl"
    ReferenceImage:
      description: |
        A single reference image, in **one** of two mutually exclusive forms
        determined by `source_type`:
          * `ManagedAssetReference`: a managed asset in the caller's product
            environment, by `asset_id` (read permission is checked).
          * `UrlReference`: an external image by HTTPS `url`.
      oneOf:
        - $ref: "#/components/schemas/ManagedAssetReference"
        - $ref: "#/components/schemas/UrlReference"
      discriminator:
        propertyName: source_type
        mapping:
          managed_asset: "#/components/schemas/ManagedAssetReference"
          url: "#/components/schemas/UrlReference"
    ManagedAssetReference:
      type: object
      title: ManagedAssetReference
      description: |
        A reference to a managed asset in the caller's product environment, by
        asset ID.
      additionalProperties: false
      required:
        - source_type
        - asset_id
      properties:
        source_type:
          type: string
          description: Discriminator identifying this as a managed-asset reference.
          enum:
            - managed_asset
        asset_id:
          type: string
          description: Cloudinary asset ID of the reference image. READ permission is enforced.
          example: 0d6f8e1c2b3a4d5e6f7a8b9c0d1e2f3a
    UrlReference:
      type: object
      title: UrlReference
      description: A reference to an external image by HTTPS URL.
      additionalProperties: false
      required:
        - source_type
        - url
      properties:
        source_type:
          type: string
          description: Discriminator identifying this as an external-URL reference.
          enum:
            - url
        url:
          type: string
          format: uri
          description: HTTPS URL of the reference image.
          example: https://example.com/product.png
    ModelSelection:
      description: |
        Selects the model, in one of three mutually exclusive forms (omit to use
        the global default):
          * `ModelByFamily`: `family` (+ optional `tier`); the stable-over-time
            selector.
          * `ModelById`: an explicit `id`, pinning one exact model.
          * `ModelAuto`: `mode: auto`, letting the service choose the model for
            the request (+ optional `preference`).
      oneOf:
        - $ref: "#/components/schemas/ModelByFamily"
        - $ref: "#/components/schemas/ModelById"
        - $ref: "#/components/schemas/ModelAuto"
    ModelByFamily:
      type: object
      title: ModelByFamily
      description: |
        Select a model by family and quality tier; a missing `tier` defaults to
        `standard`.
      additionalProperties: false
      required:
        - family
      properties:
        family:
          type: string
          enum:
            - flux
            - recraft
            - gpt-image
            - nano-banana
            - ideogram
          description: |
            Model family:
            * `flux`: Photorealistic images (FLUX.2 Klein 9B / FLUX.2 Pro).
            * `recraft`: Vector and illustration (Recraft V3 / Recraft V4).
            * `gpt-image`: Campaign and marketing images (GPT Image 1 Mini / GPT Image 2).
            * `nano-banana`: General purpose generation (Nano Banana 1 / Nano Banana 2).
            * `ideogram`: Realism, text rendering, and artistic generation (Ideogram V4).
          example: flux
        tier:
          type: string
          enum:
            - standard
            - premium
          description: Quality tier within the family. Defaults to `standard` when omitted.
          example: premium
    ModelById:
      type: object
      title: ModelById
      description: Pin an exact model by ID, bypassing family/tier.
      additionalProperties: false
      required:
        - id
      properties:
        id:
          type: string
          enum:
            - nano-banana-1
            - nano-banana-2
            - nano-banana-2-lite
            - flux-2-klein-9b
            - flux-2-pro
            - flux-2-flash
            - recraft-v3
            - recraft-v4
            - gpt-image-1-mini
            - gpt-image-2
            - gpt-image-2.5-flare
            - gpt-image-2.5-sunburst
            - muse-image
            - mai-image-2.5
            - mai-image-2.5-pro
            - seedream-5-pro
            - grok-imagine-image
            - recraft-v4.1-utility
            - recraft-v4.1-utility-pro
            - seedream-5-lite
            - grok-imagine-image-2.0-low
            - qwen-image-3
            - ideogram-v4-base
            - ideogram-v4-turbo
            # Edit models — same model kind, used by image_to_image (they accept
            # reference images). Selectable only on the image_to_image endpoint.
            - nano-banana-1-edit
            - nano-banana-2-edit
            - nano-banana-2-lite-edit
            - flux-2-klein-9b-edit
            - flux-2-pro-edit
            - flux-2-flash-edit
            - recraft-v3-edit
            - gpt-image-1-mini-edit
            - gpt-image-2-edit
            - gpt-image-2.5-flare-edit
            - gpt-image-2.5-sunburst-edit
            - muse-image-edit
            - mai-image-2.5-edit
            - mai-image-2.5-pro-edit
            - seedream-5-pro-edit
            - grok-imagine-image-edit
            - seedream-5-lite-edit
            - grok-imagine-image-2.0-low-edit
            - qwen-image-3-edit
          description: |
            Exact model identifier; overrides family/tier when provided. The
            `-edit` models accept reference images and are selectable only on
            `image_to_image`; the others only on `text_to_image`.
          example: flux-2-pro
    ModelAuto:
      type: object
      title: ModelAuto
      description: |
        Let the service choose the model for this request. The response reports
        the resolved model in `data.assets[].model`, as for the other forms; on
        `image_to_image` it is always an edit model.
      additionalProperties: false
      required:
        - mode
      properties:
        mode:
          type: string
          enum:
            - auto
          description: The only valid value; selects automatic model selection.
          example: auto
        preference:
          type: string
          enum:
            - balanced
            - quality
            - economy
            - balanced_fast
            - quality_fast
            - economy_fast
          default: balanced
          description: |
            What the choice optimizes for:
            * `balanced` (default): quality and cost weighted equally.
            * `quality`: quality only; cost isn't weighed.
            * `economy`: cost first, quality second.
            * `balanced_fast`, `quality_fast`, `economy_fast`: as above, but also
              favor faster generation, and never pick a model that typically
              takes longer than 30 seconds.
          example: quality
    ImageSize:
      description: |
        Desired output size, given in **one** of two mutually exclusive forms:

          * `DimensionsImageSize`: `width` and `height` in pixels, for precise
            control.
          * `DeclarativeImageSize`: `aspect_ratio` (and an optional `resolution`
            tier), resolved server-side to the closest size the chosen model
            supports. This is the portable form: most providers natively accept
            an aspect ratio plus a resolution tier rather than raw pixels.

        Omit `image_size` entirely to use the model's default size.
      oneOf:
        - $ref: "#/components/schemas/DimensionsImageSize"
        - $ref: "#/components/schemas/DeclarativeImageSize"
    DimensionsImageSize:
      type: object
      title: DimensionsImageSize
      description: Exact output dimensions in pixels. Both `width` and `height` are required together.
      additionalProperties: false
      required:
        - width
        - height
      properties:
        width:
          type: integer
          minimum: 64
          maximum: 4096
          description: Output width in pixels.
          example: 1280
        height:
          type: integer
          minimum: 64
          maximum: 4096
          description: Output height in pixels.
          example: 720
    DeclarativeImageSize:
      type: object
      title: DeclarativeImageSize
      description: |
        Declarative output size — an aspect ratio plus an optional resolution
        tier, resolved server-side to the nearest size the model supports.
      additionalProperties: false
      required:
        - aspect_ratio
      properties:
        aspect_ratio:
          type: string
          description: |
            Output aspect ratio, width-to-height. Limited to the core ratios
            every model supports natively.
          enum:
            - "1:1"
            - "16:9"
            - "9:16"
            - "4:3"
            - "3:4"
          example: "16:9"
        resolution:
          type: string
          description: |
            Output resolution tier, measured on the longest edge. Defaults to
            `1K` when omitted.
            * `0.5K`: ~512 px
            * `1K`: ~1024 px
            * `2K`: ~2048 px
            * `4K`: ~4096 px
          enum:
            - 0.5K
            - 1K
            - 2K
            - 4K
          example: 2K
    Target:
      description: |
        Where to store the generated output, determined by `target_type`.
        Optional; defaults to a `managed_asset` target when omitted.
      oneOf:
        - $ref: "#/components/schemas/ManagedAssetTarget"
        - $ref: "#/components/schemas/TemporaryTarget"
      discriminator:
        propertyName: target_type
        mapping:
          managed_asset: "#/components/schemas/ManagedAssetTarget"
          temporary: "#/components/schemas/TemporaryTarget"
    ManagedAssetTarget:
      type: object
      description: Store the output as a permanent managed asset in your Cloudinary product environment (the default).
      additionalProperties: false
      required:
        - target_type
      properties:
        target_type:
          type: string
          description: Discriminator identifying this as a managed-asset target.
          enum:
            - managed_asset
        public_id:
          type: string
          description: Public ID to store the asset under. Auto-assigned when omitted.
          example: my-public-id
        upload_preset:
          type: string
          description: Upload preset to apply. Uses the product environment's default when omitted.
          example: some-preset
    TemporaryTarget:
      type: object
      description: Store the output as a short-lived asset on the upload service.
      additionalProperties: false
      required:
        - target_type
      properties:
        target_type:
          type: string
          description: Discriminator identifying this as a temporary target.
          enum:
            - temporary
    Storage:
      description: |
        Where a generated asset is stored — mirrors the request `target`,
        determined by `storage_type`. `secure_url` is always present.
      oneOf:
        - $ref: "#/components/schemas/ManagedAssetStorage"
        - $ref: "#/components/schemas/TemporaryStorage"
      discriminator:
        propertyName: storage_type
        mapping:
          managed_asset: "#/components/schemas/ManagedAssetStorage"
          temporary: "#/components/schemas/TemporaryStorage"
    ManagedAssetStorage:
      type: object
      description: |
        A generated asset stored as a permanent managed asset. Reference it in
        other Cloudinary APIs by `asset_id`, or by the
        `resource_type` / `type` / `public_id` triple.
      additionalProperties: false
      required:
        - storage_type
        - secure_url
        - public_id
        - resource_type
        - type
        - version
      properties:
        storage_type:
          type: string
          description: Discriminator identifying this as managed-asset storage.
          enum:
            - managed_asset
        secure_url:
          type: string
          format: uri
          description: The URL to fetch the generated asset.
          example: https://res.cloudinary.com/demo/image/upload/v1/my-public-id.png
        asset_id:
          type: string
          description: Cloudinary asset ID — a stable, globally-unique reference to the asset.
          example: 0d6f8e1c2b3a4d5e6f7a8b9c0d1e2f3a
        public_id:
          type: string
          description: Public ID of the stored asset.
          example: my-public-id
        resource_type:
          type: string
          description: Cloudinary resource type of the stored asset.
          enum:
            - image
            - video
            - raw
          example: image
        type:
          type: string
          description: Cloudinary delivery type of the stored asset (e.g. `upload`, `private`, `authenticated`).
          example: upload
        version:
          type: integer
          format: int64
          description: Version of the stored asset.
    TemporaryStorage:
      type: object
      description: A generated asset stored as a short-lived asset on the upload service.
      additionalProperties: false
      required:
        - storage_type
        - secure_url
        - expires_at
      properties:
        storage_type:
          type: string
          description: Discriminator identifying this as temporary storage.
          enum:
            - temporary
        secure_url:
          type: string
          format: uri
          description: The URL to fetch the generated asset.
          example: https://upload-global.cloudinary.com/v2/demo/uploads/a78a2e043c2da0b50a98961d60a8b05a/stream
        expires_at:
          type: string
          format: date-time
          description: Time in UTC when secure_url stops being valid.
          example: "2026-06-25T12:50:26Z"
    GenerateImageResult:
      type: object
      description: Successful synchronous image-generation response.
      required:
        - request_id
      properties:
        data:
          $ref: "#/components/schemas/GeneratedAssets"
        limits:
          $ref: "#/components/schemas/Limits"
        notices:
          $ref: "#/components/schemas/Notices"
        request_id:
          type: string
          description: Unique identifier for this request, for correlation and support.
          example: 17c3b70c5096df0e77e838323abb7029
    GeneratedAssets:
      type: object
      description: Wrapper holding the array of generated assets.
      required:
        - assets
      properties:
        assets:
          type: array
          description: The generated assets. Currently a single asset is returned.
          items:
            $ref: "#/components/schemas/GeneratedAsset"
    GeneratedAsset:
      type: object
      description: |
        A generated asset: where it is stored (`storage`) plus its media
        metadata. The media fields are populated once the task completes; an
        in-progress asset carries only `storage`.
      required:
        - storage
      properties:
        storage:
          $ref: "#/components/schemas/Storage"
        format:
          type: string
          enum:
            - png
            - jpeg
            - webp
          description: The image format of the stored asset.
          example: png
        width:
          type: integer
          description: The width of the generated image in pixels; zero if the model doesn't provide dimensions.
          example: 1024
        height:
          type: integer
          description: The height of the generated image in pixels; zero if the model doesn't provide dimensions.
          example: 768
        bytes:
          type: integer
          format: int64
          description: The size of the generated image in bytes.
          example: 2048576
        model:
          $ref: "#/components/schemas/Model"
        seed:
          type: integer
          nullable: true
          description: |
            The seed used for generation. Echoes input or returns the model-generated seed.
            Null when the model doesn't support seeds.
          example: 42
        created_at:
          type: string
          format: date-time
          description: The timestamp when the image was generated.
          example: "2026-04-21T14:30:00Z"
    Model:
      type: object
      description: Identifies the model that produced a generation result.
      required:
        - family
        - tier
        - id
      properties:
        family:
          type: string
          description: |
            The family this model belongs to. `none` when the model is not part
            of any family.

            A family holds exactly two tiers (`standard` and `premium`), so the
            family/tier taxonomy names only part of the roster. The remaining
            models are selected by `id` alone and are not part of any family,
            which is reported as `none` rather than as a family the model does
            not belong to. This describes the model, not how it was selected: a
            model that belongs to a family reports it whether it was chosen by
            `family` and `tier` or pinned by `id`.

            Not an enum: new families are added over time, so treat any value
            as possible.
          example: flux
        tier:
          type: string
          description: |
            The quality tier this model holds within its family. `none` when
            the model is not part of any family. See `family`.
          example: premium
        id:
          type: string
          description: |
            The exact model identifier used for generation. Always a concrete
            model, and the reliable field to key on: unlike `family` and
            `tier`, it is never `none`.
          example: flux-2-pro
    TaskStatus:
      type: string
      description: |
        The status of an async generation task.
        * `pending`: accepted and queued, not yet started.
        * `processing`: generation is in progress.
        * `completed`: generation finished; `result` is populated.
        * `failed`: generation did not complete successfully.
      enum:
        - pending
        - processing
        - completed
        - failed
    Task:
      type: object
      description: |
        An async generation task. Returned when a generation is accepted (202)
        and from GET /tasks/{task_id} as it progresses. The `result` is filled
        in once `status` is `completed`.
      required:
        - task_id
        - status
      properties:
        task_id:
          type: string
          description: Identifier for the async generation task. Use it to poll `GET /generate/{cloud_name}/tasks/{task_id}`.
          example: 053f4bde4b933c8ecef23724ecde63b667c1ea21816d56c161c7ec1df6297da4b43109625650e9edf0f42152cc4cc32c8ad57824ac75ba8e05020f827c415559ac1248076a2d72c0a73af0479cca77eb
        status:
          $ref: '#/components/schemas/TaskStatus'
        result:
          type: object
          allOf:
            - $ref: '#/components/schemas/GeneratedAssets'
          nullable: true
          description: |
            The generated assets. Populated once `status` is `completed`.
        limits:
          $ref: '#/components/schemas/Limits'
    TaskResponse:
      type: object
      description: |
        Envelope for an async generation task — returned by the accepted (202)
        response and by GET /tasks/{task_id}.
      required:
        - request_id
      properties:
        data:
          $ref: '#/components/schemas/Task'
        notices:
          $ref: '#/components/schemas/Notices'
        request_id:
          type: string
          description: Unique identifier for this request, for correlation and support.
          example: 17c3b70c5096df0e77e838323abb7029
      example:
        data:
          task_id: "053f4bde4b933c8ecef23724ecde63b667c1ea21816d56c161c7ec1df6297da4b43109625650e9edf0f42152cc4cc32c8ad57824ac75ba8e05020f827c415559ac1248076a2d72c0a73af0479cca77eb"
          status: pending
        request_id: "17c3b70c5096df0e77e838323abb7029"
    ErrorResponse:
      type: object
      description: Wrapper for error responses; includes the error object and a request_id for correlation.
      required:
        - error
        - request_id
      properties:
        error:
          $ref: '#/components/schemas/Error'
        notices:
          $ref: '#/components/schemas/Notices'
        request_id:
          type: string
          description: Unique identifier for this request, for correlation and support.
          example: 17c3b70c5096df0e77e838323abb7029
    Error:
      type: object
      description: Details of an error, including a coarse category for retry logic, a stable error code, and a human-readable message.
      example:
        category: user_error
        code: MG_00001
        message: missing parameters
        details:
          parameters: [param1, param2]
      properties:
        category:
          $ref: "#/components/schemas/ErrorCategory"
        code:
          type: string
          description: Stable, machine-readable error code for programmatic handling.
          example: MG_00001
        message:
          type: string
          description: Human-readable description of what went wrong.
          example: missing parameters
        details:
          type: object
          description: Additional structured context about the error, when available.
          example:
            parameters: [prompt]
    ErrorCategory:
      type: string
      description: |
        Coarse classification of an error, primarily used by clients to decide whether to retry.
        * `user_error`: the request was invalid; do not retry without changes.
        * `auth_error`: authentication or authorization failed.
        * `server_error`: an unexpected server-side error; retrying may succeed.
        * `rate_limit_error`: quota or rate limit exceeded; retry later.
      enum:
        - user_error
        - auth_error
        - server_error
        - rate_limit_error
    Notices:
      type: array
      x-experimental: true
      description: |
        Tips and guidance attached to the response to help you get the most
        out of the generation. Each entry is plain text you can show to a
        user or act on as-is. Omitted when there is nothing to add.
      items:
        $ref: '#/components/schemas/Notice'
      example:
        - severity: warning
          text: >-
            You've used 40 of your 50 Image Generation credits. 10 remain. Tell the
            user the balance is nearly spent, do not estimate how many images it
            covers, and show them: https://console.cloudinary.com/app/image/generation/plans
    Notice:
      type: object
      required:
        - severity
        - text
      properties:
        severity:
          type: string
          description: |
            How much weight to give the message.
            * `info`: for awareness; nothing to do.
            * `warning`: worth relaying to the user before continuing.
            * `blocking`: the request was not served; the text says what unblocks it.
          enum:
            - info
            - warning
            - blocking
        text:
          type: string
          description: The tip or guidance, in plain text. Show it as-is or follow it; the wording may change between releases.
          example: "This model does not output webp; the image was stored as png. Deliver it with f_auto or f_webp to get webp."
    Limits:
      type: object
      description: Rate limit information for the account's add-on quotas.
      properties:
        addons_quota:
          type: array
          description: Per-add-on quota usage for this account.
          items:
            $ref: '#/components/schemas/AddonQuota'
          example: [ { type: "image_generation", used_by_request: 1, remaining: 48, limit: 50 } ]
    AddonQuota:
      type: object
      description: Quota usage for a single add-on.
      required:
        - type
        - used_by_request
        - remaining
        - limit
      properties:
        type:
          $ref: '#/components/schemas/Feature'
        used_by_request:
          type: integer
          nullable: true
          description: Number of generations consumed by this request.
        remaining:
          type: integer
          nullable: true
          description: Generations remaining in the current period.
        limit:
          type: integer
          nullable: true
          description: Maximum generations allowed per period.
    Feature:
      type: string
      description: The add-on a quota applies to.
      enum:
        - image_generation
  examples:
    GenerateImageBasicExample:
      summary: Basic image generation
      description: Minimal request — only a prompt; falls back to the default model.
      value:
        prompt: A man with a hat
    GenerateImageDeclarativeSizeExample:
      summary: Declarative size (aspect ratio + resolution)
      description: |
        Portable size selection — the service resolves aspect_ratio + resolution
        to the nearest dimensions the chosen model supports.
      value:
        prompt: A photorealistic sunset over a mountain lake
        model:
          family: flux
          tier: premium
        image_size:
          aspect_ratio: "16:9"
          resolution: 2K
        target:
          target_type: managed_asset
          public_id: my-public-id
          upload_preset: some-preset
        seed: 42
    GenerateImageDimensionsSizeExample:
      summary: Dimensions size (explicit pixels)
      description: Pixel-precise size selection via width + height.
      value:
        prompt: A photorealistic sunset over a mountain lake
        model:
          id: flux-2-pro
        image_size:
          width: 1280
          height: 720
        target:
          target_type: temporary
        seed: 42
    GenerateImageAsyncExample:
      summary: Async image generation
      description: |
        Request the generation be performed asynchronously. The API responds
        202 with a task_id; the caller polls /tasks/{task_id} or waits for
        the webhook.
      value:
        prompt: A futuristic city skyline at night
        model:
          family: gpt-image
          tier: premium
        async: true
        notification_url: https://path.to/webhook
    GenerateImageAutoModelExample:
      summary: Automatic model selection
      description: |
        Let the service choose the model for the prompt; `preference` says what
        the choice optimizes for (default `balanced`). The response echoes the
        model that was actually used.
      value:
        prompt: A photorealistic sunset over a mountain lake
        model:
          mode: auto
          preference: quality
        image_size:
          aspect_ratio: "16:9"
          resolution: 2K
        target:
          target_type: temporary
        seed: 42
    ImageToImageBasicExample:
      summary: Basic image-to-image edit
      description: |
        Minimal request: an edit instruction and one reference image by HTTPS
        URL; falls back to the default edit model.
      value:
        prompt: Place the product from [1] on a marble kitchen counter, soft morning light
        reference_images:
          - source_type: url
            url: https://example.com/product.png
    ImageToImageFamilyModelExample:
      summary: Edit model by family and tier
      description: |
        Select the edit model by family (+ optional tier); the family resolves to
        that family's edit model, here `nano-banana-2-edit`.
      value:
        prompt: Restyle [1] as a watercolor painting, keep the composition
        reference_images:
          - source_type: managed_asset
            asset_id: 0d6f8e1c2b3a4d5e6f7a8b9c0d1e2f3a
        model:
          family: nano-banana
          tier: premium
        image_size:
          aspect_ratio: "4:3"
          resolution: 1K
        target:
          target_type: temporary
        seed: 42
    ImageToImageExplicitModelExample:
      summary: Edit model by ID
      description: |
        Pin one exact edit model by ID. Only `-edit` models are selectable on
        this endpoint.
      value:
        prompt: Replace the background of [1] with a bright studio backdrop
        reference_images:
          - source_type: url
            url: https://example.com/product.png
        model:
          id: flux-2-pro-edit
        image_size:
          width: 1280
          height: 720
        target:
          target_type: managed_asset
          public_id: my-public-id
          upload_preset: some-preset
        seed: 42
    ImageToImageAutoModelExample:
      summary: Automatic edit-model selection
      description: |
        Let the service choose the edit model for the reference images and the
        instruction; the resolved model in the response is always an `-edit` model.
      value:
        prompt: Make it look like a watercolor painting, keep the composition
        reference_images:
          - source_type: url
            url: https://example.com/photo.jpg
        model:
          mode: auto
        image_size:
          aspect_ratio: "4:3"
          resolution: 1K
    GenerateImageSuccessExample:
      summary: Successful synchronous generation
      description: The 200 response body returned for a completed sync generation.
      value:
        data:
          assets:
            - storage:
                storage_type: temporary
                secure_url: https://upload-global.cloudinary.com/v2/demo/uploads/a78a2e043c2da0b50a98961d60a8b05a/image.png
                expires_at: "2026-06-25T12:50:26Z"
              format: png
              width: 1024
              height: 768
              bytes: 2048576
              model:
                family: flux
                tier: premium
                id: flux-2-pro
              seed: 42
              created_at: "2026-04-21T14:30:00Z"
        limits:
          addons_quota:
            - type: image_generation
              used_by_request: 1
              remaining: 48
              limit: 50
        request_id: 17c3b70c5096df0e77e838323abb7029
    GenerateImageManagedAssetSuccessExample:
      summary: Successful synchronous generation (managed asset target)
      description: The 200 response body when the request targeted a managed asset.
      value:
        data:
          assets:
            - storage:
                storage_type: managed_asset
                secure_url: https://res.cloudinary.com/demo/image/upload/v1750000000/my-public-id.png
                asset_id: 0d6f8e1c2b3a4d5e6f7a8b9c0d1e2f3a
                public_id: my-public-id
                resource_type: image
                type: upload
                version: 1750000000
              format: png
              width: 1024
              height: 768
              bytes: 2048576
              model:
                family: flux
                tier: premium
                id: flux-2-pro
              seed: 42
              created_at: "2026-04-21T14:30:00Z"
        limits:
          addons_quota:
            - type: image_generation
              used_by_request: 1
              remaining: 48
              limit: 50
        request_id: 17c3b70c5096df0e77e838323abb7029
    GenerateTaskCompletedExample:
      summary: Completed task (GET /tasks/{task_id})
      description: A completed async task — the asset is fully populated (storage + media).
      value:
        data:
          task_id: "053f4bde4b933c8ecef23724ecde63b667c1ea21816d56c161c7ec1df6297da4b43109625650e9edf0f42152cc4cc32c8ad57824ac75ba8e05020f827c415559ac1248076a2d72c0a73af0479cca77eb"
          status: completed
          result:
            assets:
              - storage:
                  storage_type: temporary
                  secure_url: https://upload-global.cloudinary.com/v2/demo/uploads/a78a2e043c2da0b50a98961d60a8b05a/stream
                  expires_at: "2026-06-25T12:50:26Z"
                format: png
                width: 1024
                height: 768
                bytes: 2048576
                model:
                  family: flux
                  tier: premium
                  id: flux-2-pro
                seed: 42
                created_at: "2026-04-21T14:30:00Z"
        request_id: 17c3b70c5096df0e77e838323abb7029
    RateLimitedExample:
      summary: 429 rate-limited response
      description: Returned when the account has exhausted its generation quota for the period.
      value:
        error:
          category: rate_limit_error
          code: MG_00429
          message: Daily generation limit exceeded. Limit resets at 2026-04-22T00:00:00Z
        limits:
          addons_quota:
            - type: image_generation
              used_by_request: 1
              remaining: 0
              limit: 50
        request_id: 17c3b70c5096df0e77e838323abb7029
