> ## Documentation Index
> Fetch the complete documentation index at: https://cloudinary.com/documentation/llms.txt
> Use this file to discover all available pages before exploring further.

# Automatic image tagging


The automatic image tagging behavior of the Cloudinary AI Content Analysis add-on can be invoked on uploading an image, or by updating an image that's already stored in your product environment. Using the specified model, it analyzes the image, identifies categories and objects, and suggests tags that could be applied to the image. 

## Object and category detection

Take a look at the following photo of a woman dressed fashionably for winter:
![Woman dressed fashionably for winter](https://res.cloudinary.com/demo/image/upload/f_auto,q_auto/docs/winter_fashion.jpg "thumb: w_550, with_code:false, with_url:false")

By setting the `detection` parameter to the name of the model (and optionally the version, e.g. `cld-fashion_v3`) you want to invoke when calling Cloudinary's [upload](image_upload_api_reference#upload) or [update](admin_api#update_details_of_an_existing_resource) methods, the add-on automatically analyzes the content of the uploaded or specified existing image. For example, invoking the `cld-fashion` detection model while uploading `winter_fashion.jpg`:

```multi
|ruby
Cloudinary::Uploader.upload("winter_fashion.jpg", 
  detection: "cld-fashion")

|php_2
$cloudinary->uploadApi()->upload("winter_fashion.jpg", 
  ["detection" => "cld-fashion"]);

|python
cloudinary.uploader.upload("winter_fashion.jpg",
  detection = "cld-fashion")

|nodejs
cloudinary.v2.uploader
.upload("winter_fashion.jpg", 
  { detection: "cld-fashion" })
.then(result=>console.log(result)); 

|java
cloudinary.uploader().upload("winter_fashion.jpg", ObjectUtils.asMap(
  "detection", "cld-fashion"));

|csharp
var uploadParams = new ImageUploadParams() 
{
  File = new FileDescription(@"winter_fashion.jpg"),
  Detection = "cld-fashion"
};
var uploadResult = cloudinary.Upload(uploadParams); 

|go
resp, err := cld.Upload.Upload(ctx, "winter_fashion.jpg", uploader.UploadParams{
		Detection: "cld-fashion"})

|android
MediaManager.get().upload("winter_fashion.jpg")
  .option("detection", "cld-fashion").dispatch();

|swift
let params = CLDUploadRequestParams().setDetection("cld-fashion")
var mySig = MyFunction(params)  // your own function that returns a signature generated on your backend
params.setSignature(CLDSignature(signature: mySig.signature, timestamp: mySig.timestamp))
let request = cloudinary.createUploader().signedUpload(
  url: "winter_fashion.jpg", params: params) 

|cli
cld uploader upload "winter_fashion.jpg" detection="cld-fashion"

|curl
curl https://api.cloudinary.com/v1_1/demo/image/upload -X POST -F 'file=@/path/to/winter_fashion.jpg' -F 'detection=cld-fashion' -F 'timestamp=173719931' -F 'api_key=436464676' -F 'signature=a781d61f86a6f818af'
```

> **TIP**:
>
> :title=Tip
> You can use **upload presets** to centrally define a set of upload options including add-on operations to apply, instead of specifying them in each upload call. You can define multiple upload presets, and apply different presets in different upload scenarios. You can create new upload presets in the **Upload Presets** page of the [Console Settings](https://console.cloudinary.com/app/settings/upload/presets) or using the [upload_presets](admin_api#upload_presets) Admin API method. From the **Upload** page of the Console Settings, you can also select default upload presets to use for image, video, and raw API uploads (respectively) as well as default presets for image, video, and raw uploads performed via the Media Library UI. 
> **Learn more**: [Upload presets](upload_presets)

The upload API response includes the categories and objects automatically identified by the model you requested. As can be seen in the response snippet below, a hat and a specific type of outerwear are automatically detected in the uploaded photo. Depending on the [capabilities](cloudinary_ai_content_analysis_addon#model_capabilities) of each model, different information is returned. In the example below, a confidence score, bounding box and in some cases, attributes, are returned for each detected object. The confidence score is a numerical value representing the certainty of a correct detection, where 1.0 means 100% confidence. The bounding-box parameter shows the location of the object in the image, as an array: [`x-coordinate of top left corner`, `y-coordinate of top left corner`, `width of box`, `height of box`]. Bounding-box information is used in the [object detection demo](cloudinary_ai_content_analysis_addon#object_detection_demo).

```json
{
...
  "info": {
    "detection": {
      "object_detection": {
        "status": "complete",
        "data": {
          "cld-fashion": {
            "model_name": "cld-fashion",
            "model_version": 3,
            "schema_version": 1,
            "tags": {
              "hat": [
                {
                  "bounding-box": [
                    1203.4641054329725,
                    85.94320068359376,
                    419.43426051207325,
                    351.2288696289063
                  ],
                  "categories": [
                    "fashion"
                  ],
                  "confidence": 0.9853795170783997
                }
              ],
              "outerwear": [
                {
                  "attributes": {
                    "jackets_coats": [
                      [
                        "blanket (coat)",
                        0.8722688555717468
                      ]
                    ],
                    "length": [
                      [
                        "knee (length)",
                        0.5171285271644592
                      ]
                    ],
                    "neckline_type": [
                      [
                        "cowl (neck)",
                        0.6793023943901062
                      ]
                    ],
                    "pattern": [
                      [
                        "herringbone (pattern)",
                        0.7162534594535828
                      ]
                    ],
                    "silhouette_fit": [
                      [
                        "loose (fit)",
                        0.636439859867096
                      ]
                    ],
                    "special_features": [
                      [
                        "lining",
                        0.7706462740898132
                      ]
                    ]
                  },
                  "bounding-box": [
                    1134.8407251769358,
                    329.68173828125003,
                    553.6939594608659,
                    951.91826171875
                  ],
                  "categories": [
                    "fashion"
                  ],
                  "confidence": 0.9895038604736328
                }
              ]
            }
          }
        }
      }
    }
  },
```

## Adding tags to images

By providing the `auto_tagging` parameter to an `upload` or `update` request, images are automatically assigned tags based on the detected content. The value of the `auto_tagging` parameter is the minimum confidence score of a detected category or object that should be automatically used as an assigned tag. You can also set `auto_tagging` to `default`, which uses the model's [default confidence](cloudinary_ai_content_analysis_addon#model_capabilities). 

The following code example automatically tags an uploaded image with all detected categories that have a confidence score higher than 0.6. 

```multi
|ruby
Cloudinary::Uploader.upload("winter_fashion.jpg", 
  detection: "cld-fashion", auto_tagging: 0.6)

|php_2
$cloudinary->uploadApi()->upload("winter_fashion.jpg", 
  ["detection" => "cld-fashion", "auto_tagging" => 0.6]);

|python
cloudinary.uploader.upload("winter_fashion.jpg",
  detection = "cld-fashion", auto_tagging = 0.6)

|nodejs
cloudinary.v2.uploader
.upload("winter_fashion.jpg", 
  { detection: "cld-fashion", 
    auto_tagging: 0.6 })
.then(result=>console.log(result)); 

|java
cloudinary.uploader().upload("winter_fashion.jpg", ObjectUtils.asMap(
  "detection", "cld-fashion", "auto_tagging", "0.6"));

|csharp
var uploadParams = new ImageUploadParams() 
{
  File = new FileDescription(@"winter_fashion.jpg"),
  Detection = "cld-fashion",
  AutoTagging = 0.6
};
var uploadResult = cloudinary.Upload(uploadParams);  

|go
resp, err := cld.Upload.Upload(ctx, "winter_fashion.jpg", uploader.UploadParams{
		Detection:   "cld-fashion",
		AutoTagging: 0.6})

|android
MediaManager.get().upload("winter_fashion.jpg")
  .option("detection", "cld-fashion")
  .option("auto_tagging", "0.6").dispatch();

|swift
let params = CLDUploadRequestParams()
  .setDetection("cld-fashion")
  .setAutoTagging(0.6)
var mySig = MyFunction(params)  // your own function that returns a signature generated on your backend
params.setSignature(CLDSignature(signature: mySig.signature, timestamp: mySig.timestamp))
let request = cloudinary.createUploader().signedUpload(
  url: "winter_fashion.jpg", params: params) 

|cli
cld uploader upload "winter_fashion.jpg" detection="cld-fashion" auto_tagging=0.6

|curl
curl https://api.cloudinary.com/v1_1/demo/image/upload -X POST -F 'file=@/path/to/winter_fashion.jpg' -F 'detection=cld-fashion' -F 'auto_tagging=0.6' -F 'timestamp=173719931' -F 'api_key=436464676' -F 'signature=a781d61f86a6f818af'
```

The response to the upload request returns the detected categories as well as the assigned tags for categories meeting the minimum confidence score of 0.6:

```json
{ 
...    
  "tags": [
    "hat",
    "outerwear"
  ],
...
}
```

You can also use the `update` method to apply auto-tagging to images already stored in your product environment.

The following example uses Cloudinary's `update` method on the `puppy` image in the product environment, to detect objects and categories in the LVIS model. Tags are automatically assigned based on the objects and categories detected with over a 90% confidence level.

```multi
|ruby
Cloudinary::Api.update("puppy", 
  detection: "lvis", 
  auto_tagging: 0.9)

|php_2
$cloudinary->api()->update("puppy", [
  "detection" => "lvis", 
  "auto_tagging" => 0.9]);

|python
cloudinary.api.update("puppy",
  detection = "lvis", 
  auto_tagging = 0.9)

|nodejs
cloudinary.v2.api
.update("puppy", 
  { detection: "lvis", 
    auto_tagging: 0.9 })
.then(result=>console.log(result));

|java
cloudinary.api().update("puppy", ObjectUtils.asMap(
  "detection", "lvis", 
  "auto_tagging", 0.9));

|csharp
var updateParams = new UpdateParams("puppy") 
{
  Detection = "lvis",
  AutoTagging = 0.9
};
var updateResult = cloudinary.UpdateResource(updateParams); 

|go
resp, err := cld.Admin.UpdateAsset(ctx, admin.UpdateAssetParams{
		PublicID:    "winter_fashion",
		Detection:   "lvis",
		AutoTagging: 0.9})

|cli
cld admin update "puppy" detection="lvis" auto_tagging=0.9
```

You can use the Admin API's [resource_by_tag](admin_api#get_resources_by_tag) method to return all resources with a certain tag, for example `hat`:

```multi
|curl
curl https://<API_KEY>:<API_SECRET>@api.cloudinary.com/v1_1/<cloud_name>/resources/image/tags/hat
       
|ruby
Cloudinary::Api.resources_by_tag('hat')

|php_2
$api->assetsByTag("hat");

|python
cloudinary.api.resources_by_tag("hat")

|nodejs
cloudinary.v2.api
.resources_by_tag("hat")
.then(result=>console.log(result));

|java
api.resourcesByTag("hat", ObjectUtils.emptyMap());

|csharp
cloudinary.ListResourcesByTag("hat");  

|go
resp, err := cld.Admin.AssetsByTag(ctx, admin.AssetsByTagParams{Tag: "hat"})

|cli
cld admin resources_by_tag hat
```

You can also use the [search method](search_method) or the [Media Library advanced search](https://console.cloudinary.com/console/media_library/search) to find images with certain tags.

## Asynchronous handling

As automatic image tagging may not be immediate, it is good practice to use asynchronous handling for these calls.

To make the call asynchronous, set the `async` parameter of the `upload` method to `true`. To be notified when the processing is complete, you can either set the `notification_url` parameter of the `upload` method (as in the example below) or the global webhook **Notification URL** in the **Upload** page of your Cloudinary Console Settings.

```multi
|ruby
Cloudinary::Uploader.upload("winter_fashion.jpg", 
  detection: "cld-fashion", auto_tagging: 0.6, 
  async: true, 
  notification_url: "https://mysite.example.com/upload_endpoint")

|php_2
$cloudinary->uploadApi()->upload("winter_fashion.jpg", 
  ["detection" => "cld-fashion", "auto_tagging" => 0.6, 
  "async" => true, 
  "notification_url" => "https://mysite.example.com/upload_endpoint"]);

|python
cloudinary.uploader.upload("winter_fashion.jpg",
  detection = "cld-fashion", auto_tagging = 0.6, 
  async = True, 
  notification_url = "https://mysite.example.com/upload_endpoint")

|nodejs
cloudinary.v2.uploader
.upload("winter_fashion.jpg", 
  { detection: "cld-fashion", 
    auto_tagging: 0.6, 
    async: true,
    notification_url: "https://mysite.example.com/upload_endpoint" })
.then(result=>console.log(result)); 

|java
cloudinary.uploader().upload("winter_fashion.jpg", ObjectUtils.asMap(
  "detection", "cld-fashion", 
  "auto_tagging", "0.6",
  "async", true,
  "notification_url", "https://mysite.example.com/upload_endpoint"));

|csharp
var uploadParams = new ImageUploadParams() 
{
  File = new FileDescription(@"winter_fashion.jpg"),
  Detection = "cld-fashion",
  AutoTagging = 0.6,
  Async = true,
  NotificationUrl = "https://mysite.example.com/upload_endpoint"
};
var uploadResult = cloudinary.Upload(uploadParams);  

|go
resp, err := cld.Upload.Upload(ctx, "winter_fashion.jpg", uploader.UploadParams{
		Detection:   "cld-fashion",
		AutoTagging: 0.6,
    Async: true,
    NotificationURL: "https://mysite.example.com/upload_endpoint"})

|android
MediaManager.get().upload("winter_fashion.jpg")
  .option("detection", "cld-fashion")
  .option("auto_tagging", "0.6")
  .option("async", true)
  .option("notification_url", "https://mysite.example.com/upload_endpoint").dispatch();

|swift
let params = CLDUploadRequestParams()
  .setDetection("cld-fashion")
  .setAutoTagging(0.6)
  .setAsync(true)
  .setNotificationUrl("https://mysite.example.com/upload_endpoint")
var mySig = MyFunction(params)  // your own function that returns a signature generated on your backend
params.setSignature(CLDSignature(signature: mySig.signature, timestamp: mySig.timestamp))
let request = cloudinary.createUploader().signedUpload(
  url: "winter_fashion.jpg", params: params) 

|cli
cld uploader upload "winter_fashion.jpg" detection="cld-fashion" auto_tagging=0.6 async=true notification_url="https://mysite.example.com/upload_endpoint"

|curl
curl https://api.cloudinary.com/v1_1/demo/image/upload -X POST -F 'file=@/path/to/winter_fashion.jpg' -F 'detection=cld-fashion' -F 'auto_tagging=0.6' -F 'async=true' -F 'notification_url=https://mysite.example.com/upload_endpoint' -F 'timestamp=173719931' -F 'api_key=436464676' -F 'signature=a781d61f86a6f818af'
```

The response to an asynchronous upload call looks similar to this:

```json
{
  "status": "pending",
  "type": "upload",
  "batch_id": "a7877927ae1af0d1115485018ce92a6792c97938bb3edb9b0777d4663d6abbee"
}
```

When the processing is finished, the complete upload response is sent to the notification URL that you specified.

```json
{
  "notification_type": "upload",
  "timestamp": "2022-06-15T14:49:17+00:00",
  "request_id": "3fcdc820276ace1fa51d4b345d28286b",
  "asset_id": "8580b2beaba30dc93a72f05db9f3d47d",
  "public_id": "ow1pnmgfxkdp1mqkkoac",
  ...
  "access_mode": "public",
  "info": {
    "detection": {
      "object_detection": {
        "status": "complete",
        "data": {
          "cld-fashion": {
            "model_name": "cld-fashion",
            "model_version": 4,
            "schema_version": 1,
            "tags": {
              ...
  },
  "original_filename": "winter_fashion"
}
```
