> ## Documentation Index
> This page is part of the Image and Video APIs product. Fetch the complete documentation index for Image and Video APIs at: https://cloudinary.com/documentation/llms-image-and-video-apis.txt?referrer=docpage and then use it to discover all relevant pages before exploring further.
> If your task extends beyond this product, fetch the top-level index covering all Cloudinary products and topics at: https://cloudinary.com/documentation/llms.txt?referrer=docpage

# Cloudinary Image Generation


Cloudinary Image Generation lets you generate images from a text prompt, optionally guided by one or more reference images, using a unified API that supports multiple best-in-class AI model families. Generated images are automatically available in your Cloudinary product environment for delivery, transformation, and optimization.

You can generate images in two ways: through the [Cloudinary Console](#generating_images_via_the_console) or through the [API](#generating_images_via_the_api).

## Getting started

Before you can use the Cloudinary Image Generation add-on:

* You must have a Cloudinary account. If you don't already have one, you can [sign up](https://cloudinary.com/users/register_free) for a free account.

* Register for the add-on: make sure you're logged in to your account and then go to the [Image Generation add-on](https://console.cloudinary.com/app/marketplace/details/image_generation) page. For more information about add-on registrations, see [Registering for add-ons](cloudinary_add_ons#registering_for_add_ons).

When you generate your first image through the [Cloudinary Console](#generating_images_via_the_console), you're automatically subscribed to the free plan. To increase your usage quota, [upgrade your plan](https://console.cloudinary.com/app/settings/billing/change_plan/feature:image_generation) in the Cloudinary Console.

## Generating images via the Console

You can generate images directly from the Cloudinary Console without writing any code.

1. In the [Cloudinary Console](https://console.cloudinary.com/app/image/generation/sandbox), go to **Image > Image Generation**. 
1. Enter a text description of the image you want to create.
1. Optionally add up to four reference images to include in the generated image.
1. Select a specific **Model** or let Cloudinary automatically decide which model to use.
1. Optionally, expand **Advanced Settings** to configure aspect ratio and resolution.
1. Click **Generate with AI** to generate the image.

The **Preview** panel displays the generated image. The **Code** panel on the right shows the equivalent API call in cURL so you can reproduce the result programmatically.

![Image Generation details page](https://cloudinary-res.cloudinary.com/image/upload/bo_1px_solid_gray/f_auto/q_auto/docs/image_generation_console.png "thumb: c_scale,w_700,dpr_2, width:700")

Images generated via the Console are automatically saved to your Media Library and you can copy the URL of the image ready for optimized delivery.

## Generating images via the API

Use the Image Generation API to generate images programmatically from a text prompt, optionally guided by reference images, and integrate them directly into your workflows.

For the full API reference, see the [Image Generation API reference](image_generation_api_reference).

### Endpoints and authentication

The API has two endpoints, both taking a `POST` request with a JSON body:

{table:class=model-table model-table-two-col} Endpoint | Generates an image from |
|----------|-------------------------|
| `POST /v2/generate/<CLOUD_NAME>/text_to_image` | A text prompt. |
| `POST /v2/generate/<CLOUD_NAME>/image_to_image` | A text prompt and up to 4 reference images. See [Generate an image from reference images](#generate_an_image_from_reference_images). |

Both accept the same parameters otherwise, and both can run [synchronously or asynchronously](#generate_an_image_asynchronously).

The Image Generation API uses HTTP Basic Authentication. Pass your **API Key** as the username and your **API Secret** as the password, either in the URL or in the `-u` flag:

```
curl -X POST https://<API_KEY>:<API_SECRET>@api.cloudinary.com/v2/generate/<CLOUD_NAME>/text_to_image
```

You can find your Cloud name, API Key, and API Secret on the [API Keys](https://console.cloudinary.com/app/settings/api-keys) page of the Cloudinary Console.

### Selecting a model

You select a model in the `model` parameter, in one of three mutually exclusive ways:

* **Automatically (recommended)**: set `model.mode` to `auto` and let Cloudinary choose the model for each request. See [Automatic model selection](#automatic_model_selection).
* **By ID**: set `model.id` to pin an exact model, for when you need a particular one. Every model can be selected this way.
* **By family and tier**: set `model.family` and an optional `model.tier` to get the current model in that slot, which keeps working as models change. Only the models that hold a family and tier can be selected this way.

When you omit the `model` parameter, the API uses `nano-banana` at the premium tier.

For the models available and what each one is for, see [Supported models](#supported_models).

### Automatic model selection

Instead of naming a model, you can set `model.mode` to `auto` and let Cloudinary choose the model for each request. Cloudinary makes the choice per request, based on your prompt, the number of reference images, the requested output size, and where the image is stored.

```json
"model": {
  "mode": "auto"
}
```

Automatic selection is useful when you don't want to track which model suits which kind of prompt, and it keeps your integration current: as models are added, updated, or retired, requests using `auto` pick up the change without any code change on your side.

Automatic selection works on both the `text_to_image` and `image_to_image` endpoints, and in both synchronous and asynchronous mode. It's mutually exclusive with `model.id` and `model.family`: a request that combines `auto` with either of them returns a `400` error.

#### Steer the choice with a preference

Add an optional `preference` to tell Cloudinary what the choice should optimize for. If you omit it, Cloudinary uses `balanced`.

```json
"model": {
  "mode": "auto",
  "preference": "economy"
}
```

{table:class=model-table model-table-two-col} Preference | Optimizes for |
|------------|---------------|
| balanced (default) | Quality and cost, weighted equally. |
| quality | Quality alone, without weighing cost. |
| economy | Cost first, quality second. |
| balanced_fast | The same as `balanced`, and also favors faster models. |
| quality_fast | The same as `quality`, and also favors faster models. |
| economy_fast | The same as `economy`, and also favors faster models. |

The `_fast` variants add generation speed to the trade-off and never select a model that typically takes longer than 30 seconds to generate an image.

#### See which model ran

Cloudinary resolves `auto` to a specific model before generating, so the response reports the model that ran in `data.assets[].model`, with its `family`, `tier`, and `id`, exactly as it does when you select a model yourself:

```json
"model": {
    "family": "flux",
    "id": "flux-2-pro",
    "tier": "premium"
}
```

Always key on `model.id`, which is always a concrete model. Some models are offered by ID only and belong to no family or tier, and those report `unmapped` for `family` and `tier`:

```json
"model": {
    "family": "unmapped",
    "id": "gpt-image-2.5-flare",
    "tier": "unmapped"
}
```

For an asynchronous request, the resolved model appears in the task result, in `data.result.assets[].model`. On the `image_to_image` endpoint, the resolved model is always an [edit-capable model](#models_for_generating_images_from_reference_images).

> **NOTE**: The resolved model is also recorded on the generated asset as the `model_id` [contextual metadata](#automatic_tags_and_metadata) field, so you can see which model produced an asset later on.

### Generate an image and save it in your product environment

The simplest possible request requires only a `prompt`. The API uses the default `nano-banana` (premium) model and default image dimensions, and stores the result as a permanent asset in your product environment, where it's immediately available for delivery, transformation, and optimization.

```curl
curl -X POST https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/text_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A man with a hat"
  }'
```

The response includes a permanent `secure_url` and the `asset_id`, `public_id`, and other managed asset fields you can use in other Cloudinary APIs.

```json
{
    "data": {
        "assets": [
            {
                "bytes": 1683741,
                "created_at": "2026-07-21T14:55:47.471359532Z",
                "format": "png",
                "height": 1024,
                "model": {
                    "family": "nano-banana",
                    "id": "nano-banana-2",
                    "tier": "premium"
                },
                "seed": null,
                "storage": {
                    "asset_id": "e282fa1731dd75ab18386bda6abf4457",
                    "public_id": "susggqvm0h41ewohtdsr",
                    "resource_type": "image",
                    "secure_url": "https://res.cloudinary.com/demo/image/upload/v1784645746/susggqvm0h41ewohtdsr.png",
                    "storage_type": "managed_asset",
                    "type": "upload",
                    "version": 1784645746
                },
                "width": 1024
            }
        ]
    },
    "limits": {
        "addons_quota": [
            {
                "limit": 50,
                "remaining": 5,
                "type": "image_generation",
                "used_by_request": 9
            }
        ]
    },
    "request_id": "15c8373fbfae88ee1c3ec34783b76ef6"
}
```

The generated image:

![A man with a hat](https://res.cloudinary.com/demo/image/upload/v1784645746/susggqvm0h41ewohtdsr.png "with_code:false, thumb:c_scale,w_400/e_sharpen/f_auto/q_auto")

#### Control the stored asset with `target`

Include a `target` object to control how and where the generated asset is stored. Set `target.target_type` to `managed_asset` (the default) and optionally specify a `public_id` to control where the asset is stored, and an `upload_preset` to apply additional configuration (learn about [upload presets](upload_presets)):

```curl
curl -X POST https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/text_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A man with a hat",
    "target": {
      "target_type": "managed_asset",
      "public_id": "my-generated-image",
      "upload_preset": "my-preset"
    }
  }'
```

### Let Cloudinary choose the model

Unless you need a particular model, this is the recommended way to generate an image: set `model.mode` to `auto` and Cloudinary selects the model for each request, keeping up with the roster as models are added, updated, or retired.

Optionally add a `preference` to say what the choice should optimize for. This works on both endpoints; for an `image_to_image` example, see [Let Cloudinary choose the edit model](#let_cloudinary_choose_the_edit_model). For details on how the choice is made and what each preference means, see [Automatic model selection](#automatic_model_selection).

```curl
curl -X POST https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/text_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A promotional banner for a summer coffee sale, with the text SUMMER SALE in bold letters over an iced latte on a sunlit cafe table",
    "model": {
      "mode": "auto",
      "preference": "quality"
    },
    "image_size": {
      "aspect_ratio": "16:9",
      "resolution": "2K"
    },
    "target": {
      "target_type": "managed_asset",
      "public_id": "summer-sale-banner"
    }
  }'
```

The response reports the model Cloudinary chose in `data.assets[].model`:

```json
{
    "data": {
        "assets": [
            {
                "bytes": 3105845,
                "created_at": "2026-09-23T08:16:25.239618284Z",
                "format": "png",
                "height": 1152,
                "model": {
                    "family": "unmapped",
                    "id": "gpt-image-2.5-flare",
                    "tier": "unmapped"
                },
                "seed": null,
                "storage": {
                    "asset_id": "d07337a25fffff0a0abb72dd66e54b88",
                    "public_id": "summer-sale-banner",
                    "resource_type": "image",
                    "secure_url": "https://res.cloudinary.com/demo/image/upload/v1790151384/summer-sale-banner.png",
                    "storage_type": "managed_asset",
                    "type": "upload",
                    "version": 1790151384
                },
                "width": 2048
            }
        ]
    },
    "limits": {
        "addons_quota": [
            {
                "limit": 50,
                "remaining": 45,
                "type": "image_generation",
                "used_by_request": 5
            }
        ]
    },
    "request_id": "c381b33fef9858567e469a5117e94d7f"
}
```

The generated image:

![A promotional banner for a summer coffee sale, with the text SUMMER SALE in bold letters over an iced latte on a sunlit cafe table](https://res.cloudinary.com/demo/image/upload/v1790151384/summer-sale-banner.png "with_code:false, thumb:c_scale,w_500/f_auto/q_auto")

### Generate an image with a specific model family and size

When you do need a particular model, select a model family and quality tier, and use the declarative `aspect_ratio` and `resolution` parameters to specify output size. The API resolves the closest dimensions the selected model supports.

```curl
curl -X POST https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/text_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "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-generated-sunset"
    }
  }'
```

The generated image:

![A photorealistic sunset over a mountain lake](https://res.cloudinary.com/demo/image/upload/v1782402283/my-generated-sunset.png "with_code:false, thumb:c_scale,w_500/f_auto/q_auto")

### Specify an exact model and use pixel dimensions

Use `model.id` to specify an exact model version, and use `width` and `height` for precise pixel control.

```curl
curl -X POST https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/text_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A photorealistic sunset over a mountain lake",
    "model": {
      "id": "flux-2-pro"
    },
    "image_size": {
      "width": 1280,
      "height": 720
    },
    "target": {
      "target_type": "managed_asset",
      "public_id": "my-generated-sunset-flux-2-pro"
    },
    "seed": 42
  }'
```

> **TIP**: Use `seed` to reproduce a specific generation result. See the [Seed support](#supported_models) column for which models support it; models that don't support seeds silently ignore the parameter.

The generated image:

![A photorealistic sunset over a mountain lake](https://res.cloudinary.com/demo/image/upload/v1782402553/my-generated-sunset-flux-2-pro.png "with_code:false, thumb:c_scale,w_500/f_auto/q_auto")

### Generate a temporary image

Set `target.target_type` to `temporary` to generate a short-lived image that expires after a fixed period. This is useful for previewing or evaluating prompts before committing quota to a permanent asset, for example, to iterate on a prompt before saving the result.

```curl
curl -X POST https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/text_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A photorealistic sunset over a mountain lake",
    "model": {
      "mode": "auto",
      "preference": "quality"
    },
    "target": {
      "target_type": "temporary"
    }
  }'
```

The response includes a `secure_url` that's valid until the `expires_at` time, and reports the model `auto` resolved to. To save the image permanently, resubmit the request with `target.target_type` set to `managed_asset`.

```json
{
    "data": {
        "assets": [
            {
                "bytes": 1188619,
                "created_at": "2026-09-24T13:20:13.970155691Z",
                "format": "png",
                "height": 768,
                "model": {
                    "family": "unmapped",
                    "id": "gpt-image-2.5-flare",
                    "tier": "unmapped"
                },
                "seed": null,
                "storage": {
                    "expires_at": "2026-09-24T14:20:13Z",
                    "secure_url": "https://upload-us-east-1.cloudinary.com/v2/demo/uploads/e7f41cc1cfcf49e248e158dcc553c1e1/stream",
                    "storage_type": "temporary"
                },
                "width": 1024
            }
        ]
    },
    "limits": {
        "addons_quota": [
            {
                "limit": 50,
                "remaining": 40,
                "type": "image_generation",
                "used_by_request": 4
            }
        ]
    },
    "request_id": "b2a328ee8be7377309b171085b312389"
}
```

### Generate an image asynchronously

For long-running generations, set `async` to `true`. The API returns immediately with a `202` response containing a `task_id`. You can poll the task endpoint or use a webhook to receive the result.

```curl
curl -X POST https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/text_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A futuristic city skyline at night",
    "model": {
      "mode": "auto"
    },
    "target": {
      "target_type": "managed_asset",
      "public_id": "city-skyline-night"
    },
    "async": true,
    "notification_url": "https://path.to/webhook"
  }'
```

**Response (202 Accepted):**

```json
{
    "data": {
        "result": null,
        "status": "pending",
        "task_id": "2a16a5c15522e4da9f250a2abca6441c9ae724f7aa518ef935902255653e4a64c6e5777d4bedb8490f7418cb1e72ccfb1f61662c69f11f57297c4daaaaf3eebb7298ff75812fcceea3e05e2cfe4e3235"
    },
    "request_id": "6a0edc398bdcfa1f5d68699de113b7ba"
}
```

### Check the status of an async generation

Poll the task endpoint using the `task_id` returned in the async response, or receive the result at your `notification_url`.

```curl
curl -X GET https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/tasks/<TASK_ID> \
  -u "<API_KEY>:<API_SECRET>"
```

When the task is complete, the generated asset is available with its storage and media metadata, including the model `auto` resolved to. This is the notification Cloudinary sends to your `notification_url`:

```json
{
  "data": {
    "assets": [
      {
        "bytes": 3884392,
        "created_at": "2026-09-24T13:27:04.82076388Z",
        "format": "png",
        "height": 1280,
        "model": {
          "family": "unmapped",
          "id": "muse-image",
          "tier": "unmapped"
        },
        "seed": null,
        "storage": {
          "asset_id": "e01bdbb20467da0f1fa529aebd4e4a88",
          "public_id": "city-skyline-night",
          "resource_type": "image",
          "secure_url": "https://res.cloudinary.com/demo/image/upload/v1790256423/city-skyline-night.png",
          "storage_type": "managed_asset",
          "type": "upload",
          "version": 1790256423
        },
        "width": 1920
      }
    ]
  },
  "http_status": 200,
  "limits": {
    "addons_quota": [
      {
        "limit": 50,
        "remaining": 39,
        "type": "image_generation",
        "used_by_request": 1
      }
    ]
  },
  "notification_context": {
    "triggered_at": "2026-09-24T13:26:45.086000613Z",
    "triggered_by": {
      "id": "335549336743821",
      "source": "api"
    }
  },
  "notification_type": "generation",
  "operation_name": "generate_image",
  "operation_type": "single",
  "request_id": "6a0edc398bdcfa1f5d68699de113b7ba",
  "task_id": "2a16a5c15522e4da9f250a2abca6441c9ae724f7aa518ef935902255653e4a64c6e5777d4bedb8490f7418cb1e72ccfb1f61662c69f11f57297c4daaaaf3eebb7298ff75812fcceea3e05e2cfe4e3235"
}

```

The task endpoint returns the same asset, nested under `data.result`, together with the task's `status` and `task_id`.

The generated image:

![A futuristic city skyline at night](https://res.cloudinary.com/demo/image/upload/v1790256423/city-skyline-night.png "with_code:false, thumb:c_scale,w_500/f_auto/q_auto")

### Generate an image from reference images

Use the `image_to_image` endpoint to generate an image guided by a `prompt` and one or more **reference images**. This supports use cases such as restyling, on-brand variants, character consistency, virtual try-on, and edit/extend.

Both `prompt` and `reference_images` are required. All other parameters (`model`, `image_size`, `format`, `target`, `seed`, `async`, `notification_url`) behave the same as for the [text_to_image](#generate_an_image_and_save_it_in_your_product_environment) endpoint. Note that this endpoint accepts only [edit-capable models](#models_for_generating_images_from_reference_images).

Reference images are 1-indexed and you can address them positionally in the prompt as `[1]`, `[2]`, and so on. The platform accepts up to 4 reference images, though a specific model may accept fewer (see **Max reference images** in the [edit models table](#models_for_generating_images_from_reference_images)) — exceeding the selected model's capacity returns a `400`. Each reference image is provided in one of two ways, set via `source_type`:

* `url`: an external HTTPS URL.
* `managed_asset`: a stored asset in your product environment, by `asset_id` (read permission is checked).

**By URL:**

```curl
curl -X POST https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/image_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Place the product from [1] on a marble kitchen counter, soft morning light",
    "reference_images": [
      {
        "source_type": "url",
        "url": "https://res.cloudinary.com/demo/image/upload/v1784151459/docs/teapot-product.jpg"
      }
    ],
    "model": {
      "family": "nano-banana",
      "tier": "premium"
    },
    "target": {
      "target_type": "managed_asset",
      "public_id": "teapot-product/kitchen-counter"
    }
  }'
```

**By managed asset ID:**

```curl
curl -X POST https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/image_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Place the product from [1] on a marble kitchen counter, soft morning light",
    "reference_images": [
      {
        "source_type": "managed_asset",
        "asset_id": "7e3768a0d359920d8e1e0cf4564070ac"
      }
    ],
    "model": {
      "family": "nano-banana",
      "tier": "premium"
    },
    "target": {
      "target_type": "managed_asset",
      "public_id": "teapot-product/kitchen-counter"
    }
  }'
```

The response has the same structure as for the [text_to_image](#generate_an_image_and_save_it_in_your_product_environment) endpoint, including the stored asset's `secure_url` and managed asset fields.

The reference image (`[1]`) and the generated image:

Reference

Generated

#### Let Cloudinary choose the edit model

You can also let Cloudinary choose the edit model, by setting `model.mode` to `auto`. On this endpoint it always resolves to an edit-capable model:

```curl
curl -X POST https://api.cloudinary.com/v2/generate/<CLOUD_NAME>/image_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Restyle the product in [1] as a hand-painted watercolor illustration, keeping the composition and proportions",
    "reference_images": [
      {
        "source_type": "url",
        "url": "https://res.cloudinary.com/demo/image/upload/v1784151459/docs/teapot-product.jpg"
      }
    ],
    "model": {
      "mode": "auto"
    },
    "image_size": {
      "aspect_ratio": "4:3",
      "resolution": "1K"
    },
    "target": {
      "target_type": "managed_asset",
      "public_id": "teapot-product/watercolor"
    }
  }'
```

Here, `auto` resolved to an edit-capable model, as it always does on this endpoint:

```json
{
    "data": {
        "assets": [
            {
                "bytes": 2928680,
                "created_at": "2026-09-23T08:35:38.346718476Z",
                "format": "png",
                "height": 1344,
                "model": {
                    "family": "unmapped",
                    "id": "muse-image-edit",
                    "tier": "unmapped"
                },
                "seed": null,
                "storage": {
                    "asset_id": "4a2447348c655cc836ad548836517d0e",
                    "public_id": "teapot-product/watercolor",
                    "resource_type": "image",
                    "secure_url": "https://res.cloudinary.com/demo/image/upload/v1790152537/teapot-product/watercolor.png",
                    "storage_type": "managed_asset",
                    "type": "upload",
                    "version": 1790152537
                },
                "width": 1792
            }
        ]
    },
    "limits": {
        "addons_quota": [
            {
                "limit": 50,
                "remaining": 44,
                "type": "image_generation",
                "used_by_request": 1
            }
        ]
    },
    "request_id": "b404960c077a0ae1c06f0bb74e3bf537"
}
```

The same reference image (`[1]`) and the generated image:

Reference

Generated

## Supported models

The Image Generation API supports the models listed below. Any of them can be pinned with `model.id`; see [Selecting a model](#selecting_a_model) for the other ways to choose one.

The family and tier matrix holds two models per family, one `standard` and one `premium`, so it names only part of the roster. Every other model is available by `model.id` only: those have no family or tier in the table below, and report `unmapped` for both in the response, as described in [See which model ran](#see_which_model_ran).

{table:class=model-table model-table-roster} Model ID | Description | Family | Tier | Seed support |
|----------|-------------|--------|------|--------------|
| nano-banana-1 | General-purpose generation | `nano-banana` | `standard` | Yes |
| nano-banana-2 | General-purpose generation | `nano-banana` | `premium` | Yes |
| nano-banana-2-lite | The fastest, lowest-cost Nano Banana model | | | Yes |
| flux-2-klein-9b | Photorealistic images | `flux` | `standard` | Yes |
| flux-2-pro | Photorealistic images | `flux` | `premium` | Yes |
| flux-2-flash | Fast, economical FLUX generation, up to 4 MP | | | Yes |
| recraft-v3 | Vector and illustration | `recraft` | `standard` | No |
| recraft-v4 | Vector and illustration | `recraft` | `premium` | No |
| recraft-v4.1-utility | Faster, lighter Recraft for high-volume work | | | No |
| recraft-v4.1-utility-pro | High-resolution, cost-efficient Recraft | | | No |
| gpt-image-1-mini | Campaign and marketing images | `gpt-image` | `standard` | No |
| gpt-image-2 | Campaign and marketing images | `gpt-image` | `premium` | No |
| gpt-image-2.5-flare | Fast, high-quality general-purpose generation, with natural lighting, rich textures, complex layouts, and transparent backgrounds | | | No |
| gpt-image-2.5-sunburst | Precision-focused generation, with extra fidelity on intricate detail in exchange for longer generation times | | | No |
| ideogram-v4-turbo | Realism, text rendering, and artistic generation | `ideogram` | `standard` | Yes |
| ideogram-v4-base | Realism, text rendering, and artistic generation | `ideogram` | `premium` | Yes |
| muse-image | Precise edits that change only what you ask, coherent across turns, composing from multiple reference images | | | No |
| mai-image-2.5 | General-purpose generation | | | No |
| mai-image-2.5-pro | Higher-quality version of mai-image-2.5 | | | No |
| seedream-5-lite | Low-cost generation and editing, up to 4K | | | No |
| seedream-5-pro | Higher-quality version of seedream-5 | | | No |
| grok-imagine-image | Stylistic variety and unusual subjects | | | No |
| grok-imagine-image-2.0-low | Grok Imagine 2.0, pinned to its lowest quality setting | | | No |
| qwen-image-3 | General-purpose generation | | | Yes |

> **NOTE**: `auto` chooses from the models the selection service currently covers, which is a subset of the models listed here. A model you can pin with `model.id` isn't necessarily one that `auto` picks.

### Models for generating images from reference images

[Generating images from reference images](#generate_an_image_from_reference_images) requires an **edit-capable model**. On the `image_to_image` endpoint, `auto` always resolves to one of the models below, and a family and tier resolves to the edit model in that slot. You can also specify an exact edit model by ID.

Each model accepts a maximum number of reference images. The platform accepts up to 4, and exceeding the selected model's own maximum returns a `400` error.

{table:class=model-table model-table-edit} Edit model ID | Family | Tier | Max reference images |
|---------------|--------|------|----------------------|
| nano-banana-1-edit | `nano-banana` | `standard` | 4 |
| nano-banana-2-edit | `nano-banana` | `premium` | 4 |
| nano-banana-2-lite-edit | | | 4 |
| flux-2-klein-9b-edit | `flux` | `standard` | 4 |
| flux-2-pro-edit | `flux` | `premium` | 4 |
| flux-2-flash-edit | | | 4 |
| recraft-v3-edit | `recraft` | `standard` | 1 |
| gpt-image-1-mini-edit | `gpt-image` | `standard` | 4 |
| gpt-image-2-edit | `gpt-image` | `premium` | 4 |
| gpt-image-2.5-flare-edit | | | 4 |
| gpt-image-2.5-sunburst-edit | | | 4 |
| muse-image-edit | | | 4 |
| mai-image-2.5-edit | | | 1 |
| mai-image-2.5-pro-edit | | | 1 |
| seedream-5-lite-edit | | | 4 |
| seedream-5-pro-edit | | | 4 |
| grok-imagine-image-edit | | | 3 |
| grok-imagine-image-2.0-low-edit | | | 3 |
| qwen-image-3-edit | | | 3 |

### Requested output format

Most models generate the `format` you request. The `recraft-v4.1-utility`, `recraft-v4.1-utility-pro`, and `seedream-5-lite` models select their own output format, so they may return a different one than you asked for. The `format` field in the response always reports the format you actually received.

## Automatic tags and metadata

When you generate an image via the Console or the API, Cloudinary automatically applies the following to the asset:

* **Tag:** `text-to-image` or `image-to-image`
* **Contextual metadata:**
  * `model_id`: the model used to generate the image (for example, `recraft-v4`)
  * `prompt`: the text prompt used for generation
  * `seed`: the seed value used (or `0` if you didn't specify one)

For example, the asset generated by the [automatic model selection](#let_cloudinary_choose_the_model) request above carries the `text-to-image` tag, the resolved `model_id`, the prompt, and a `seed` of `0`, because the request didn't specify one:

![Tags and contextual metadata applied to a generated image in the Media Library](https://cloudinary-res.cloudinary.com/image/upload/bo_1px_solid_gray/f_auto/q_auto/v1790152114/docs/image-gen-metadata.png "thumb: c_scale,w_400,dpr_2, width:400")

This makes it straightforward to find, filter, and manage generated images alongside your other assets in the Media Library.

## Use case examples

### Omnichannel social media campaigns

A marketing team wants to generate a high-end visual for a global campaign and distribute it across Instagram (1:1), TikTok (9:16), and use it as a web banner on their website (32:9). Instead of generating three separate AI images, which would result in inconsistent visuals, they generate one high-resolution image and use Cloudinary to crop it dynamically.

This request lets Cloudinary choose the model, with a `quality` preference for a high-end photorealistic result, and uses a reference image of the watch. It instructs the server to store it under a specific `public_id`.

Reference

Here's an example API call for the `demo` product environment:

```curl
curl -X POST https://api.cloudinary.com/v2/generate/demo/image_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A high-end product shot of the watch from [1] floating in water, hyper-detailed, sleek commercial photography, minimal background.",
      "reference_images": [
    {
      "source_type": "managed_asset",
      "asset_id": "056ce933eaedce52714573d3c403f545"
    }
  ],
    "model": {
      "mode": "auto",
      "preference": "quality"
    },
    "image_size": {
      "resolution": "1K"
    },
    "target": {
      "target_type": "managed_asset",
      "public_id": "campaigns/floating_watch_1_launch"
    }
  }'
```

The generated image:

![A high-end product shot of a luxury watch floating in water, hyper-detailed, sleek commercial](https://res.cloudinary.com/demo/image/upload/v1784719257/campaigns/floating_watch_1_launch "with_code:false, thumb:c_scale,w_500")

Once generated, you can immediately serve various crops out-of-the-box using Cloudinary's dynamic URL transformations:

* **Instagram Grid (1:1 Square, Smart Cropped):**
    ![A high-end product shot of a luxury watch floating in water, hyper-detailed, sleek commercial](https://res.cloudinary.com/demo/image/upload/c_auto,g_auto,h_1080,w_1080/f_auto/q_auto/campaigns/floating_watch_1_launch "thumb:c_scale,w_300")

```nodejs
cloudinary.image("campaigns/floating_watch_1_launch", {transformation: [
  {gravity: "auto", height: 1080, width: 1080, crop: "auto"},
  {quality: "auto"}
  ]})
```

```react
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1080)
      .height(1080)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```vue
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1080)
      .height(1080)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```angular
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1080)
      .height(1080)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```js
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1080)
      .height(1080)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```python
CloudinaryImage("campaigns/floating_watch_1_launch").image(transformation=[
  {'gravity': "auto", 'height': 1080, 'width': 1080, 'crop': "auto"},
  {'quality': "auto"}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Delivery;
use Cloudinary\Transformation\Format;
use Cloudinary\Transformation\Quality;
use Cloudinary\Transformation\Gravity;

(new ImageTag('campaigns/floating_watch_1_launch'))
	->resize(Resize::auto()->width(1080)
->height(1080)
	->gravity(
	Gravity::autoGravity())
	)
	->delivery(Delivery::format(
	Format::auto()))
	->delivery(Delivery::quality(
	Quality::auto()));
```

```java
cloudinary.url().transformation(new Transformation()
  .gravity("auto").height(1080).width(1080).crop("auto").chain()
  .quality("auto")).imageTag("campaigns/floating_watch_1_launch");
```

```ruby
cl_image_tag("campaigns/floating_watch_1_launch", transformation: [
  {gravity: "auto", height: 1080, width: 1080, crop: "auto"},
  {quality: "auto"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Gravity("auto").Height(1080).Width(1080).Crop("auto").Chain()
  .Quality("auto")).BuildImageTag("campaigns/floating_watch_1_launch")
```

```dart
cloudinary.image('campaigns/floating_watch_1_launch').transformation(Transformation()
	.resize(Resize.auto().width(1080)
.height(1080)
	.gravity(
	Gravity.autoGravity())
	)
	.delivery(Delivery.format(
	Format.auto()))
	.delivery(Delivery.quality(
	Quality.auto())));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setGravity("auto").setHeight(1080).setWidth(1080).setCrop("auto").chain()
  .setQuality("auto")).generate("campaigns/floating_watch_1_launch")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .gravity("auto").height(1080).width(1080).crop("auto").chain()
  .quality("auto")).generate("campaigns/floating_watch_1_launch");
```

```flutter
cloudinary.image('campaigns/floating_watch_1_launch').transformation(Transformation()
	.resize(Resize.auto().width(1080)
.height(1080)
	.gravity(
	Gravity.autoGravity())
	)
	.delivery(Delivery.format(
	Format.auto()))
	.delivery(Delivery.quality(
	Quality.auto())));
```

```kotlin
cloudinary.image {
	publicId("campaigns/floating_watch_1_launch")
	 resize(Resize.auto() { width(1080)
 height(1080)
	 gravity(
	Gravity.autoGravity())
	 })
	 delivery(Delivery.format(
	Format.auto()))
	 delivery(Delivery.quality(
	Quality.auto())) 
}.generate()
```

```jquery
$.cloudinary.image("campaigns/floating_watch_1_launch", {transformation: [
  {gravity: "auto", height: 1080, width: 1080, crop: "auto"},
  {quality: "auto"}
  ]})
```

```react_native
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1080)
      .height(1080)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

* **TikTok/Stories (9:16 Vertical, Smart Cropped):**
    ![A high-end product shot of a luxury watch floating in water, hyper-detailed, sleek commercial](https://res.cloudinary.com/demo/image/upload/c_auto,g_auto,h_1920,w_1080/f_auto/q_auto/campaigns/floating_watch_1_launch "thumb:c_scale,w_300")

```nodejs
cloudinary.image("campaigns/floating_watch_1_launch", {transformation: [
  {gravity: "auto", height: 1920, width: 1080, crop: "auto"},
  {quality: "auto"}
  ]})
```

```react
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1080)
      .height(1920)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```vue
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1080)
      .height(1920)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```angular
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1080)
      .height(1920)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```js
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1080)
      .height(1920)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```python
CloudinaryImage("campaigns/floating_watch_1_launch").image(transformation=[
  {'gravity': "auto", 'height': 1920, 'width': 1080, 'crop': "auto"},
  {'quality': "auto"}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Delivery;
use Cloudinary\Transformation\Format;
use Cloudinary\Transformation\Quality;
use Cloudinary\Transformation\Gravity;

(new ImageTag('campaigns/floating_watch_1_launch'))
	->resize(Resize::auto()->width(1080)
->height(1920)
	->gravity(
	Gravity::autoGravity())
	)
	->delivery(Delivery::format(
	Format::auto()))
	->delivery(Delivery::quality(
	Quality::auto()));
```

```java
cloudinary.url().transformation(new Transformation()
  .gravity("auto").height(1920).width(1080).crop("auto").chain()
  .quality("auto")).imageTag("campaigns/floating_watch_1_launch");
```

```ruby
cl_image_tag("campaigns/floating_watch_1_launch", transformation: [
  {gravity: "auto", height: 1920, width: 1080, crop: "auto"},
  {quality: "auto"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Gravity("auto").Height(1920).Width(1080).Crop("auto").Chain()
  .Quality("auto")).BuildImageTag("campaigns/floating_watch_1_launch")
```

```dart
cloudinary.image('campaigns/floating_watch_1_launch').transformation(Transformation()
	.resize(Resize.auto().width(1080)
.height(1920)
	.gravity(
	Gravity.autoGravity())
	)
	.delivery(Delivery.format(
	Format.auto()))
	.delivery(Delivery.quality(
	Quality.auto())));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setGravity("auto").setHeight(1920).setWidth(1080).setCrop("auto").chain()
  .setQuality("auto")).generate("campaigns/floating_watch_1_launch")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .gravity("auto").height(1920).width(1080).crop("auto").chain()
  .quality("auto")).generate("campaigns/floating_watch_1_launch");
```

```flutter
cloudinary.image('campaigns/floating_watch_1_launch').transformation(Transformation()
	.resize(Resize.auto().width(1080)
.height(1920)
	.gravity(
	Gravity.autoGravity())
	)
	.delivery(Delivery.format(
	Format.auto()))
	.delivery(Delivery.quality(
	Quality.auto())));
```

```kotlin
cloudinary.image {
	publicId("campaigns/floating_watch_1_launch")
	 resize(Resize.auto() { width(1080)
 height(1920)
	 gravity(
	Gravity.autoGravity())
	 })
	 delivery(Delivery.format(
	Format.auto()))
	 delivery(Delivery.quality(
	Quality.auto())) 
}.generate()
```

```jquery
$.cloudinary.image("campaigns/floating_watch_1_launch", {transformation: [
  {gravity: "auto", height: 1920, width: 1080, crop: "auto"},
  {quality: "auto"}
  ]})
```

```react_native
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1080)
      .height(1920)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

* **Web Banner (32:9 Horizontal, Smart Cropped):**
    ![A high-end product shot of a luxury watch floating in water, hyper-detailed, sleek commercial](https://res.cloudinary.com/demo/image/upload/c_auto,g_auto,h_540,w_1920/f_auto/q_auto/campaigns/floating_watch_1_launch "thumb:c_scale,w_600")

```nodejs
cloudinary.image("campaigns/floating_watch_1_launch", {transformation: [
  {gravity: "auto", height: 540, width: 1920, crop: "auto"},
  {quality: "auto"}
  ]})
```

```react
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1920)
      .height(540)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```vue
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1920)
      .height(540)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```angular
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1920)
      .height(540)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```js
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1920)
      .height(540)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```python
CloudinaryImage("campaigns/floating_watch_1_launch").image(transformation=[
  {'gravity': "auto", 'height': 540, 'width': 1920, 'crop': "auto"},
  {'quality': "auto"}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Delivery;
use Cloudinary\Transformation\Format;
use Cloudinary\Transformation\Quality;
use Cloudinary\Transformation\Gravity;

(new ImageTag('campaigns/floating_watch_1_launch'))
	->resize(Resize::auto()->width(1920)
->height(540)
	->gravity(
	Gravity::autoGravity())
	)
	->delivery(Delivery::format(
	Format::auto()))
	->delivery(Delivery::quality(
	Quality::auto()));
```

```java
cloudinary.url().transformation(new Transformation()
  .gravity("auto").height(540).width(1920).crop("auto").chain()
  .quality("auto")).imageTag("campaigns/floating_watch_1_launch");
```

```ruby
cl_image_tag("campaigns/floating_watch_1_launch", transformation: [
  {gravity: "auto", height: 540, width: 1920, crop: "auto"},
  {quality: "auto"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Gravity("auto").Height(540).Width(1920).Crop("auto").Chain()
  .Quality("auto")).BuildImageTag("campaigns/floating_watch_1_launch")
```

```dart
cloudinary.image('campaigns/floating_watch_1_launch').transformation(Transformation()
	.resize(Resize.auto().width(1920)
.height(540)
	.gravity(
	Gravity.autoGravity())
	)
	.delivery(Delivery.format(
	Format.auto()))
	.delivery(Delivery.quality(
	Quality.auto())));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setGravity("auto").setHeight(540).setWidth(1920).setCrop("auto").chain()
  .setQuality("auto")).generate("campaigns/floating_watch_1_launch")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .gravity("auto").height(540).width(1920).crop("auto").chain()
  .quality("auto")).generate("campaigns/floating_watch_1_launch");
```

```flutter
cloudinary.image('campaigns/floating_watch_1_launch').transformation(Transformation()
	.resize(Resize.auto().width(1920)
.height(540)
	.gravity(
	Gravity.autoGravity())
	)
	.delivery(Delivery.format(
	Format.auto()))
	.delivery(Delivery.quality(
	Quality.auto())));
```

```kotlin
cloudinary.image {
	publicId("campaigns/floating_watch_1_launch")
	 resize(Resize.auto() { width(1920)
 height(540)
	 gravity(
	Gravity.autoGravity())
	 })
	 delivery(Delivery.format(
	Format.auto()))
	 delivery(Delivery.quality(
	Quality.auto())) 
}.generate()
```

```jquery
$.cloudinary.image("campaigns/floating_watch_1_launch", {transformation: [
  {gravity: "auto", height: 540, width: 1920, crop: "auto"},
  {quality: "auto"}
  ]})
```

```react_native
import { auto } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { autoGravity } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("campaigns/floating_watch_1_launch")
  .resize(
    auto()
      .width(1920)
      .height(540)
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

### Dynamic localization and ad personalization

A travel platform wants to show personalized banners to users depending on where they're booking a trip, complete with localized text rendered on the fly.

This request lets Cloudinary choose the model, so you get a composition balanced for text placement without naming one.

Here's an example API call for the `demo` product environment:

```curl
curl -X POST https://api.cloudinary.com/v2/generate/demo/text_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A beautiful, Mediterranean travel landscape with vast empty copy space on the left side.",
    "model": {
      "mode": "auto"
    },
    "image_size": {
      "resolution": "2K"
    },
    "target": {
      "target_type": "managed_asset",
      "public_id": "marketing/med_travel_landscape"
    },
    "seed": 8472
}'
```

The generated image:

![Travel banner](https://res.cloudinary.com/demo/image/upload/v1790258905/marketing/med_travel_landscape "with_code:false, thumb:c_scale,w_500")

To maintain campaign consistency, generate the graphic once and dynamically burn text layers (`l_text:`) into the empty space:

* **English version:**
  
    ![English travel banner](https://res.cloudinary.com/demo/image/upload/l_text:Arial_80_bold:Book%20Your%20Dream%20Getaway/fl_layer_apply,g_north_west,x_50,y_180/c_fill,g_auto,ar_16:9/f_auto/q_auto/marketing/med_travel_landscape.jpg "thumb:c_scale,w_500")

```nodejs
cloudinary.image("marketing/med_travel_landscape.jpg", {transformation: [
  {overlay: {font_family: "Arial", font_size: 80, font_weight: "bold", text: "Book%20Your%20Dream%20Getaway"}},
  {gravity: "north_west", x: 50, y: 180, flags: "layer_apply"},
  {gravity: "auto", aspect_ratio: "16:9", crop: "fill"},
  {quality: "auto"}
  ]})
```

```react
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fill } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";
import { ar16X9 } from "@cloudinary/url-gen/qualifiers/aspectRatio";
import { autoGravity, compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("marketing/med_travel_landscape.jpg")
  .overlay(
    source(
      text(
        "Book Your Dream Getaway",
        new TextStyle("Arial", 80).fontWeight("bold")
      )
    ).position(
      new Position()
        .gravity(compass("north_west"))
        .offsetX(50)
        .offsetY(180)
    )
  )
  .resize(
    fill()
      .aspectRatio(ar16X9())
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```vue
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fill } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";
import { ar16X9 } from "@cloudinary/url-gen/qualifiers/aspectRatio";
import { autoGravity, compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("marketing/med_travel_landscape.jpg")
  .overlay(
    source(
      text(
        "Book Your Dream Getaway",
        new TextStyle("Arial", 80).fontWeight("bold")
      )
    ).position(
      new Position()
        .gravity(compass("north_west"))
        .offsetX(50)
        .offsetY(180)
    )
  )
  .resize(
    fill()
      .aspectRatio(ar16X9())
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```angular
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fill } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";
import { ar16X9 } from "@cloudinary/url-gen/qualifiers/aspectRatio";
import { autoGravity, compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("marketing/med_travel_landscape.jpg")
  .overlay(
    source(
      text(
        "Book Your Dream Getaway",
        new TextStyle("Arial", 80).fontWeight("bold")
      )
    ).position(
      new Position()
        .gravity(compass("north_west"))
        .offsetX(50)
        .offsetY(180)
    )
  )
  .resize(
    fill()
      .aspectRatio(ar16X9())
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```js
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fill } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";
import { ar16X9 } from "@cloudinary/url-gen/qualifiers/aspectRatio";
import { autoGravity, compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("marketing/med_travel_landscape.jpg")
  .overlay(
    source(
      text(
        "Book Your Dream Getaway",
        new TextStyle("Arial", 80).fontWeight("bold")
      )
    ).position(
      new Position()
        .gravity(compass("north_west"))
        .offsetX(50)
        .offsetY(180)
    )
  )
  .resize(
    fill()
      .aspectRatio(ar16X9())
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```python
CloudinaryImage("marketing/med_travel_landscape.jpg").image(transformation=[
  {'overlay': {'font_family': "Arial", 'font_size': 80, 'font_weight': "bold", 'text': "Book%20Your%20Dream%20Getaway"}},
  {'gravity': "north_west", 'x': 50, 'y': 180, 'flags': "layer_apply"},
  {'gravity': "auto", 'aspect_ratio': "16:9", 'crop': "fill"},
  {'quality': "auto"}
  ])
```

```php
use Cloudinary\Transformation\Overlay;
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Delivery;
use Cloudinary\Transformation\Source;
use Cloudinary\Transformation\Position;
use Cloudinary\Transformation\Format;
use Cloudinary\Transformation\Quality;
use Cloudinary\Transformation\TextStyle;
use Cloudinary\Transformation\AspectRatio;
use Cloudinary\Transformation\Gravity;
use Cloudinary\Transformation\FontWeight;
use Cloudinary\Transformation\Compass;

(new ImageTag('marketing/med_travel_landscape.jpg'))
	->overlay(Overlay::source(
	Source::text("Book Your Dream Getaway",(new TextStyle("Arial",80))
	->fontWeight(
	FontWeight::bold())
	))
	->position((new Position())
	->gravity(
	Gravity::compass(
	Compass::northWest()))
->offsetX(50)
->offsetY(180))
	)
	->resize(Resize::fill()
	->aspectRatio(
	AspectRatio::ar16X9())
	->gravity(
	Gravity::autoGravity())
	)
	->delivery(Delivery::format(
	Format::auto()))
	->delivery(Delivery::quality(
	Quality::auto()));
```

```java
cloudinary.url().transformation(new Transformation()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(80).fontWeight("bold").text("Book%20Your%20Dream%20Getaway")).chain()
  .gravity("north_west").x(50).y(180).flags("layer_apply").chain()
  .gravity("auto").aspectRatio("16:9").crop("fill").chain()
  .quality("auto")).imageTag("marketing/med_travel_landscape.jpg");
```

```ruby
cl_image_tag("marketing/med_travel_landscape.jpg", transformation: [
  {overlay: {font_family: "Arial", font_size: 80, font_weight: "bold", text: "Book%20Your%20Dream%20Getaway"}},
  {gravity: "north_west", x: 50, y: 180, flags: "layer_apply"},
  {gravity: "auto", aspect_ratio: "16:9", crop: "fill"},
  {quality: "auto"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Overlay(new TextLayer().FontFamily("Arial").FontSize(80).FontWeight("bold").Text("Book%20Your%20Dream%20Getaway")).Chain()
  .Gravity("north_west").X(50).Y(180).Flags("layer_apply").Chain()
  .Gravity("auto").AspectRatio("16:9").Crop("fill").Chain()
  .Quality("auto")).BuildImageTag("marketing/med_travel_landscape.jpg")
```

```dart
cloudinary.image('marketing/med_travel_landscape.jpg').transformation(Transformation()
	.addTransformation("l_text:Arial_80_bold:Book Your Dream Getaway/fl_layer_apply,g_north_west,x_50,y_180/c_fill,g_auto,ar_16:9/f_auto/q_auto"));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setOverlay("text:Arial_80_bold:Book%20Your%20Dream%20Getaway").chain()
  .setGravity("north_west").setX(50).setY(180).setFlags("layer_apply").chain()
  .setGravity("auto").setAspectRatio("16:9").setCrop("fill").chain()
  .setQuality("auto")).generate("marketing/med_travel_landscape.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(80).fontWeight("bold").text("Book%20Your%20Dream%20Getaway")).chain()
  .gravity("north_west").x(50).y(180).flags("layer_apply").chain()
  .gravity("auto").aspectRatio("16:9").crop("fill").chain()
  .quality("auto")).generate("marketing/med_travel_landscape.jpg");
```

```flutter
cloudinary.image('marketing/med_travel_landscape.jpg').transformation(Transformation()
	.addTransformation("l_text:Arial_80_bold:Book Your Dream Getaway/fl_layer_apply,g_north_west,x_50,y_180/c_fill,g_auto,ar_16:9/f_auto/q_auto"));
```

```kotlin
cloudinary.image {
	publicId("marketing/med_travel_landscape.jpg")
	 overlay(Overlay.source(
	Source.text("Book Your Dream Getaway",TextStyle("Arial",80) {
	 fontWeight(
	FontWeight.bold())
	 })) {
	 position(Position() {
	 gravity(
	Gravity.compass(
	Compass.northWest()))
 offsetX(50)
 offsetY(180) })
	 })
	 resize(Resize.fill() {
	 aspectRatio(
	AspectRatio.ar16X9())
	 gravity(
	Gravity.autoGravity())
	 })
	 delivery(Delivery.format(
	Format.auto()))
	 delivery(Delivery.quality(
	Quality.auto())) 
}.generate()
```

```jquery
$.cloudinary.image("marketing/med_travel_landscape.jpg", {transformation: [
  {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(80).fontWeight("bold").text("Book%20Your%20Dream%20Getaway")},
  {gravity: "north_west", x: 50, y: 180, flags: "layer_apply"},
  {gravity: "auto", aspect_ratio: "16:9", crop: "fill"},
  {quality: "auto"}
  ]})
```

```react_native
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fill } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";
import { ar16X9 } from "@cloudinary/url-gen/qualifiers/aspectRatio";
import { autoGravity, compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("marketing/med_travel_landscape.jpg")
  .overlay(
    source(
      text(
        "Book Your Dream Getaway",
        new TextStyle("Arial", 80).fontWeight("bold")
      )
    ).position(
      new Position()
        .gravity(compass("north_west"))
        .offsetX(50)
        .offsetY(180)
    )
  )
  .resize(
    fill()
      .aspectRatio(ar16X9())
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

* **Italian version:**
  
    ![Italian travel banner](https://res.cloudinary.com/demo/image/upload/l_text:Arial_80_bold:Prenota%20Le%20Tue%20Vacanze%20Dei%20Sogni/fl_layer_apply,g_north_west,x_50,y_180/c_fill,g_auto,ar_16:9/f_auto/q_auto/marketing/med_travel_landscape.jpg "thumb:c_scale,w_500")

```nodejs
cloudinary.image("marketing/med_travel_landscape.jpg", {transformation: [
  {overlay: {font_family: "Arial", font_size: 80, font_weight: "bold", text: "Prenota%20Le%20Tue%20Vacanze%20Dei%20Sogni"}},
  {gravity: "north_west", x: 50, y: 180, flags: "layer_apply"},
  {gravity: "auto", aspect_ratio: "16:9", crop: "fill"},
  {quality: "auto"}
  ]})
```

```react
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fill } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";
import { ar16X9 } from "@cloudinary/url-gen/qualifiers/aspectRatio";
import { autoGravity, compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("marketing/med_travel_landscape.jpg")
  .overlay(
    source(
      text(
        "Prenota Le Tue Vacanze Dei Sogni",
        new TextStyle("Arial", 80).fontWeight("bold")
      )
    ).position(
      new Position()
        .gravity(compass("north_west"))
        .offsetX(50)
        .offsetY(180)
    )
  )
  .resize(
    fill()
      .aspectRatio(ar16X9())
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```vue
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fill } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";
import { ar16X9 } from "@cloudinary/url-gen/qualifiers/aspectRatio";
import { autoGravity, compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("marketing/med_travel_landscape.jpg")
  .overlay(
    source(
      text(
        "Prenota Le Tue Vacanze Dei Sogni",
        new TextStyle("Arial", 80).fontWeight("bold")
      )
    ).position(
      new Position()
        .gravity(compass("north_west"))
        .offsetX(50)
        .offsetY(180)
    )
  )
  .resize(
    fill()
      .aspectRatio(ar16X9())
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```angular
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fill } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";
import { ar16X9 } from "@cloudinary/url-gen/qualifiers/aspectRatio";
import { autoGravity, compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("marketing/med_travel_landscape.jpg")
  .overlay(
    source(
      text(
        "Prenota Le Tue Vacanze Dei Sogni",
        new TextStyle("Arial", 80).fontWeight("bold")
      )
    ).position(
      new Position()
        .gravity(compass("north_west"))
        .offsetX(50)
        .offsetY(180)
    )
  )
  .resize(
    fill()
      .aspectRatio(ar16X9())
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```js
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fill } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";
import { ar16X9 } from "@cloudinary/url-gen/qualifiers/aspectRatio";
import { autoGravity, compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("marketing/med_travel_landscape.jpg")
  .overlay(
    source(
      text(
        "Prenota Le Tue Vacanze Dei Sogni",
        new TextStyle("Arial", 80).fontWeight("bold")
      )
    ).position(
      new Position()
        .gravity(compass("north_west"))
        .offsetX(50)
        .offsetY(180)
    )
  )
  .resize(
    fill()
      .aspectRatio(ar16X9())
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```python
CloudinaryImage("marketing/med_travel_landscape.jpg").image(transformation=[
  {'overlay': {'font_family': "Arial", 'font_size': 80, 'font_weight': "bold", 'text': "Prenota%20Le%20Tue%20Vacanze%20Dei%20Sogni"}},
  {'gravity': "north_west", 'x': 50, 'y': 180, 'flags': "layer_apply"},
  {'gravity': "auto", 'aspect_ratio': "16:9", 'crop': "fill"},
  {'quality': "auto"}
  ])
```

```php
use Cloudinary\Transformation\Overlay;
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Delivery;
use Cloudinary\Transformation\Source;
use Cloudinary\Transformation\Position;
use Cloudinary\Transformation\Format;
use Cloudinary\Transformation\Quality;
use Cloudinary\Transformation\TextStyle;
use Cloudinary\Transformation\AspectRatio;
use Cloudinary\Transformation\Gravity;
use Cloudinary\Transformation\FontWeight;
use Cloudinary\Transformation\Compass;

(new ImageTag('marketing/med_travel_landscape.jpg'))
	->overlay(Overlay::source(
	Source::text("Prenota Le Tue Vacanze Dei Sogni",(new TextStyle("Arial",80))
	->fontWeight(
	FontWeight::bold())
	))
	->position((new Position())
	->gravity(
	Gravity::compass(
	Compass::northWest()))
->offsetX(50)
->offsetY(180))
	)
	->resize(Resize::fill()
	->aspectRatio(
	AspectRatio::ar16X9())
	->gravity(
	Gravity::autoGravity())
	)
	->delivery(Delivery::format(
	Format::auto()))
	->delivery(Delivery::quality(
	Quality::auto()));
```

```java
cloudinary.url().transformation(new Transformation()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(80).fontWeight("bold").text("Prenota%20Le%20Tue%20Vacanze%20Dei%20Sogni")).chain()
  .gravity("north_west").x(50).y(180).flags("layer_apply").chain()
  .gravity("auto").aspectRatio("16:9").crop("fill").chain()
  .quality("auto")).imageTag("marketing/med_travel_landscape.jpg");
```

```ruby
cl_image_tag("marketing/med_travel_landscape.jpg", transformation: [
  {overlay: {font_family: "Arial", font_size: 80, font_weight: "bold", text: "Prenota%20Le%20Tue%20Vacanze%20Dei%20Sogni"}},
  {gravity: "north_west", x: 50, y: 180, flags: "layer_apply"},
  {gravity: "auto", aspect_ratio: "16:9", crop: "fill"},
  {quality: "auto"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Overlay(new TextLayer().FontFamily("Arial").FontSize(80).FontWeight("bold").Text("Prenota%20Le%20Tue%20Vacanze%20Dei%20Sogni")).Chain()
  .Gravity("north_west").X(50).Y(180).Flags("layer_apply").Chain()
  .Gravity("auto").AspectRatio("16:9").Crop("fill").Chain()
  .Quality("auto")).BuildImageTag("marketing/med_travel_landscape.jpg")
```

```dart
cloudinary.image('marketing/med_travel_landscape.jpg').transformation(Transformation()
	.addTransformation("l_text:Arial_80_bold:Prenota Le Tue Vacanze Dei Sogni/fl_layer_apply,g_north_west,x_50,y_180/c_fill,g_auto,ar_16:9/f_auto/q_auto"));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setOverlay("text:Arial_80_bold:Prenota%20Le%20Tue%20Vacanze%20Dei%20Sogni").chain()
  .setGravity("north_west").setX(50).setY(180).setFlags("layer_apply").chain()
  .setGravity("auto").setAspectRatio("16:9").setCrop("fill").chain()
  .setQuality("auto")).generate("marketing/med_travel_landscape.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(80).fontWeight("bold").text("Prenota%20Le%20Tue%20Vacanze%20Dei%20Sogni")).chain()
  .gravity("north_west").x(50).y(180).flags("layer_apply").chain()
  .gravity("auto").aspectRatio("16:9").crop("fill").chain()
  .quality("auto")).generate("marketing/med_travel_landscape.jpg");
```

```flutter
cloudinary.image('marketing/med_travel_landscape.jpg').transformation(Transformation()
	.addTransformation("l_text:Arial_80_bold:Prenota Le Tue Vacanze Dei Sogni/fl_layer_apply,g_north_west,x_50,y_180/c_fill,g_auto,ar_16:9/f_auto/q_auto"));
```

```kotlin
cloudinary.image {
	publicId("marketing/med_travel_landscape.jpg")
	 overlay(Overlay.source(
	Source.text("Prenota Le Tue Vacanze Dei Sogni",TextStyle("Arial",80) {
	 fontWeight(
	FontWeight.bold())
	 })) {
	 position(Position() {
	 gravity(
	Gravity.compass(
	Compass.northWest()))
 offsetX(50)
 offsetY(180) })
	 })
	 resize(Resize.fill() {
	 aspectRatio(
	AspectRatio.ar16X9())
	 gravity(
	Gravity.autoGravity())
	 })
	 delivery(Delivery.format(
	Format.auto()))
	 delivery(Delivery.quality(
	Quality.auto())) 
}.generate()
```

```jquery
$.cloudinary.image("marketing/med_travel_landscape.jpg", {transformation: [
  {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(80).fontWeight("bold").text("Prenota%20Le%20Tue%20Vacanze%20Dei%20Sogni")},
  {gravity: "north_west", x: 50, y: 180, flags: "layer_apply"},
  {gravity: "auto", aspect_ratio: "16:9", crop: "fill"},
  {quality: "auto"}
  ]})
```

```react_native
import { source } from "@cloudinary/url-gen/actions/overlay";
import { fill } from "@cloudinary/url-gen/actions/resize";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { text } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";
import { TextStyle } from "@cloudinary/url-gen/qualifiers/textStyle";
import { ar16X9 } from "@cloudinary/url-gen/qualifiers/aspectRatio";
import { autoGravity, compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("marketing/med_travel_landscape.jpg")
  .overlay(
    source(
      text(
        "Prenota Le Tue Vacanze Dei Sogni",
        new TextStyle("Arial", 80).fontWeight("bold")
      )
    ).position(
      new Position()
        .gravity(compass("north_west"))
        .offsetX(50)
        .offsetY(180)
    )
  )
  .resize(
    fill()
      .aspectRatio(ar16X9())
      .gravity(autoGravity())
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

### Brand-aligned vector merchandise

An enterprise wants to allow users to customize internal company swag.

Vector and illustration output is a specific capability, so this request pins `recraft-v4` with `model.id` rather than letting Cloudinary choose.

Here's an example API call for the `demo` product environment:

```curl
curl -X POST https://api.cloudinary.com/v2/generate/demo/text_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A cute minimalist astronaut drinking coffee, vector art, sticker design, isolated white background.",
    "model": {
      "id": "recraft-v4"
    },
    "image_size": {
      "aspect_ratio": "1:1",
      "resolution": "1K"
    },
    "target": {
      "target_type": "managed_asset",
      "public_id": "swag/astronaut_sticker"
    }
  }'
```

The generated image:

![Astronaut sticker](https://res.cloudinary.com/demo/image/upload/v1782681014/swag/astronaut_sticker "with_code:false, thumb:c_scale,w_300")

This URL removes the background of the sticker (`e_background_removal`), before layering it directly onto a pre-existing t-shirt merchandise image (`swag:tshirt_mockup`):

![Astronaut sticker on t-shirt](https://res.cloudinary.com/demo/image/upload/l_swag:astronaut_sticker/e_background_removal/c_scale,w_0.3,fl_relative/fl_layer_apply,x_0.02/f_auto/q_auto/swag/tshirt_mockup.png "thumb:c_scale,w_500")

```nodejs
cloudinary.image("swag/tshirt_mockup.png", {transformation: [
  {overlay: "swag:astronaut_sticker"},
  {effect: "background_removal"},
  {width: "0.3", flags: "relative", crop: "scale"},
  {x: "0.02", flags: "layer_apply"},
  {quality: "auto"}
  ]})
```

```react
import { source } from "@cloudinary/url-gen/actions/overlay";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { backgroundRemoval } from "@cloudinary/url-gen/actions/effect";
import { scale } from "@cloudinary/url-gen/actions/resize";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";

new CloudinaryImage("swag/tshirt_mockup.png")
  .overlay(
    source(
      image("swag/astronaut_sticker").transformation(
        new Transformation()
          .effect(backgroundRemoval())
          .resize(scale().width(0.3).relative())
      )
    ).position(new Position().offsetX(0.02))
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```vue
import { source } from "@cloudinary/url-gen/actions/overlay";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { backgroundRemoval } from "@cloudinary/url-gen/actions/effect";
import { scale } from "@cloudinary/url-gen/actions/resize";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";

new CloudinaryImage("swag/tshirt_mockup.png")
  .overlay(
    source(
      image("swag/astronaut_sticker").transformation(
        new Transformation()
          .effect(backgroundRemoval())
          .resize(scale().width(0.3).relative())
      )
    ).position(new Position().offsetX(0.02))
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```angular
import { source } from "@cloudinary/url-gen/actions/overlay";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { backgroundRemoval } from "@cloudinary/url-gen/actions/effect";
import { scale } from "@cloudinary/url-gen/actions/resize";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";

new CloudinaryImage("swag/tshirt_mockup.png")
  .overlay(
    source(
      image("swag/astronaut_sticker").transformation(
        new Transformation()
          .effect(backgroundRemoval())
          .resize(scale().width(0.3).relative())
      )
    ).position(new Position().offsetX(0.02))
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```js
import { source } from "@cloudinary/url-gen/actions/overlay";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { backgroundRemoval } from "@cloudinary/url-gen/actions/effect";
import { scale } from "@cloudinary/url-gen/actions/resize";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";

new CloudinaryImage("swag/tshirt_mockup.png")
  .overlay(
    source(
      image("swag/astronaut_sticker").transformation(
        new Transformation()
          .effect(backgroundRemoval())
          .resize(scale().width(0.3).relative())
      )
    ).position(new Position().offsetX(0.02))
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```python
CloudinaryImage("swag/tshirt_mockup.png").image(transformation=[
  {'overlay': "swag:astronaut_sticker"},
  {'effect': "background_removal"},
  {'width': "0.3", 'flags': "relative", 'crop': "scale"},
  {'x': "0.02", 'flags': "layer_apply"},
  {'quality': "auto"}
  ])
```

```php
use Cloudinary\Transformation\Overlay;
use Cloudinary\Transformation\Delivery;
use Cloudinary\Transformation\Effect;
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Source;
use Cloudinary\Transformation\Position;
use Cloudinary\Transformation\Format;
use Cloudinary\Transformation\Quality;

(new ImageTag('swag/tshirt_mockup.png'))
	->overlay(Overlay::source(
	Source::image("swag/astronaut_sticker")
	->transformation((new Transformation())
	->effect(Effect::backgroundRemoval())
	->resize(Resize::scale()->width(0.3)
	->relative()
	))
	)
	->position((new Position())->offsetX(0.02))
	)
	->delivery(Delivery::format(
	Format::auto()))
	->delivery(Delivery::quality(
	Quality::auto()));
```

```java
cloudinary.url().transformation(new Transformation()
  .overlay(new Layer().publicId("swag:astronaut_sticker")).chain()
  .effect("background_removal").chain()
  .width(0.3).flags("relative").crop("scale").chain()
  .x(0.02).flags("layer_apply").chain()
  .quality("auto")).imageTag("swag/tshirt_mockup.png");
```

```ruby
cl_image_tag("swag/tshirt_mockup.png", transformation: [
  {overlay: "swag:astronaut_sticker"},
  {effect: "background_removal"},
  {width: 0.3, flags: "relative", crop: "scale"},
  {x: 0.02, flags: "layer_apply"},
  {quality: "auto"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Overlay(new Layer().PublicId("swag:astronaut_sticker")).Chain()
  .Effect("background_removal").Chain()
  .Width(0.3).Flags("relative").Crop("scale").Chain()
  .X(0.02).Flags("layer_apply").Chain()
  .Quality("auto")).BuildImageTag("swag/tshirt_mockup.png")
```

```dart
cloudinary.image('swag/tshirt_mockup.png').transformation(Transformation()
	.overlay(Overlay.source(
	Source.image("swag/astronaut_sticker")
	.transformation(new Transformation()
	.effect(Effect.backgroundRemoval())
	.resize(Resize.scale().width(0.3)
	.relative()
	))
	)
	.position(Position().offsetX(0.02))
	)
	.delivery(Delivery.format(
	Format.auto()))
	.delivery(Delivery.quality(
	Quality.auto())));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setOverlay("swag:astronaut_sticker").chain()
  .setEffect("background_removal").chain()
  .setWidth(0.3).setFlags("relative").setCrop("scale").chain()
  .setX(0.02).setFlags("layer_apply").chain()
  .setQuality("auto")).generate("swag/tshirt_mockup.png")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .overlay(new Layer().publicId("swag:astronaut_sticker")).chain()
  .effect("background_removal").chain()
  .width(0.3).flags("relative").crop("scale").chain()
  .x(0.02).flags("layer_apply").chain()
  .quality("auto")).generate("swag/tshirt_mockup.png");
```

```flutter
cloudinary.image('swag/tshirt_mockup.png').transformation(Transformation()
	.overlay(Overlay.source(
	Source.image("swag/astronaut_sticker")
	.transformation(new Transformation()
	.effect(Effect.backgroundRemoval())
	.resize(Resize.scale().width(0.3)
	.relative()
	))
	)
	.position(Position().offsetX(0.02))
	)
	.delivery(Delivery.format(
	Format.auto()))
	.delivery(Delivery.quality(
	Quality.auto())));
```

```kotlin
cloudinary.image {
	publicId("swag/tshirt_mockup.png")
	 overlay(Overlay.source(
	Source.image("swag/astronaut_sticker") {
	 transformation(Transformation {
	 effect(Effect.backgroundRemoval())
	 resize(Resize.scale() { width(0.3F)
	 relative()
	 }) })
	 }) {
	 position(Position() { offsetX(0.02F) })
	 })
	 delivery(Delivery.format(
	Format.auto()))
	 delivery(Delivery.quality(
	Quality.auto())) 
}.generate()
```

```jquery
$.cloudinary.image("swag/tshirt_mockup.png", {transformation: [
  {overlay: new cloudinary.Layer().publicId("swag:astronaut_sticker")},
  {effect: "background_removal"},
  {width: "0.3", flags: "relative", crop: "scale"},
  {x: "0.02", flags: "layer_apply"},
  {quality: "auto"}
  ]})
```

```react_native
import { source } from "@cloudinary/url-gen/actions/overlay";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { backgroundRemoval } from "@cloudinary/url-gen/actions/effect";
import { scale } from "@cloudinary/url-gen/actions/resize";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";

new CloudinaryImage("swag/tshirt_mockup.png")
  .overlay(
    source(
      image("swag/astronaut_sticker").transformation(
        new Transformation()
          .effect(backgroundRemoval())
          .resize(scale().width(0.3).relative())
      )
    ).position(new Position().offsetX(0.02))
  )
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

### Efficient catalog photography with a reusable model

An online fashion retailer wants to shoot their catalog without booking a new photoshoot for every product. Instead, they photograph a single model once and reuse that same reference photo to generate on-model shots for each new garment, cutting studio time and cost.

This request uses the `image_to_image` endpoint with two reference images: the reusable model photo (`[1]`) and a product shot of the garment (`[2]`). Cloudinary chooses the model, which on this endpoint is always an edit-capable one, to composite them into a single realistic result. To generate the next product in the catalog, swap in a new garment reference and keep the same model reference.

Here's an example API call for the `demo` product environment:

```curl
curl -X POST https://api.cloudinary.com/v2/generate/demo/image_to_image \
  -u "<API_KEY>:<API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Dress the person in [1] in the jacket from [2], changing their pose to a confident standing position against a clean, plain white background, photorealistic.",
    "reference_images": [
      {
        "source_type": "url",
        "url": "https://res.cloudinary.com/demo/image/upload/v1784148584/docs/female-model-01.jpg"
      },
      {
        "source_type": "url",
        "url": "https://res.cloudinary.com/demo/image/upload/v1784148059/docs/jacket-2899729_1920.png"
      }
    ],
    "model": {
      "mode": "auto"
    },
    "target": {
      "target_type": "managed_asset",
      "public_id": "tryOn/model-01_jacket-navy_stand_clean"
    }
  }'
```

The reference images — the model (`[1]`) and the jacket (`[2]`):

Model

Jacket

The generated composite is stored as a managed asset like any other generation, so you can immediately deliver, transform, or optimize it with Cloudinary's standard delivery URLs. Repeat the request with a different garment reference and the same model reference to produce the rest of the catalog, without rebooking the model or studio:

![Model wearing the jacket](https://res.cloudinary.com/demo/image/upload/f_auto/q_auto/tryOn/model-01_jacket-navy_stand_clean "thumb:c_scale,w_400/e_sharpen")

```nodejs
cloudinary.image("tryOn/model-01_jacket-navy_stand_clean", {quality: "auto"})
```

```react
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";

new CloudinaryImage("tryOn/model-01_jacket-navy_stand_clean")
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```vue
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";

new CloudinaryImage("tryOn/model-01_jacket-navy_stand_clean")
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```angular
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";

new CloudinaryImage("tryOn/model-01_jacket-navy_stand_clean")
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```js
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";

new CloudinaryImage("tryOn/model-01_jacket-navy_stand_clean")
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

```python
CloudinaryImage("tryOn/model-01_jacket-navy_stand_clean").image(quality="auto")
```

```php
use Cloudinary\Transformation\Delivery;
use Cloudinary\Transformation\Format;
use Cloudinary\Transformation\Quality;

(new ImageTag('tryOn/model-01_jacket-navy_stand_clean'))
	->delivery(Delivery::format(
	Format::auto()))
	->delivery(Delivery::quality(
	Quality::auto()));
```

```java
cloudinary.url().transformation(new Transformation().quality("auto")).imageTag("tryOn/model-01_jacket-navy_stand_clean");
```

```ruby
cl_image_tag("tryOn/model-01_jacket-navy_stand_clean", quality: "auto")
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation().Quality("auto")).BuildImageTag("tryOn/model-01_jacket-navy_stand_clean")
```

```dart
cloudinary.image('tryOn/model-01_jacket-navy_stand_clean').transformation(Transformation()
	.delivery(Delivery.format(
	Format.auto()))
	.delivery(Delivery.quality(
	Quality.auto())));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setQuality("auto")).generate("tryOn/model-01_jacket-navy_stand_clean")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation().quality("auto")).generate("tryOn/model-01_jacket-navy_stand_clean");
```

```flutter
cloudinary.image('tryOn/model-01_jacket-navy_stand_clean').transformation(Transformation()
	.delivery(Delivery.format(
	Format.auto()))
	.delivery(Delivery.quality(
	Quality.auto())));
```

```kotlin
cloudinary.image {
	publicId("tryOn/model-01_jacket-navy_stand_clean")
	 delivery(Delivery.format(
	Format.auto()))
	 delivery(Delivery.quality(
	Quality.auto())) 
}.generate()
```

```jquery
$.cloudinary.image("tryOn/model-01_jacket-navy_stand_clean", {quality: "auto"})
```

```react_native
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto as autoFormat } from "@cloudinary/url-gen/qualifiers/format";
import { auto as autoQuality } from "@cloudinary/url-gen/qualifiers/quality";

new CloudinaryImage("tryOn/model-01_jacket-navy_stand_clean")
  .delivery(format(autoFormat()))
  .delivery(quality(autoQuality()));
```

## Plans and quota

Image Generation uses a credit-based billing model. One credit is approximately one US cent, and each generation consumes a variable number of credits depending on the model and output quality. Higher resolution outputs consume more credits.

All Cloudinary accounts include a free monthly credit allotment. When you exhaust your free credits, you must [upgrade to a paid Image Generation plan](https://console.cloudinary.com/app/settings/billing/change_plan/feature:image_generation) to continue generating images. Paid Image Generation plans are separate from your Cloudinary account plan. You can be on a free Cloudinary account and still subscribe to a paid Image Generation plan.

On a paid plan, generation continues on a pay-as-you-go basis once your plan credits are used up. You can view available plans, subscribe, and monitor remaining credits on the [Image Generation add-on](https://console.cloudinary.com/app/marketplace/details/image_generation) page in the Cloudinary Console.

For details about prorated billing, mid-cycle upgrades, and downgrade behavior, see [Add-on units and billing](cloudinary_add_ons#add_on_units_and_billing).
