> ## 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.

# Contextual metadata


Contextual metadata is a custom key-value pair that you can assign to individual assets either programmatically or in the Cloudinary Console. Once defined, contextual metadata can be referenced in your application, for example to find assets that meet relevant criteria and for generating transformations based on the value of a particular contextual metadata key, using user-defined variables and/or conditional transformations.

## Adding context while uploading

You can assign context to assets while [uploading](image_upload_api_reference#upload_method) them by specifying the `context` parameter in the upload method. 

For example, uploading the image `boots.jpg` and adding the context key `caption` set to a value of `New` to the image:

```multi
|ruby
Cloudinary::Uploader.upload("boots.jpg", 
  context: "caption=New")

|php_2
$cloudinary->uploadApi()->upload("boots.jpg", 
  ["context" => "caption=New"]);

|python
cloudinary.uploader.upload("boots.jpg", 
  context = "caption=New")

|nodejs
cloudinary.v2.uploader
.upload("boots.jpg", 
  { context: "caption=New" })
.then(result=>console.log(result)); 
                           
|java
cloudinary.uploader().upload(new File("boots.jpg"),
  ObjectUtils.asMap("context", "caption=New"));

|csharp
var uploadParams = new UploadParams(){
  Context = "caption=New"};
var uploadResult = cloudinary.Upload(uploadParams); 

|swift
let params = CLDUploadRequestParams()
  .setContext("caption=New")
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: "boots.jpg", params: params) 

|go
resp, err := cld.Upload.Upload(ctx, "boots.jpg", uploader.UploadParams{
		Context: "caption=New"})

|cli
cld uploader upload "boots.jpg" context="caption=New"
```

> **TIP**:
>
> You can open the asset in your Media Library and check the **Metadata** tab in the Preview pane to confirm that the upload applied the contextual metadata as expected. For more information, see [Managing assets](media_library_for_developers#managing_assets) on the _Media Library for developers_ page.

## The context method

The `context` parameter of an uploaded asset contains a pipe-separated list of key-value pairs of contextual metadata (up to 255 characters). The `context` method can be used to manage the contextual metadata of an uploaded asset by setting the value of the `command` parameter to either `add` a new key-value pair, or `remove_all` contextual metadata from the asset. The Cloudinary SDKs wrap the REST API `context` method and offer two separate methods: one for adding contextual metadata and one for removing all contextual metadata:

* [Adding context](image_upload_api_reference#adding_context_syntax)
* [Removing all context](image_upload_api_reference#removing_all_context_syntax)

For example, adding the contextual metadata key-pairs `caption=New` and `product=shirt` to the images with the public IDs of `shirt1` and `shirt2`:

```multi
|ruby
result = Cloudinary::Uploader
.add_context('caption=New|product=shirt', ['shirt1', 'shirt2'])

|php_2
$result = $cloudinary->uploadApi()
->addContext('caption=New|product=shirt', ['shirt1', 'shirt2']);

|python
result = cloudinary.uploader\
.add_context("caption=New|product=shirt", ["shirt1", "shirt2"])

|nodejs
cloudinary.v2.uploader
.add_context('caption=New|product=shirt', [ 'shirt1', 'shirt2' ])
.then(result=>console.log(result));

|java
result = cloudinary.uploader()
.addContext("caption=New|product=shirt",
  ["shirt1", "shirt2"], ObjectUtils.emptyMap());

|csharp
var contextParams = new ContextParams(){
  PublicIds = new List<string>(){"shirt1","shirt2"},
  Context = "caption=New|product=shirt",
  Command = ContextCommand.Add};
var contextResult = cloudinary.Context(contextParams); 

|curl
curl https://api.cloudinary.com/v1_1/demo/image/context -X POST --data 'context=caption%3DNew%7Cproduct%3Dshirt&public_ids[]=shirt1&public_ids[]=shirt2&command=add&timestamp=173719931&api_key=436464676&signature=a788d68f86a6f868af' 

|go
resp, err := cld.Upload.AddContext(ctx, uploader.AddContextParams{
    Context: map[string]string{"caption": "New", "product": "shirt"}, 
    PublicIDs: []string{"shirt1","shirt2"}})

|cli
cld uploader add_context 'caption=New|product=shirt' shirt1 shirt2
```

## Monitoring context changes using a notification URL

You can use [Cloudinary notifications](notifications#global_notification_urls) to monitor for changes to the contextual metadata on your media assets, including contextual metadata that has been added or removed via API or the Cloudinary Console UI. 

To capture these changes, add a [Notification URL](notifications#global_notification_urls) triggered by the 'Resource context changed' Notification Type in the [Webhook Notifications](https://console.cloudinary.com/app/settings/webhooks) page of your Console Settings. The notification sent will specify `resource_context_changed` as the `notification_type`, and include information about which resource was changed, the source of the change (UI or API), and whether contextual metadata was added, removed, or updated. For example:

```json
{ 
  "notification_type": "resource_context_changed",
  "source": "api",
  "resources": {
    "jeans-1421398-1279x852_srghta": {
      "added": [
        {
          "name": "caption",
          "value": "New"
        }
      ],
      "removed": [],
      "updated": [],
      "asset_id": "ede59e6d3befdc65a8adc2f381c0f96f",
      "resource_type": "image",
      "type": "upload"
    }
  },
  "notification_context": {
    "triggered_at": "2022-11-17T09:07:50.766353Z",
    "triggered_by": {
      "source": "api",
      "id": "86787995117726"
    }
  }
}
```

See the documentation on [Notifications](notifications) for more information.

